aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/_nuts/github.com/fabioberger/coinbase-go/coinbase.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/_nuts/github.com/fabioberger/coinbase-go/coinbase.go')
-rw-r--r--vendor/_nuts/github.com/fabioberger/coinbase-go/coinbase.go460
1 files changed, 460 insertions, 0 deletions
diff --git a/vendor/_nuts/github.com/fabioberger/coinbase-go/coinbase.go b/vendor/_nuts/github.com/fabioberger/coinbase-go/coinbase.go
new file mode 100644
index 0000000..2f5fdb9
--- /dev/null
+++ b/vendor/_nuts/github.com/fabioberger/coinbase-go/coinbase.go
@@ -0,0 +1,460 @@
+// Coinbase-go is a convenient Go wrapper for the Coinbase API
+package coinbase
+
+import (
+ "errors"
+ "strconv"
+ "strings"
+)
+
+// Client is the struct from which all API requests are made
+type Client struct {
+ rpc rpc
+}
+
+// ApiKeyClient instantiates the client with ApiKey Authentication
+func ApiKeyClient(key string, secret string) Client {
+ c := Client{
+ rpc: rpc{
+ auth: apiKeyAuthWithEnv(key, secret, false),
+ mock: false,
+ },
+ }
+ return c
+}
+
+// ApiKeyClientSandbox instantiates the client with ApiKey Authentication for Coinbase Sandbox
+func ApiKeyClientSandbox(key string, secret string) Client {
+ c := Client{
+ rpc: rpc{
+ auth: apiKeyAuthWithEnv(key, secret, true),
+ mock: false,
+ },
+ }
+ return c
+}
+
+// OAuthClient instantiates the client with OAuth Authentication
+func OAuthClient(tokens *oauthTokens) Client {
+ c := Client{
+ rpc: rpc{
+ auth: clientOAuthWithEnv(tokens, false),
+ mock: false,
+ },
+ }
+ return c
+}
+
+// OAuthClientSandbox instantiates the client with OAuth Authentication for Coinbase Sandbox
+func OAuthClientSandbox(tokens *oauthTokens) Client {
+ c := Client{
+ rpc: rpc{
+ auth: clientOAuthWithEnv(tokens, true),
+ mock: false,
+ },
+ }
+ return c
+}
+
+// ApiKeyClientTest instantiates Testing ApiKeyClient. All client methods execute
+// normally except responses are returned from a test_data/ file instead of the coinbase API
+func apiKeyClientTest(key string, secret string) Client {
+ c := ApiKeyClient(key, secret)
+ c.rpc.mock = true
+ return c
+}
+
+// Get sends a GET request and marshals response data into holder
+func (c Client) Get(path string, params interface{}, holder interface{}) error {
+ return c.rpc.Request("GET", path, params, &holder)
+}
+
+// Post sends a POST request and marshals response data into holder
+func (c Client) Post(path string, params interface{}, holder interface{}) error {
+ return c.rpc.Request("POST", path, params, &holder)
+}
+
+// Delete sends a DELETE request and marshals response data into holder
+func (c Client) Delete(path string, params interface{}, holder interface{}) error {
+ return c.rpc.Request("DELETE", path, params, &holder)
+}
+
+// Put sends a PUT request and marshals response data into holder
+func (c Client) Put(path string, params interface{}, holder interface{}) error {
+ return c.rpc.Request("PUT", path, params, &holder)
+}
+
+// GetBalance returns current balance in BTC
+func (c Client) GetBalance() (float64, error) {
+ balance := map[string]string{}
+ if err := c.Get("account/balance", nil, &balance); err != nil {
+ return 0.0, err
+ }
+ balanceFloat, err := strconv.ParseFloat(balance["amount"], 64)
+ if err != nil {
+ return 0, err
+ }
+ return balanceFloat, nil
+}
+
+// GetReceiveAddress returns clients current bitcoin receive address
+func (c Client) GetReceiveAddress() (string, error) {
+ holder := map[string]interface{}{}
+ if err := c.Get("account/receive_address", nil, &holder); err != nil {
+ return "", err
+ }
+ return holder["address"].(string), nil
+}
+
+// GetAllAddresses returns bitcoin addresses associated with client account
+func (c Client) GetAllAddresses(params *AddressesParams) (*addresses, error) {
+ holder := addressesHolder{}
+ if err := c.Get("addresses", params, &holder); err != nil {
+ return nil, err
+ }
+ addresses := addresses{
+ paginationStats: holder.paginationStats,
+ }
+ // Remove one layer of nesting
+ for _, addr := range holder.Addresses {
+ addresses.Addresses = append(addresses.Addresses, addr.Address)
+ }
+ return &addresses, nil
+}
+
+// GenerateReceiveAddress generates and returns a new bitcoin receive address
+func (c Client) GenerateReceiveAddress(params *AddressParams) (string, error) {
+ holder := map[string]interface{}{}
+ if err := c.Post("account/generate_receive_address", params, &holder); err != nil {
+ return "", err
+ }
+ return holder["address"].(string), nil
+}
+
+// SendMoney to either a bitcoin or email address
+func (c Client) SendMoney(params *TransactionParams) (*transactionConfirmation, error) {
+ return c.transactionRequest("POST", "send_money", params)
+}
+
+// RequestMoney from either a bitcoin or email address
+func (c Client) RequestMoney(params *TransactionParams) (*transactionConfirmation, error) {
+ return c.transactionRequest("POST", "request_money", params)
+}
+
+func (c Client) transactionRequest(method string, kind string, params *TransactionParams) (*transactionConfirmation, error) {
+ finalParams := &struct {
+ Transaction *TransactionParams `json:"transaction"`
+ }{
+ Transaction: params,
+ }
+ holder := transactionHolder{}
+ var err error
+ if method == "POST" {
+ err = c.Post("transactions/"+kind, finalParams, &holder)
+ } else if method == "PUT" {
+ err = c.Put("transactions/"+kind, finalParams, &holder)
+ }
+ if err != nil {
+ return nil, err
+ }
+ if err := checkApiErrors(holder.response, kind); err != nil {
+ return nil, err
+ }
+ confirmation := transactionConfirmation{
+ Transaction: holder.Transaction,
+ Transfer: holder.Transfer,
+ }
+ return &confirmation, nil
+}
+
+// ResendRequest resends a transaction request referenced by id
+func (c Client) ResendRequest(id string) (bool, error) {
+ holder := map[string]interface{}{}
+ if err := c.Put("transactions/"+id+"/resend_request", nil, &holder); err != nil {
+ return false, err
+ }
+ if holder["success"].(bool) {
+ return true, nil
+ }
+ return false, nil
+}
+
+// CancelRequest cancels a transaction request referenced by id
+func (c Client) CancelRequest(id string) (bool, error) {
+ holder := map[string]interface{}{}
+ if err := c.Delete("transactions/"+id+"/cancel_request", nil, &holder); err != nil {
+ return false, err
+ }
+ if holder["success"].(bool) {
+ return true, nil
+ }
+ return false, nil
+}
+
+// CompleteRequest completes a money request referenced by id
+func (c Client) CompleteRequest(id string) (*transactionConfirmation, error) {
+ return c.transactionRequest("PUT", id+"/complete_request", nil)
+}
+
+// CreateButton gets a new payment button including EmbedHtml as a field on button struct
+func (c Client) CreateButton(params *Button) (*Button, error) {
+ finalParams := &struct {
+ Button *Button `json:"button"`
+ }{
+ Button: params,
+ }
+ holder := buttonHolder{}
+ if err := c.Post("buttons", finalParams, &holder); err != nil {
+ return nil, err
+ }
+ if err := checkApiErrors(holder.response, "CreateButton"); err != nil {
+ return nil, err
+ }
+ button := holder.Button
+ button.EmbedHtml = "<div class=\"coinbase-button\" data-code=\"" + button.Code + "\"></div><script src=\"https://coinbase.com/assets/button.js\" type=\"text/javascript\"></script>"
+ return &button, nil
+}
+
+// CreateOrderFromButtonCode creates an order for a given button code
+func (c Client) CreateOrderFromButtonCode(buttonCode string) (*order, error) {
+ holder := orderHolder{}
+ if err := c.Post("buttons/"+buttonCode+"/create_order", nil, &holder); err != nil {
+ return nil, err
+ }
+ if err := checkApiErrors(holder.response, "CreateOrderFromButtonCode"); err != nil {
+ return nil, err
+ }
+ return &holder.Order, nil
+}
+
+// CreateUser creates a new user given an email and password
+func (c Client) CreateUser(email string, password string) (*user, error) {
+ params := map[string]interface{}{
+ "user[email]": email,
+ "user[password]": password,
+ }
+ holder := userHolder{}
+ if err := c.Post("users", params, &holder); err != nil {
+ return nil, err
+ }
+ if err := checkApiErrors(holder.response, "CreateUser"); err != nil {
+ return nil, err
+ }
+ return &holder.User, nil
+}
+
+// Buy an amount of BTC and bypass rate limits by setting agreeBtcAmountVaries to true
+func (c Client) Buy(amount float64, agreeBtcAmountVaries bool) (*transfer, error) {
+ params := map[string]interface{}{
+ "qty": amount,
+ "agree_btc_amount_varies": agreeBtcAmountVaries,
+ }
+ holder := transferHolder{}
+ if err := c.Post("buys", params, &holder); err != nil {
+ return nil, err
+ }
+ if err := checkApiErrors(holder.response, "Buy"); err != nil {
+ return nil, err
+ }
+ return &holder.Transfer, nil
+}
+
+// Sell an amount of BTC
+func (c Client) Sell(amount float64) (*transfer, error) {
+ params := map[string]interface{}{
+ "qty": amount,
+ }
+ holder := transferHolder{}
+ if err := c.Post("sells", params, &holder); err != nil {
+ return nil, err
+ }
+ if err := checkApiErrors(holder.response, "Sell"); err != nil {
+ return nil, err
+ }
+ return &holder.Transfer, nil
+}
+
+// GetContacts gets a users contacts
+func (c Client) GetContacts(params *ContactsParams) (*contactsHolder, error) {
+ holder := contactsHolder{}
+ if err := c.Get("contacts", params, &holder); err != nil {
+ return nil, err
+ }
+ for _, contact := range holder.Contacts {
+ if contact.Contact.Email != "" {
+ holder.Emails = append(holder.Emails, contact.Contact.Email)
+ }
+ }
+ return &holder, nil
+}
+
+// GetCurrencies gets all currency names and ISO's
+func (c Client) GetCurrencies() ([]currency, error) {
+ holder := [][]string{}
+ if err := c.Get("currencies", nil, &holder); err != nil {
+ return nil, err
+ }
+ finalData := []currency{}
+ for _, curr := range holder {
+ class := currency{
+ Name: curr[0],
+ Iso: curr[1],
+ }
+ finalData = append(finalData, class)
+ }
+ return finalData, nil
+}
+
+// GetExchangeRates gets the current exchange rates
+func (c Client) GetExchangeRates() (map[string]string, error) {
+ holder := map[string]string{}
+ if err := c.Get("currencies/exchange_rates", nil, &holder); err != nil {
+ return nil, err
+ }
+ return holder, nil
+}
+
+// GetExchangeRate gets the exchange rate between two specified currencies
+func (c Client) GetExchangeRate(from string, to string) (float64, error) {
+ exchanges, err := c.GetExchangeRates()
+ if err != nil {
+ return 0.0, err
+ }
+ key := from + "_to_" + to
+ if exchanges[key] == "" {
+ return 0.0, errors.New("The exchange rate does not exist for this currency pair")
+ }
+ exchangeFloat, err := strconv.ParseFloat(exchanges[key], 64)
+ if err != nil {
+ return 0.0, err
+ }
+ return exchangeFloat, nil
+}
+
+// GetTransactions gets transactions associated with an account
+func (c Client) GetTransactions(page int) (*transactions, error) {
+ params := map[string]int{
+ "page": page,
+ }
+ holder := transactionsHolder{}
+ if err := c.Get("transactions", params, &holder); err != nil {
+ return nil, err
+ }
+ transactions := transactions{
+ paginationStats: holder.paginationStats,
+ }
+ // Remove one layer of nesting
+ for _, tx := range holder.Transactions {
+ transactions.Transactions = append(transactions.Transactions, tx.Transaction)
+ }
+ return &transactions, nil
+}
+
+// GetOrders gets orders associated with an account
+func (c Client) GetOrders(page int) (*orders, error) {
+ holder := ordersHolder{}
+ params := map[string]int{
+ "page": page,
+ }
+ if err := c.Get("orders", params, &holder); err != nil {
+ return nil, err
+ }
+ orders := orders{
+ paginationStats: holder.paginationStats,
+ }
+ // Remove one layer of nesting
+ for _, o := range holder.Orders {
+ orders.Orders = append(orders.Orders, o.Order)
+ }
+ return &orders, nil
+}
+
+// GetTransfers get transfers associated with an account
+func (c Client) GetTransfers(page int) (*transfers, error) {
+ params := map[string]int{
+ "page": page,
+ }
+ holder := transfersHolder{}
+ if err := c.Get("transfers", params, &holder); err != nil {
+ return nil, err
+ }
+ transfers := transfers{
+ paginationStats: holder.paginationStats,
+ }
+ // Remove one layer of nesting
+ for _, t := range holder.Transfers {
+ transfers.Transfers = append(transfers.Transfers, t.Transfer)
+ }
+ return &transfers, nil
+}
+
+// GetBuyPrice gets the current BTC buy price
+func (c Client) GetBuyPrice(qty int) (*pricesHolder, error) {
+ return c.getPrice("buy", qty)
+}
+
+// GetSellPrice gets the current BTC sell price
+func (c Client) GetSellPrice(qty int) (*pricesHolder, error) {
+ return c.getPrice("sell", qty)
+}
+
+func (c Client) getPrice(kind string, qty int) (*pricesHolder, error) {
+ params := map[string]int{
+ "qty": qty,
+ }
+ holder := pricesHolder{}
+ if err := c.Get("prices/"+kind, params, &holder); err != nil {
+ return nil, err
+ }
+ return &holder, nil
+}
+
+// GetTransaction gets a particular transaction referenced by id
+func (c Client) GetTransaction(id string) (*transaction, error) {
+ holder := transactionHolder{}
+ if err := c.Get("transactions/"+id, nil, &holder); err != nil {
+ return nil, err
+ }
+ if err := checkApiErrors(holder.response, "GetTransaction"); err != nil {
+ return nil, err
+ }
+ return &holder.Transaction, nil
+}
+
+// GetOrder gets a particular order referenced by id
+func (c Client) GetOrder(id string) (*order, error) {
+ holder := orderHolder{}
+ if err := c.Get("orders/"+id, nil, &holder); err != nil {
+ return nil, err
+ }
+ if err := checkApiErrors(holder.response, "GetOrder"); err != nil {
+ return nil, err
+ }
+ return &holder.Order, nil
+}
+
+// GetUser gets the user associated with the authentication
+func (c Client) GetUser() (*user, error) {
+ holder := usersHolder{}
+ if err := c.Get("users", nil, &holder); err != nil {
+ return nil, err
+ }
+ return &holder.Users[0].User, nil
+}
+
+// checkApiErrors checks for errors returned by coinbase API JSON response
+// i.e { "success": false, "errors": ["Button with code code123456 does not exist"], ...}
+func checkApiErrors(resp response, method string) error {
+ if resp.Success == false { // Return errors received from API here
+ err := " in " + method + "()"
+ if resp.Errors != nil {
+ err = strings.Join(resp.Errors, ",") + err
+ return errors.New(err)
+ }
+ if resp.Error != "" { // Return errors received from API here
+ err = resp.Error + err
+ return errors.New(err)
+ }
+ }
+ return nil
+}