mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-14 07:26:47 +00:00
Adds walletRoutes.go Adds method to get all exchange account stuff in go Adds method to get all exchange account stuff in server.js
722 lines
18 KiB
Go
722 lines
18 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"net/url"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
GDAX_API_URL = "https://api.gdax.com/"
|
|
GDAX_API_VERISON = "0"
|
|
GDAX_PRODUCTS = "products"
|
|
GDAX_ORDERBOOK = "book"
|
|
GDAX_TICKER = "ticker"
|
|
GDAX_TRADES = "trades"
|
|
GDAX_HISTORY = "candles"
|
|
GDAX_STATS = "stats"
|
|
GDAX_CURRENCIES = "currencies"
|
|
GDAX_ACCOUNTS = "accounts"
|
|
GDAX_LEDGER = "ledger"
|
|
GDAX_HOLDS = "holds"
|
|
GDAX_ORDERS = "orders"
|
|
GDAX_FILLS = "fills"
|
|
GDAX_TRANSFERS = "transfers"
|
|
GDAX_REPORTS = "reports"
|
|
)
|
|
|
|
type GDAX struct {
|
|
Name string
|
|
Enabled bool
|
|
Verbose bool
|
|
Websocket bool
|
|
RESTPollingDelay time.Duration
|
|
AuthenticatedAPISupport bool
|
|
Password, APIKey, APISecret string
|
|
TakerFee, MakerFee float64
|
|
BaseCurrencies []string
|
|
AvailablePairs []string
|
|
EnabledPairs []string
|
|
}
|
|
|
|
type GDAXTicker struct {
|
|
TradeID int64 `json:"trade_id"`
|
|
Price float64 `json:"price,string"`
|
|
Size float64 `json:"size,string"`
|
|
Time string `json:"time"`
|
|
}
|
|
|
|
type GDAXProduct struct {
|
|
ID string `json:"id"`
|
|
BaseCurrency string `json:"base_currency"`
|
|
QuoteCurrency string `json:"quote_currency"`
|
|
BaseMinSize float64 `json:"base_min_size,string"`
|
|
BaseMaxSize int64 `json:"base_max_size,string"`
|
|
QuoteIncrement float64 `json:"quote_increment,string"`
|
|
DisplayName string `json:"string"`
|
|
}
|
|
|
|
type GDAXOrderL1L2 struct {
|
|
Price float64
|
|
Amount float64
|
|
NumOrders float64
|
|
}
|
|
|
|
type GDAXOrderL3 struct {
|
|
Price float64
|
|
Amount float64
|
|
OrderID string
|
|
}
|
|
|
|
type GDAXOrderbookL1L2 struct {
|
|
Sequence int64 `json:"sequence"`
|
|
Bids [][]GDAXOrderL1L2 `json:"asks"`
|
|
Asks [][]GDAXOrderL1L2 `json:"asks"`
|
|
}
|
|
|
|
type GDAXOrderbookL3 struct {
|
|
Sequence int64 `json:"sequence"`
|
|
Bids [][]GDAXOrderL3 `json:"asks"`
|
|
Asks [][]GDAXOrderL3 `json:"asks"`
|
|
}
|
|
|
|
type GDAXOrderbookResponse struct {
|
|
Sequence int64 `json:"sequence"`
|
|
Bids [][]interface{} `json:"bids"`
|
|
Asks [][]interface{} `json:"asks"`
|
|
}
|
|
|
|
type GDAXTrade struct {
|
|
TradeID int64 `json:"trade_id"`
|
|
Price float64 `json:"price,string"`
|
|
Size float64 `json:"size,string"`
|
|
Time string `json:"time"`
|
|
Side string `json:"side"`
|
|
}
|
|
|
|
type GDAXStats struct {
|
|
Open float64 `json:"open,string"`
|
|
High float64 `json:"high,string"`
|
|
Low float64 `json:"low,string"`
|
|
Volume float64 `json:"volume,string"`
|
|
}
|
|
|
|
type GDAXCurrency struct {
|
|
ID string
|
|
Name string
|
|
MinSize float64 `json:"min_size,string"`
|
|
}
|
|
|
|
type GDAXHistory struct {
|
|
Time int64
|
|
Low float64
|
|
High float64
|
|
Open float64
|
|
Close float64
|
|
Volume float64
|
|
}
|
|
|
|
func (g *GDAX) SetDefaults() {
|
|
g.Name = "GDAX"
|
|
g.Enabled = false
|
|
g.Verbose = false
|
|
g.TakerFee = 0.25
|
|
g.MakerFee = 0
|
|
g.Verbose = false
|
|
g.Websocket = false
|
|
g.RESTPollingDelay = 10
|
|
}
|
|
|
|
func (g *GDAX) GetName() string {
|
|
return g.Name
|
|
}
|
|
|
|
func (g *GDAX) SetEnabled(enabled bool) {
|
|
g.Enabled = enabled
|
|
}
|
|
|
|
func (g *GDAX) IsEnabled() bool {
|
|
return g.Enabled
|
|
}
|
|
|
|
func (g *GDAX) Setup(exch Exchanges) {
|
|
if !exch.Enabled {
|
|
g.SetEnabled(false)
|
|
} else {
|
|
g.Enabled = true
|
|
g.AuthenticatedAPISupport = exch.AuthenticatedAPISupport
|
|
g.SetAPIKeys(exch.ClientID, exch.APIKey, exch.APISecret)
|
|
g.RESTPollingDelay = exch.RESTPollingDelay
|
|
g.Verbose = exch.Verbose
|
|
g.Websocket = exch.Websocket
|
|
g.BaseCurrencies = SplitStrings(exch.BaseCurrencies, ",")
|
|
g.AvailablePairs = SplitStrings(exch.AvailablePairs, ",")
|
|
g.EnabledPairs = SplitStrings(exch.EnabledPairs, ",")
|
|
}
|
|
}
|
|
|
|
func (k *GDAX) GetEnabledCurrencies() []string {
|
|
return k.EnabledPairs
|
|
}
|
|
|
|
func (g *GDAX) Start() {
|
|
go g.Run()
|
|
}
|
|
|
|
func (g *GDAX) GetFee(maker bool) float64 {
|
|
if maker {
|
|
return g.MakerFee
|
|
} else {
|
|
return g.TakerFee
|
|
}
|
|
}
|
|
|
|
func (g *GDAX) Run() {
|
|
if g.Verbose {
|
|
log.Printf("%s Websocket: %s. (url: %s).\n", g.GetName(), IsEnabled(g.Websocket), GDAX_WEBSOCKET_URL)
|
|
log.Printf("%s polling delay: %ds.\n", g.GetName(), g.RESTPollingDelay)
|
|
log.Printf("%s %d currencies enabled: %s.\n", g.GetName(), len(g.EnabledPairs), g.EnabledPairs)
|
|
}
|
|
|
|
if g.Websocket {
|
|
go g.WebsocketClient()
|
|
}
|
|
|
|
exchangeProducts, err := g.GetProducts()
|
|
if err != nil {
|
|
log.Printf("%s Failed to get available products.\n", g.GetName())
|
|
} else {
|
|
currencies := []string{}
|
|
for _, x := range exchangeProducts {
|
|
if x.ID != "BTC" && x.ID != "USD" && x.ID != "GBP" {
|
|
currencies = append(currencies, x.ID[0:3]+x.ID[4:])
|
|
}
|
|
}
|
|
diff := StringSliceDifference(g.AvailablePairs, currencies)
|
|
if len(diff) > 0 {
|
|
exch, err := GetExchangeConfig(g.Name)
|
|
if err != nil {
|
|
log.Println(err)
|
|
} else {
|
|
log.Printf("%s Updating available pairs. Difference: %s.\n", g.Name, diff)
|
|
exch.AvailablePairs = JoinStrings(currencies, ",")
|
|
UpdateExchangeConfig(exch)
|
|
}
|
|
}
|
|
}
|
|
|
|
for g.Enabled {
|
|
for _, x := range g.EnabledPairs {
|
|
currency := x[0:3] + "-" + x[3:]
|
|
go func() {
|
|
stats, err := g.GetStats(currency)
|
|
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
ticker, err := g.GetTicker(currency)
|
|
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
log.Printf("GDAX %s: Last %f High %f Low %f Volume %f\n", currency, ticker.Price, stats.High, stats.Low, stats.Volume)
|
|
AddExchangeInfo(g.GetName(), currency[0:3], currency[4:], ticker.Price, stats.Volume)
|
|
}()
|
|
}
|
|
time.Sleep(time.Second * g.RESTPollingDelay)
|
|
}
|
|
}
|
|
|
|
func (g *GDAX) SetAPIKeys(password, apiKey, apiSecret string) {
|
|
if !g.AuthenticatedAPISupport {
|
|
return
|
|
}
|
|
|
|
g.Password = password
|
|
g.APIKey = apiKey
|
|
result, err := Base64Decode(apiSecret)
|
|
|
|
if err != nil {
|
|
log.Printf("%s unable to decode secret key.", g.GetName())
|
|
g.Enabled = false
|
|
return
|
|
}
|
|
|
|
g.APISecret = string(result)
|
|
}
|
|
|
|
func (g *GDAX) GetProducts() ([]GDAXProduct, error) {
|
|
products := []GDAXProduct{}
|
|
err := SendHTTPGetRequest(GDAX_API_URL+GDAX_PRODUCTS, true, &products)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return products, nil
|
|
}
|
|
|
|
func (g *GDAX) GetOrderbook(symbol string, level int) (interface{}, error) {
|
|
orderbook := GDAXOrderbookResponse{}
|
|
path := ""
|
|
if level > 0 {
|
|
levelStr := strconv.Itoa(level)
|
|
path = fmt.Sprintf("%s/%s/%s?level=%s", GDAX_API_URL+GDAX_PRODUCTS, symbol, GDAX_ORDERBOOK, levelStr)
|
|
} else {
|
|
path = fmt.Sprintf("%s/%s/%s", GDAX_API_URL+GDAX_PRODUCTS, symbol, GDAX_ORDERBOOK)
|
|
}
|
|
|
|
err := SendHTTPGetRequest(path, true, &orderbook)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if level == 3 {
|
|
ob := GDAXOrderbookL3{}
|
|
ob.Sequence = orderbook.Sequence
|
|
for _, x := range orderbook.Asks {
|
|
price, err := strconv.ParseFloat((x[0].(string)), 64)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
amount, err := strconv.ParseFloat((x[1].(string)), 64)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
order := make([]GDAXOrderL3, 1)
|
|
order[0].Price = price
|
|
order[0].Amount = amount
|
|
order[0].OrderID = x[2].(string)
|
|
ob.Asks = append(ob.Asks, order)
|
|
}
|
|
for _, x := range orderbook.Bids {
|
|
price, err := strconv.ParseFloat((x[0].(string)), 64)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
amount, err := strconv.ParseFloat((x[1].(string)), 64)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
order := make([]GDAXOrderL3, 1)
|
|
order[0].Price = price
|
|
order[0].Amount = amount
|
|
order[0].OrderID = x[2].(string)
|
|
ob.Bids = append(ob.Bids, order)
|
|
}
|
|
return ob, nil
|
|
} else {
|
|
ob := GDAXOrderbookL1L2{}
|
|
ob.Sequence = orderbook.Sequence
|
|
for _, x := range orderbook.Asks {
|
|
price, err := strconv.ParseFloat((x[0].(string)), 64)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
amount, err := strconv.ParseFloat((x[1].(string)), 64)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
order := make([]GDAXOrderL1L2, 1)
|
|
order[0].Price = price
|
|
order[0].Amount = amount
|
|
order[0].NumOrders = x[2].(float64)
|
|
ob.Asks = append(ob.Asks, order)
|
|
}
|
|
for _, x := range orderbook.Bids {
|
|
price, err := strconv.ParseFloat((x[0].(string)), 64)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
amount, err := strconv.ParseFloat((x[1].(string)), 64)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
order := make([]GDAXOrderL1L2, 1)
|
|
order[0].Price = price
|
|
order[0].Amount = amount
|
|
order[0].NumOrders = x[2].(float64)
|
|
ob.Bids = append(ob.Bids, order)
|
|
}
|
|
return ob, nil
|
|
}
|
|
}
|
|
|
|
func (g *GDAX) GetTicker(symbol string) (GDAXTicker, error) {
|
|
ticker := GDAXTicker{}
|
|
path := fmt.Sprintf("%s/%s/%s", GDAX_API_URL+GDAX_PRODUCTS, symbol, GDAX_TICKER)
|
|
err := SendHTTPGetRequest(path, true, &ticker)
|
|
|
|
if err != nil {
|
|
return ticker, err
|
|
}
|
|
return ticker, nil
|
|
}
|
|
|
|
func (g *GDAX) GetTickerPrice(currency string) TickerPrice {
|
|
var tickerPrice TickerPrice
|
|
ticker, err := g.GetTicker(currency)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return TickerPrice{}
|
|
}
|
|
tickerPrice.Ask = ticker.Price
|
|
tickerPrice.CryptoCurrency = currency
|
|
tickerPrice.Volume = ticker.Size
|
|
|
|
return tickerPrice
|
|
}
|
|
|
|
func (g *GDAX) GetTrades(symbol string) ([]GDAXTrade, error) {
|
|
trades := []GDAXTrade{}
|
|
path := fmt.Sprintf("%s/%s/%s", GDAX_API_URL+GDAX_PRODUCTS, symbol, GDAX_TRADES)
|
|
err := SendHTTPGetRequest(path, true, &trades)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return trades, nil
|
|
}
|
|
|
|
func (g *GDAX) GetHistoricRates(symbol string, start, end, granularity int64) ([]GDAXHistory, error) {
|
|
history := []GDAXHistory{}
|
|
values := url.Values{}
|
|
|
|
if start > 0 {
|
|
values.Set("start", strconv.FormatInt(start, 10))
|
|
}
|
|
|
|
if end > 0 {
|
|
values.Set("end", strconv.FormatInt(end, 10))
|
|
}
|
|
|
|
if granularity > 0 {
|
|
values.Set("granularity", strconv.FormatInt(granularity, 10))
|
|
}
|
|
|
|
path := EncodeURLValues(fmt.Sprintf("%s/%s/%s", GDAX_API_URL+GDAX_PRODUCTS, symbol, GDAX_HISTORY), values)
|
|
err := SendHTTPGetRequest(path, true, &history)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return history, nil
|
|
}
|
|
|
|
func (g *GDAX) GetStats(symbol string) (GDAXStats, error) {
|
|
stats := GDAXStats{}
|
|
path := fmt.Sprintf("%s/%s/%s", GDAX_API_URL+GDAX_PRODUCTS, symbol, GDAX_STATS)
|
|
err := SendHTTPGetRequest(path, true, &stats)
|
|
|
|
if err != nil {
|
|
return stats, err
|
|
}
|
|
return stats, nil
|
|
}
|
|
|
|
func (g *GDAX) GetCurrencies() ([]GDAXCurrency, error) {
|
|
currencies := []GDAXCurrency{}
|
|
err := SendHTTPGetRequest(GDAX_API_URL+GDAX_CURRENCIES, true, ¤cies)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return currencies, nil
|
|
}
|
|
|
|
type GDAXAccountResponse struct {
|
|
ID string `json:"id"`
|
|
Balance float64 `json:"balance,string"`
|
|
Hold float64 `json:"hold,string"`
|
|
Available float64 `json:"available,string"`
|
|
Currency string `json:"currency"`
|
|
}
|
|
|
|
func (g *GDAX) GetAccounts() ([]GDAXAccountResponse, error) {
|
|
resp := []GDAXAccountResponse{}
|
|
err := g.SendAuthenticatedHTTPRequest("GET", GDAX_API_URL+GDAX_ACCOUNTS, nil, &resp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return resp, nil
|
|
}
|
|
|
|
func (g *GDAX) GetAccount(account string) (GDAXAccountResponse, error) {
|
|
resp := GDAXAccountResponse{}
|
|
path := fmt.Sprintf("%s/%s", GDAX_ACCOUNTS, account)
|
|
err := g.SendAuthenticatedHTTPRequest("GET", GDAX_API_URL+path, nil, &resp)
|
|
if err != nil {
|
|
return resp, err
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the GDAX exchange
|
|
func (e *GDAX) GetExchangeAccountInfo() (ExchangeAccountInfo, error) {
|
|
var response ExchangeAccountInfo
|
|
response.ExchangeName = e.GetName()
|
|
accountBalance, err := e.GetAccounts()
|
|
if err != nil {
|
|
return response, err
|
|
}
|
|
for i := 0; i < len(accountBalance); i++ {
|
|
var exchangeCurrency ExchangeAccountCurrencyInfo
|
|
exchangeCurrency.CurrencyName = accountBalance[i].Currency
|
|
exchangeCurrency.TotalValue = accountBalance[i].Balance
|
|
exchangeCurrency.Hold = accountBalance[i].Hold
|
|
|
|
response.Currencies = append(response.Currencies, exchangeCurrency)
|
|
}
|
|
return response, nil
|
|
}
|
|
|
|
type GDAXAccountLedgerResponse struct {
|
|
ID string `json:"id"`
|
|
CreatedAt string `json:"created_at"`
|
|
Amount float64 `json:"amount,string"`
|
|
Balance float64 `json:"balance,string"`
|
|
Type string `json:"type"`
|
|
details interface{} `json:"details"`
|
|
}
|
|
|
|
func (g *GDAX) GetAccountHistory(accountID string) ([]GDAXAccountLedgerResponse, error) {
|
|
resp := []GDAXAccountLedgerResponse{}
|
|
path := fmt.Sprintf("%s/%s/%s", GDAX_ACCOUNTS, accountID, GDAX_LEDGER)
|
|
err := g.SendAuthenticatedHTTPRequest("GET", GDAX_API_URL+path, nil, &resp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
type GDAXAccountHolds struct {
|
|
ID string `json:"id"`
|
|
AccountID string `json:"account_id"`
|
|
CreatedAt string `json:"created_at"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
Amount float64 `json:"amount,string"`
|
|
Type string `json:"type"`
|
|
Reference string `json:"ref"`
|
|
}
|
|
|
|
func (g *GDAX) GetHolds(accountID string) ([]GDAXAccountHolds, error) {
|
|
resp := []GDAXAccountHolds{}
|
|
path := fmt.Sprintf("%s/%s/%s", GDAX_ACCOUNTS, accountID, GDAX_HOLDS)
|
|
err := g.SendAuthenticatedHTTPRequest("GET", GDAX_API_URL+path, nil, &resp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (g *GDAX) PlaceOrder(clientRef string, price, amount float64, side string, productID, stp string) (string, error) {
|
|
request := make(map[string]interface{})
|
|
|
|
if clientRef != "" {
|
|
request["client_oid"] = clientRef
|
|
}
|
|
|
|
request["price"] = strconv.FormatFloat(price, 'f', -1, 64)
|
|
request["size"] = strconv.FormatFloat(amount, 'f', -1, 64)
|
|
request["side"] = side
|
|
request["product_id"] = productID
|
|
|
|
if stp != "" {
|
|
request["stp"] = stp
|
|
}
|
|
|
|
type OrderResponse struct {
|
|
ID string `json:"id"`
|
|
}
|
|
|
|
resp := OrderResponse{}
|
|
err := g.SendAuthenticatedHTTPRequest("POST", GDAX_API_URL+GDAX_ORDERS, request, &resp)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return resp.ID, nil
|
|
}
|
|
|
|
func (g *GDAX) CancelOrder(orderID string) error {
|
|
path := fmt.Sprintf("%s/%s", GDAX_ORDERS, orderID)
|
|
err := g.SendAuthenticatedHTTPRequest("DELETE", GDAX_API_URL+path, nil, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type GDAXOrdersResponse struct {
|
|
ID string `json:"id"`
|
|
Size float64 `json:"size,string"`
|
|
Price float64 `json:"price,string"`
|
|
ProductID string `json:"product_id"`
|
|
Status string `json:"status"`
|
|
FilledSize float64 `json:"filled_size,string"`
|
|
FillFees float64 `json:"fill_fees,string"`
|
|
Settled bool `json:"settled"`
|
|
Side string `json:"side"`
|
|
CreatedAt string `json:"created_at"`
|
|
}
|
|
|
|
func (g *GDAX) GetOrders(params url.Values) ([]GDAXOrdersResponse, error) {
|
|
path := EncodeURLValues(GDAX_API_URL+GDAX_ORDERS, params)
|
|
resp := []GDAXOrdersResponse{}
|
|
err := g.SendAuthenticatedHTTPRequest("GET", path, nil, &resp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
type GDAXOrderResponse struct {
|
|
ID string `json:"id"`
|
|
Size float64 `json:"size,string"`
|
|
Price float64 `json:"price,string"`
|
|
DoneReason string `json:"done_reason"`
|
|
Status string `json:"status"`
|
|
Settled bool `json:"settled"`
|
|
FilledSize float64 `json:"filled_size,string"`
|
|
ProductID string `json:"product_id"`
|
|
FillFees float64 `json:"fill_fees,string"`
|
|
Side string `json:"side"`
|
|
CreatedAt string `json:"created_at"`
|
|
DoneAt string `json:"done_at"`
|
|
}
|
|
|
|
func (g *GDAX) GetOrder(orderID string) (GDAXOrderResponse, error) {
|
|
path := fmt.Sprintf("%s/%s", GDAX_ORDERS, orderID)
|
|
resp := GDAXOrderResponse{}
|
|
err := g.SendAuthenticatedHTTPRequest("GET", GDAX_API_URL+path, nil, &resp)
|
|
if err != nil {
|
|
return resp, err
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
type GDAXFillResponse struct {
|
|
TradeID int `json:"trade_id"`
|
|
ProductID string `json:"product_id"`
|
|
Price float64 `json:"price,string"`
|
|
Size float64 `json:"size,string"`
|
|
OrderID string `json:"order_id"`
|
|
CreatedAt string `json:"created_at"`
|
|
Liquidity string `json:"liquidity"`
|
|
Fee float64 `json:"fee,string"`
|
|
Settled bool `json:"settled"`
|
|
Side string `json:"side"`
|
|
}
|
|
|
|
func (g *GDAX) GetFills(params url.Values) ([]GDAXFillResponse, error) {
|
|
path := EncodeURLValues(GDAX_API_URL+GDAX_FILLS, params)
|
|
resp := []GDAXFillResponse{}
|
|
err := g.SendAuthenticatedHTTPRequest("GET", path, nil, &resp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (g *GDAX) Transfer(transferType string, amount float64, accountID string) error {
|
|
request := make(map[string]interface{})
|
|
request["type"] = transferType
|
|
request["amount"] = strconv.FormatFloat(amount, 'f', -1, 64)
|
|
request["GDAX_account_id"] = accountID
|
|
|
|
err := g.SendAuthenticatedHTTPRequest("POST", GDAX_API_URL+GDAX_TRANSFERS, request, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type GDAXReportResponse struct {
|
|
ID string `json:"id"`
|
|
Type string `json:"type"`
|
|
Status string `json:"status"`
|
|
CreatedAt string `json:"created_at"`
|
|
CompletedAt string `json:"completed_at"`
|
|
ExpiresAt string `json:"expires_at"`
|
|
FileURL string `json:"file_url"`
|
|
Params struct {
|
|
StartDate string `json:"start_date"`
|
|
EndDate string `json:"end_date"`
|
|
} `json:params"`
|
|
}
|
|
|
|
func (g *GDAX) GetReport(reportType, startDate, endDate string) (GDAXReportResponse, error) {
|
|
request := make(map[string]interface{})
|
|
request["type"] = reportType
|
|
request["start_date"] = startDate
|
|
request["end_date"] = endDate
|
|
|
|
resp := GDAXReportResponse{}
|
|
err := g.SendAuthenticatedHTTPRequest("POST", GDAX_API_URL+GDAX_REPORTS, request, &resp)
|
|
if err != nil {
|
|
return resp, err
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (g *GDAX) GetReportStatus(reportID string) (GDAXReportResponse, error) {
|
|
path := fmt.Sprintf("%s/%s", GDAX_REPORTS, reportID)
|
|
resp := GDAXReportResponse{}
|
|
err := g.SendAuthenticatedHTTPRequest("POST", GDAX_API_URL+path, nil, &resp)
|
|
if err != nil {
|
|
return resp, err
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (g *GDAX) SendAuthenticatedHTTPRequest(method, path string, params map[string]interface{}, result interface{}) (err error) {
|
|
timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)[0:13]
|
|
payload := []byte("")
|
|
|
|
if params != nil {
|
|
payload, err = JSONEncode(params)
|
|
|
|
if err != nil {
|
|
return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request")
|
|
}
|
|
|
|
if g.Verbose {
|
|
log.Printf("Request JSON: %s\n", payload)
|
|
}
|
|
}
|
|
|
|
message := timestamp + method + path + string(payload)
|
|
hmac := GetHMAC(HASH_SHA256, []byte(message), []byte(g.APISecret))
|
|
headers := make(map[string]string)
|
|
headers["CB-ACCESS-SIGN"] = Base64Encode([]byte(hmac))
|
|
headers["CB-ACCESS-TIMESTAMP"] = timestamp
|
|
headers["CB-ACCESS-KEY"] = g.APIKey
|
|
headers["CB-ACCESS-PASSPHRASE"] = g.Password
|
|
headers["Content-Type"] = "application/json"
|
|
|
|
resp, err := SendHTTPRequest(method, GDAX_API_URL+path, headers, bytes.NewBuffer(payload))
|
|
|
|
if g.Verbose {
|
|
log.Printf("Recieved raw: \n%s\n", resp)
|
|
}
|
|
|
|
err = JSONDecode([]byte(resp), &result)
|
|
|
|
if err != nil {
|
|
return errors.New("Unable to JSON Unmarshal response.")
|
|
}
|
|
|
|
return nil
|
|
}
|