Categorygithub.com/moonr-app/go-coinbasepro
repositorypackage
1.0.1
Repository: https://github.com/moonr-app/go-coinbasepro.git
Documentation: pkg.go.dev

# 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/moonr-app/go-coinbasepro

Significant releases

Use dep to install previous releases

dep ensure --add github.com/moonr-app/[email protected]
  • 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/moonr-app/go-coinbasepro"
)

client, err := coinbasepro.NewClient(
    "coinbase pro key",
    "coinbase pro passphrase",
    "coinbase pro secret",
)
if err != nil {
    // handle error
}

// optional configuration can be provided using function options:
client, err := coinbasepro.NewClient(
    "coinbase pro key",
    "coinbase pro passphrase",
    "coinbase pro secret",
    coinbasepro.WithSandboxEnvironment(),
    coinbasepro.WithHTTPClient(&http.Client{}),
    coinbasepro.WithRetryCount(5),
    coinbasepro.WithRetryInterval(time.Second),
    coinbasepro.WithTimeOffsetSeconds(30),
)
if err != nil {
    // handle error
}

Sandbox

You can switch to the sandbox env by using the following functional option (will default to production if not provided):

coinbasepro.WithSandboxEnvironment()

HTTP Settings

You can use a custom http client by using the following functional option:

coinbasepro.WithHTTPClient(&http.Client{}),

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 & interval which uses exponential backoff using functional options:

(2^(retry_attempt) - 1) / 2 * retryInterval

coinbasepro.WithRetryCount(3),
coinbasepro.WithRetryInterval(500 * time.Millisecond),

// retry count = 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(ctx, &orders); err != nil {
    println(err.Error())
    return
  }

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

Websockets

Listen for websocket messages

  client, err := coinbasepro.NewClient(
    "coinbase pro key", 
	"coinbase pro passphrase", 
	"coinbase pro secret",
  )
  if err != nil { 
    // handle 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",
        },
      },
    },
  }
  
  err := client.Subscribe(ctx, subscribe, func(msg coinbasepro.Message) error {
    println(message.Type)
    return nil
  })

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/moonr-app/go-coinbasepro"
  )

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

Examples

This library supports all public and private endpoints

Get Accounts:

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

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

List Account Ledger:

  var ledgers []coinbasepro.LedgerEntry

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

  for _, a := range accounts {
    cursor := client.ListAccountLedger(a.ID)
    for cursor.HasMore {
      if err := cursor.NextPage(ctx, &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(ctx, order)
  if err != nil {
    println(err.Error())
  }

  println(savedOrder.ID)

Transfer funds:

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

  savedTransfer, err := client.CreateTransfer(ctx, 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(ctx, &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.