coinbasepro

package module
v2.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 14, 2021 License: MIT Imports: 17 Imported by: 0

README

Go Coinbase Pro GoDoc Build Status

Summary

Go client for CoinBase Pro formerly known as gdax

Installation

If using Go modules (Go version >= 11.1) simply import as needed.

go mod init github.com/yourusername/yourprojectname
Older Go versions
go get github.com/preichenberger/go-coinbasepro
Significant releases

Use dep to install previous releases

dep ensure --add github.com/preichenberger/go-gdax@0.5.7
  • 0.5.7, last release before rename package to: coinbasepro
  • 0.5, as of 0.5 this library uses strings and is not backwards compatible

Documentation

For full details on functionality, see GoDoc documentation.

Setup

Client will respect environment variables: COINBASE_PRO_BASEURL, COINBASE_PRO_PASSPHRASE, COINBASE_PRO_KEY, COINBASE_PRO_SECRET by default

import (
  coinbasepro "github.com/preichenberger/go-coinbasepro/v2"
)

client := coinbasepro.NewClient()

// optional, configuration can be updated with ClientConfig
client.UpdateConfig(&coinbasepro.ClientConfig{
  BaseURL: "https://api.pro.coinbase.com",
  Key: "coinbase pro key",
  Passphrase: "coinbase pro passphrase",
  Secret: "coinbase pro secret",
})
Sandbox

You can switch to the sandbox URL by setting environment variable: COINBASE_PRO_SANDBOX

Enable sandbox

export COINBASE_PRO_SANDBOX=1

Disable sandbox

export COINBASE_PRO_SANDBOX=0
HTTP Settings
import (
  "net/http"
  "time"
)

client.HTTPClient = &http.Client {
  Timeout: 15 * time.Second,
}
Decimals

To manage precision correctly, this library sends all price values as strings. It is recommended to use a decimal library like Spring's Decimal if you are doing any manipulation of prices.

Example:

import (
  "github.com/shopspring/decimal"
)

book, err := client.GetBook("BTC-USD", 1)
if err != nil {
    println(err.Error())  
}

lastPrice, err := decimal.NewFromString(book.Bids[0].Price)
if err != nil {
    println(err.Error())  
}

order := coinbasepro.Order{
  Price: lastPrice.Add(decimal.NewFromFloat(1.00)).String(),
  Size: "2.00",
  Side: "buy",
  ProductID: "BTC-USD",
}

savedOrder, err := client.CreateOrder(&order)
if err != nil {
  println(err.Error())
}

println(savedOrder.ID)
Retry

You can set a retry count which uses exponential backoff: (2^(retry_attempt) - 1) / 2 * 1000 * milliseconds

client.RetryCount = 3 # 500ms, 1500ms, 3500ms
Cursor

This library uses a cursor pattern so you don't have to keep track of pagination.

var orders []coinbasepro.Order
cursor = client.ListOrders()

for cursor.HasMore {
  if err := cursor.NextPage(&orders); err != nil {
    println(err.Error())
    return
  }

  for _, o := range orders {
    println(o.ID)
  }
}

Websockets

Listen for websocket messages

  import(
    ws "github.com/gorilla/websocket"
  )

  var wsDialer ws.Dialer
  wsConn, _, err := wsDialer.Dial("wss://ws-feed.pro.coinbase.com", nil)
  if err != nil {
    println(err.Error())
  }

  subscribe := coinbasepro.Message{
    Type:      "subscribe",
    Channels: []coinbasepro.MessageChannel{
      coinbasepro.MessageChannel{
        Name: "heartbeat",
        ProductIds: []string{
          "BTC-USD",
        },
      },
      coinbasepro.MessageChannel{
        Name: "level2",
        ProductIds: []string{
          "BTC-USD",
        },
      },
    },
  }
  if err := wsConn.WriteJSON(subscribe); err != nil {
    println(err.Error())
  }

  for true {
    message := coinbasepro.Message{}
    if err := wsConn.ReadJSON(&message); err != nil {
      println(err.Error())
      break
    }

    println(message.Type)
  }

Time

Results return coinbase time type which handles different types of time parsing that coinbasepro returns. This wraps the native go time type

  import(
    "time"
    coinbasepro "github.com/preichenberger/go-coinbasepro/v2"
  )

  coinbaseTime := coinbasepro.Time{}
  println(time.Time(coinbaseTime).Day())
Examples

This library supports all public and private endpoints

Get Accounts:

  accounts, err := client.GetAccounts()
  if err != nil {
    println(err.Error())
  }

  for _, a := range accounts {
    println(a.Balance)
  }

List Account Ledger:

  var ledgers []coinbasepro.LedgerEntry

  accounts, err := client.GetAccounts()
  if err != nil {
    println(err.Error())
  }

  for _, a := range accounts {
    cursor := client.ListAccountLedger(a.ID)
    for cursor.HasMore {
      if err := cursor.NextPage(&ledgers); err != nil {
        println(err.Error())
      }

      for _, e := range ledgers {
        println(e.Amount)
      }
    }
  }

Create an Order:

  order := coinbasepro.Order{
    Price: "1.00",
    Size: "1.00",
    Side: "buy",
    ProductID: "BTC-USD",
  }

  savedOrder, err := client.CreateOrder(&order)
  if err != nil {
    println(err.Error())
  }

  println(savedOrder.ID)

Transfer funds:

  transfer := coinbasepro.Transfer {
    Type: "deposit",
    Amount: "1.00",
  }

  savedTransfer, err := client.CreateTransfer(&transfer)
  if err != nil {
    println(err.Error())
  }

Get Trade history:

  var trades []coinbasepro.Trade
  cursor := client.ListTrades("BTC-USD")

  for cursor.HasMore {
    if err := cursor.NextPage(&trades); err != nil {
      for _, t := range trades {
        println(trade.CoinbaseID)
      }
    }
  }
Testing

To test with Coinbase's public sandbox set the following environment variables:

export COINBASE_PRO_KEY="sandbox key"
export COINBASE_PRO_PASSPHRASE="sandbox passphrase"
export COINBASE_PRO_SECRET="sandbox secret"

Then run go test

go test

Note that your sandbox account will need at least 2,000 USD and 2 BTC to run the tests.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CompareProperties

func CompareProperties(a, b interface{}, properties []string) (bool, error)

func Ensure

func Ensure(a interface{}) error

func EnsureProperties

func EnsureProperties(a interface{}, properties []string) error

func NewTestWebsocketClient

func NewTestWebsocketClient() (*ws.Conn, error)

func StructHasZeroValues

func StructHasZeroValues(i interface{}) bool

Types

type Account

type Account struct {
	ID        string `json:"id"`
	Balance   string `json:"balance"`
	Hold      string `json:"hold"`
	Available string `json:"available"`
	Currency  string `json:"currency"`
}

type Book

type Book struct {
	Sequence int64       `json:"sequence"`
	Bids     []BookEntry `json:"bids"`
	Asks     []BookEntry `json:"asks"`
}

type BookEntry

type BookEntry struct {
	Price          string
	Size           string
	NumberOfOrders int
	OrderID        string
}

func (*BookEntry) UnmarshalJSON

func (e *BookEntry) UnmarshalJSON(data []byte) error

type CancelAllOrdersParams

type CancelAllOrdersParams struct {
	ProductID string
}

type Client

type Client struct {
	BaseURL    string
	Secret     string
	Key        string
	Passphrase string
	HTTPClient *http.Client
	RetryCount int
}

func NewClient

func NewClient() *Client

func NewTestClient

func NewTestClient() *Client

func (*Client) CancelAllOrders

func (c *Client) CancelAllOrders(p ...CancelAllOrdersParams) ([]string, error)

func (*Client) CancelOrder

func (c *Client) CancelOrder(id string) error

func (*Client) CreateDeposit

func (c *Client) CreateDeposit(newDeposit *Deposit) (Deposit, error)

func (*Client) CreateOrder

func (c *Client) CreateOrder(newOrder *Order) (Order, error)

func (*Client) CreateProfileTransfer

func (c *Client) CreateProfileTransfer(newTransfer *ProfileTransfer) error

CreateProfileTransfer transfers a currency amount from one profile to another

func (*Client) CreateReport

func (c *Client) CreateReport(newReport *Report) (Report, error)

func (*Client) CreateTransfer

func (c *Client) CreateTransfer(newTransfer *Transfer) (Transfer, error)

func (*Client) CreateWithdrawalCoinbase

func (c *Client) CreateWithdrawalCoinbase(newWithdrawalCoinbase *WithdrawalCoinbase) (WithdrawalCoinbase, error)

func (*Client) CreateWithdrawalCrypto

func (c *Client) CreateWithdrawalCrypto(newWithdrawalCrypto *WithdrawalCrypto) (WithdrawalCrypto, error)

func (*Client) GetAccount

func (c *Client) GetAccount(id string) (Account, error)

func (*Client) GetAccounts

func (c *Client) GetAccounts() ([]Account, error)

Client Funcs

func (*Client) GetBook

func (c *Client) GetBook(product string, level int) (Book, error)

func (*Client) GetCurrencies

func (c *Client) GetCurrencies() ([]Currency, error)

func (*Client) GetFees

func (c *Client) GetFees() (Fees, error)

func (*Client) GetHistoricRates

func (c *Client) GetHistoricRates(product string,
	p ...GetHistoricRatesParams) ([]HistoricRate, error)

func (*Client) GetOrder

func (c *Client) GetOrder(id string) (Order, error)

func (*Client) GetPaymentMethods

func (c *Client) GetPaymentMethods() ([]PaymentMethod, error)

func (*Client) GetProducts

func (c *Client) GetProducts() ([]Product, error)

func (*Client) GetProfile

func (c *Client) GetProfile(id string) (Profile, error)

GetProfile retrieves a single profile

func (*Client) GetProfiles

func (c *Client) GetProfiles() ([]Profile, error)

GetProfiles retrieves a list of profiles

func (*Client) GetReportStatus

func (c *Client) GetReportStatus(id string) (Report, error)

func (*Client) GetStats

func (c *Client) GetStats(product string) (Stats, error)

func (*Client) GetTicker

func (c *Client) GetTicker(product string) (Ticker, error)

func (*Client) GetTime

func (c *Client) GetTime() (ServerTime, error)

func (*Client) Headers

func (c *Client) Headers(method, url, timestamp, data string) (map[string]string, error)

Headers generates a map that can be used as headers to authenticate a request

func (*Client) ListAccountLedger

func (c *Client) ListAccountLedger(id string,
	p ...GetAccountLedgerParams) *Cursor

func (*Client) ListFills

func (c *Client) ListFills(p ListFillsParams) *Cursor

func (*Client) ListHolds

func (c *Client) ListHolds(id string, p ...ListHoldsParams) *Cursor

func (*Client) ListOrders

func (c *Client) ListOrders(p ...ListOrdersParams) *Cursor

func (*Client) ListTrades

func (c *Client) ListTrades(product string,
	p ...ListTradesParams) *Cursor

func (*Client) Request

func (c *Client) Request(method string, url string,
	params, result interface{}) (res *http.Response, err error)

func (*Client) UpdateConfig

func (c *Client) UpdateConfig(config *ClientConfig)

type ClientConfig

type ClientConfig struct {
	BaseURL    string
	Key        string
	Passphrase string
	Secret     string
}

type CreateReportParams

type CreateReportParams struct {
	Start time.Time
	End   time.Time
}

type Currency

type Currency struct {
	ID      string `json:"id"`
	Name    string `json:"name"`
	MinSize string `json:"min_size"`
}

type Cursor

type Cursor struct {
	Client     *Client
	Pagination *PaginationParams
	Method     string
	Params     interface{}
	URL        string
	HasMore    bool
}

func NewCursor

func NewCursor(client *Client, method, url string,
	paginationParams *PaginationParams) *Cursor

func (*Cursor) NextPage

func (c *Cursor) NextPage(i interface{}) error

func (*Cursor) Page

func (c *Cursor) Page(i interface{}, direction string) error

func (*Cursor) PrevPage

func (c *Cursor) PrevPage(i interface{}) error

type Deposit

type Deposit struct {
	Currency        string `json:"currency"`
	Amount          string `json:"amount"`
	PaymentMethodID string `json:"payment_method_id"` // PaymentMethodID can be determined by calling GetPaymentMethods()
	// Response fields
	ID       string `json:"id,omitempty"`
	PayoutAt Time   `json:"payout_at,string,omitempty"`
}

type Error

type Error struct {
	Message string `json:"message"`
}

func (Error) Error

func (e Error) Error() string

type Fees

type Fees struct {
	MakerFeeRate string `json:"maker_fee_rate"`
	TakerFeeRate string `json:"taker_fee_rate"`
	USDVolume    string `json:"usd_volume"`
}

type Fill

type Fill struct {
	TradeID   int    `json:"trade_id,int"`
	ProductID string `json:"product_id"`
	Price     string `json:"price"`
	Size      string `json:"size"`
	FillID    string `json:"order_id"`
	CreatedAt Time   `json:"created_at,string"`
	Fee       string `json:"fee"`
	Settled   bool   `json:"settled"`
	Side      string `json:"side"`
	Liquidity string `json:"liquidity"`
}

type GetAccountLedgerParams

type GetAccountLedgerParams struct {
	Pagination PaginationParams
}

type GetHistoricRatesParams

type GetHistoricRatesParams struct {
	Start       time.Time
	End         time.Time
	Granularity int
}

type HistoricRate

type HistoricRate struct {
	Time   time.Time
	Low    float64
	High   float64
	Open   float64
	Close  float64
	Volume float64
}

func (*HistoricRate) UnmarshalJSON

func (e *HistoricRate) UnmarshalJSON(data []byte) error

type Hold

type Hold struct {
	AccountID string `json:"account_id"`
	CreatedAt Time   `json:"created_at,string"`
	UpdatedAt Time   `json:"updated_at,string"`
	Amount    string `json:"amount"`
	Type      string `json:"type"`
	Ref       string `json:"ref"`
}

type LedgerDetails

type LedgerDetails struct {
	OrderID   string `json:"order_id"`
	TradeID   string `json:"trade_id"`
	ProductID string `json:"product_id"`
}

type LedgerEntry

type LedgerEntry struct {
	ID        string        `json:"id,number"`
	CreatedAt Time          `json:"created_at,string"`
	Amount    string        `json:"amount"`
	Balance   string        `json:"balance"`
	Type      string        `json:"type"`
	Details   LedgerDetails `json:"details"`
}

type ListFillsParams

type ListFillsParams struct {
	OrderID    string
	ProductID  string
	Pagination PaginationParams
}

type ListHoldsParams

type ListHoldsParams struct {
	Pagination PaginationParams
}

type ListOrdersParams

type ListOrdersParams struct {
	Status     string
	ProductID  string
	Pagination PaginationParams
}

type ListTradesParams

type ListTradesParams struct {
	Pagination PaginationParams
}

type Message

type Message struct {
	Type          string           `json:"type"`
	ProductID     string           `json:"product_id"`
	ProductIds    []string         `json:"product_ids"`
	Products      []Product        `json:"products"`
	Currencies    []Currency       `json:"currencies"`
	TradeID       int              `json:"trade_id,number"`
	OrderID       string           `json:"order_id"`
	ClientOID     string           `json:"client_oid"`
	Sequence      int64            `json:"sequence,number"`
	MakerOrderID  string           `json:"maker_order_id"`
	TakerOrderID  string           `json:"taker_order_id"`
	Time          Time             `json:"time,string"`
	RemainingSize string           `json:"remaining_size"`
	NewSize       string           `json:"new_size"`
	OldSize       string           `json:"old_size"`
	Size          string           `json:"size"`
	Price         string           `json:"price"`
	Side          string           `json:"side"`
	Reason        string           `json:"reason"`
	OrderType     string           `json:"order_type"`
	Funds         string           `json:"funds"`
	NewFunds      string           `json:"new_funds"`
	OldFunds      string           `json:"old_funds"`
	Message       string           `json:"message"`
	Bids          []SnapshotEntry  `json:"bids,omitempty"`
	Asks          []SnapshotEntry  `json:"asks,omitempty"`
	Changes       []SnapshotChange `json:"changes,omitempty"`
	LastSize      string           `json:"last_size"`
	BestBid       string           `json:"best_bid"`
	BestAsk       string           `json:"best_ask"`
	Channels      []MessageChannel `json:"channels"`
	UserID        string           `json:"user_id"`
	ProfileID     string           `json:"profile_id"`
	LastTradeID   int              `json:"last_trade_id"`
}

func (Message) Sign

func (m Message) Sign(secret, key, passphrase string) (SignedMessage, error)

type MessageChannel

type MessageChannel struct {
	Name       string   `json:"name"`
	ProductIds []string `json:"product_ids"`
}

type Order

type Order struct {
	Type      string `json:"type"`
	Size      string `json:"size,omitempty"`
	Side      string `json:"side"`
	ProductID string `json:"product_id"`
	ClientOID string `json:"client_oid,omitempty"`
	Stp       string `json:"stp,omitempty"`
	Stop      string `json:"stop,omitempty"`
	StopPrice string `json:"stop_price,omitempty"`
	// Limit Order
	Price       string `json:"price,omitempty"`
	TimeInForce string `json:"time_in_force,omitempty"`
	PostOnly    bool   `json:"post_only,omitempty"`
	CancelAfter string `json:"cancel_after,omitempty"`
	// Market Order
	Funds          string `json:"funds,omitempty"`
	SpecifiedFunds string `json:"specified_funds,omitempty"`
	// Response Fields
	ID            string `json:"id"`
	Status        string `json:"status,omitempty"`
	Settled       bool   `json:"settled,omitempty"`
	DoneReason    string `json:"done_reason,omitempty"`
	DoneAt        Time   `json:"done_at,string,omitempty"`
	CreatedAt     Time   `json:"created_at,string,omitempty"`
	FillFees      string `json:"fill_fees,omitempty"`
	FilledSize    string `json:"filled_size,omitempty"`
	ExecutedValue string `json:"executed_value,omitempty"`
}

type PaginationParams

type PaginationParams struct {
	Limit  int
	Before string
	After  string
	Extra  map[string]string
}

func (*PaginationParams) AddExtraParam

func (p *PaginationParams) AddExtraParam(key, value string)

func (*PaginationParams) Done

func (p *PaginationParams) Done(direction string) bool

func (*PaginationParams) Encode

func (p *PaginationParams) Encode(direction string) string

type PaymentMethod

type PaymentMethod struct {
	Currency string `json:"currency"`
	Type     string `json:"type"`
	ID       string `json:"id"`
}

type Product

type Product struct {
	ID              string `json:"id"`
	BaseCurrency    string `json:"base_currency"`
	QuoteCurrency   string `json:"quote_currency"`
	BaseMinSize     string `json:"base_min_size"`
	BaseMaxSize     string `json:"base_max_size"`
	QuoteIncrement  string `json:"quote_increment"`
	BaseIncrement   string `json:"base_increment"`
	DisplayName     string `json:"display_name"`
	MinMarketFunds  string `json:"min_market_funds"`
	MaxMarketFunds  string `json:"max_market_funds"`
	MarginEnabled   bool   `json:"margin_enabled"`
	PostOnly        bool   `json:"post_only"`
	LimitOnly       bool   `json:"limit_only"`
	CancelOnly      bool   `json:"cancel_only"`
	TradingDisabled bool   `json:"trading_disabled"`
	Status          string `json:"status"`
	StatusMessage   string `json:"status_message"`
}

type Profile

type Profile struct {
	ID        string `json:"id"`
	UserID    string `json:"user_id"`
	Name      string `json:"name"`
	Active    bool   `json:"active"`
	IsDefault bool   `json:"is_default"`
	CreatedAt Time   `json:"created_at,string"`
}

type ProfileTransfer

type ProfileTransfer struct {
	From     string `json:"from"`
	To       string `json:"to"`
	Currency string `json:"currency"`
	Amount   string `json:"amount"`
}

type Report

type Report struct {
	ID          string       `json:"id"`
	Type        string       `json:"type"`
	Status      string       `json:"status"`
	CreatedAt   Time         `json:"created_at,string"`
	CompletedAt Time         `json:"completed_at,string,"`
	ExpiresAt   Time         `json:"expires_at,string"`
	FileURL     string       `json:"file_url"`
	Params      ReportParams `json:"params"`
	StartDate   time.Time
	EndDate     time.Time
}

type ReportParams

type ReportParams struct {
	StartDate time.Time
	EndDate   time.Time
}

type ServerTime

type ServerTime struct {
	ISO   string  `json:"iso"`
	Epoch float64 `json:"epoch,number"`
}

type SignedMessage

type SignedMessage struct {
	Message
	Key        string `json:"key"`
	Passphrase string `json:"passphrase"`
	Timestamp  string `json:"timestamp"`
	Signature  string `json:"signature"`
}

type SnapshotChange

type SnapshotChange struct {
	Side  string
	Price string
	Size  string
}

func (*SnapshotChange) UnmarshalJSON

func (e *SnapshotChange) UnmarshalJSON(data []byte) error

type SnapshotEntry

type SnapshotEntry struct {
	Price string
	Size  string
}

func (*SnapshotEntry) UnmarshalJSON

func (e *SnapshotEntry) UnmarshalJSON(data []byte) error

type Stats

type Stats struct {
	Low         string `json:"low"`
	High        string `json:"high"`
	Open        string `json:"open"`
	Volume      string `json:"volume"`
	Last        string `json:"last"`
	Volume30Day string `json:"volume_30day"`
}

type StringNumber

type StringNumber string

func (*StringNumber) UnmarshalJSON

func (s *StringNumber) UnmarshalJSON(data []byte) error

type Ticker

type Ticker struct {
	TradeID int          `json:"trade_id,number"`
	Price   string       `json:"price"`
	Size    string       `json:"size"`
	Time    Time         `json:"time,string"`
	Bid     string       `json:"bid"`
	Ask     string       `json:"ask"`
	Volume  StringNumber `json:"volume"`
}

type Time

type Time time.Time

func (Time) MarshalJSON

func (t Time) MarshalJSON() ([]byte, error)

MarshalJSON marshal time back to time.Time for json encoding

func (*Time) Scan

func (t *Time) Scan(value interface{}) error

Scan implements the sql.Scanner interface for database deserialization.

func (*Time) Time

func (t *Time) Time() time.Time

func (*Time) UnmarshalJSON

func (t *Time) UnmarshalJSON(data []byte) error

func (Time) Value

func (t Time) Value() (driver.Value, error)

Value implements the driver.Valuer interface for database serialization.

type Trade

type Trade struct {
	TradeID int    `json:"trade_id,number"`
	Price   string `json:"price"`
	Size    string `json:"size"`
	Time    Time   `json:"time,string"`
	Side    string `json:"side"`
}

type Transfer

type Transfer struct {
	Type              string `json:"type"`
	Amount            string `json:"amount"`
	CoinbaseAccountID string `json:"coinbase_account_id,string"`
}

type WithdrawalCoinbase

type WithdrawalCoinbase struct {
	Currency          string `json:"currency"`
	Amount            string `json:"amount"`
	CoinbaseAccountID string `json:"coinbase_account_id"`
}

type WithdrawalCrypto

type WithdrawalCrypto struct {
	Currency      string `json:"currency"`
	Amount        string `json:"amount"`
	CryptoAddress string `json:"crypto_address"`
	ProfileID     string `json:"profile_id"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL