package ccxt // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN: // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code type coinbase struct { Exchange } func NewCoinbaseCore() coinbase { p := coinbase{} setDefaults(&p) return p } func (this *coinbase) Describe() interface{} { return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} { "id": "coinbase", "name": "Coinbase Advanced", "countries": []interface{}{"US"}, "pro": true, "certified": false, "rateLimit": 34, "version": "v2", "userAgent": GetValue(this.UserAgents, "chrome"), "headers": map[string]interface{} { "CB-VERSION": "2018-05-30", }, "has": map[string]interface{} { "CORS": true, "spot": true, "margin": false, "swap": false, "future": false, "option": false, "addMargin": false, "cancelOrder": true, "cancelOrders": true, "closeAllPositions": false, "closePosition": true, "createConvertTrade": true, "createDepositAddress": true, "createLimitBuyOrder": true, "createLimitSellOrder": true, "createMarketBuyOrder": true, "createMarketBuyOrderWithCost": true, "createMarketOrderWithCost": false, "createMarketSellOrder": true, "createMarketSellOrderWithCost": false, "createOrder": true, "createPostOnlyOrder": true, "createReduceOnlyOrder": false, "createStopLimitOrder": true, "createStopMarketOrder": false, "createStopOrder": true, "deposit": true, "editOrder": true, "fetchAccounts": true, "fetchBalance": true, "fetchBidsAsks": true, "fetchBorrowRateHistories": false, "fetchBorrowRateHistory": false, "fetchCanceledOrders": true, "fetchClosedOrders": true, "fetchConvertQuote": true, "fetchConvertTrade": true, "fetchConvertTradeHistory": false, "fetchCrossBorrowRate": false, "fetchCrossBorrowRates": false, "fetchCurrencies": true, "fetchDeposit": true, "fetchDepositAddress": "emulated", "fetchDepositAddresses": false, "fetchDepositAddressesByNetwork": true, "fetchDepositMethodId": true, "fetchDepositMethodIds": true, "fetchDeposits": true, "fetchDepositsWithdrawals": true, "fetchFundingHistory": false, "fetchFundingRate": false, "fetchFundingRateHistory": false, "fetchFundingRates": false, "fetchIndexOHLCV": false, "fetchIsolatedBorrowRate": false, "fetchIsolatedBorrowRates": false, "fetchL2OrderBook": false, "fetchLedger": true, "fetchLeverage": false, "fetchLeverageTiers": false, "fetchMarginMode": false, "fetchMarkets": true, "fetchMarkOHLCV": false, "fetchMyBuys": true, "fetchMySells": true, "fetchMyTrades": true, "fetchOHLCV": true, "fetchOpenInterestHistory": false, "fetchOpenOrders": true, "fetchOrder": true, "fetchOrderBook": true, "fetchOrders": true, "fetchPosition": true, "fetchPositionMode": false, "fetchPositions": true, "fetchPositionsRisk": false, "fetchPremiumIndexOHLCV": false, "fetchTicker": true, "fetchTickers": true, "fetchTime": true, "fetchTrades": true, "fetchTradingFee": "emulated", "fetchTradingFees": true, "fetchWithdrawals": true, "reduceMargin": false, "setLeverage": false, "setMarginMode": false, "setPositionMode": false, "withdraw": true, }, "urls": map[string]interface{} { "logo": "https://user-images.githubusercontent.com/1294454/40811661-b6eceae2-653a-11e8-829e-10bfadb078cf.jpg", "api": map[string]interface{} { "rest": "https://api.coinbase.com", }, "www": "https://www.coinbase.com", "doc": []interface{}{"https://developers.coinbase.com/api/v2", "https://docs.cloud.coinbase.com/advanced-trade/docs/welcome"}, "fees": []interface{}{"https://support.coinbase.com/customer/portal/articles/2109597-buy-sell-bank-transfer-fees", "https://www.coinbase.com/advanced-fees"}, "referral": "https://www.coinbase.com/join/58cbe25a355148797479dbd2", }, "requiredCredentials": map[string]interface{} { "apiKey": true, "secret": true, }, "api": map[string]interface{} { "v2": map[string]interface{} { "public": map[string]interface{} { "get": map[string]interface{} { "currencies": 10.6, "currencies/crypto": 10.6, "time": 10.6, "exchange-rates": 10.6, "users/{user_id}": 10.6, "prices/{symbol}/buy": 10.6, "prices/{symbol}/sell": 10.6, "prices/{symbol}/spot": 10.6, }, }, "private": map[string]interface{} { "get": map[string]interface{} { "accounts": 10.6, "accounts/{account_id}": 10.6, "accounts/{account_id}/addresses": 10.6, "accounts/{account_id}/addresses/{address_id}": 10.6, "accounts/{account_id}/addresses/{address_id}/transactions": 10.6, "accounts/{account_id}/transactions": 10.6, "accounts/{account_id}/transactions/{transaction_id}": 10.6, "accounts/{account_id}/buys": 10.6, "accounts/{account_id}/buys/{buy_id}": 10.6, "accounts/{account_id}/sells": 10.6, "accounts/{account_id}/sells/{sell_id}": 10.6, "accounts/{account_id}/deposits": 10.6, "accounts/{account_id}/deposits/{deposit_id}": 10.6, "accounts/{account_id}/withdrawals": 10.6, "accounts/{account_id}/withdrawals/{withdrawal_id}": 10.6, "payment-methods": 10.6, "payment-methods/{payment_method_id}": 10.6, "user": 10.6, "user/auth": 10.6, }, "post": map[string]interface{} { "accounts": 10.6, "accounts/{account_id}/primary": 10.6, "accounts/{account_id}/addresses": 10.6, "accounts/{account_id}/transactions": 10.6, "accounts/{account_id}/transactions/{transaction_id}/complete": 10.6, "accounts/{account_id}/transactions/{transaction_id}/resend": 10.6, "accounts/{account_id}/buys": 10.6, "accounts/{account_id}/buys/{buy_id}/commit": 10.6, "accounts/{account_id}/sells": 10.6, "accounts/{account_id}/sells/{sell_id}/commit": 10.6, "accounts/{account_id}/deposits": 10.6, "accounts/{account_id}/deposits/{deposit_id}/commit": 10.6, "accounts/{account_id}/withdrawals": 10.6, "accounts/{account_id}/withdrawals/{withdrawal_id}/commit": 10.6, }, "put": map[string]interface{} { "accounts/{account_id}": 10.6, "user": 10.6, }, "delete": map[string]interface{} { "accounts/{id}": 10.6, "accounts/{account_id}/transactions/{transaction_id}": 10.6, }, }, }, "v3": map[string]interface{} { "public": map[string]interface{} { "get": map[string]interface{} { "brokerage/time": 3, "brokerage/market/product_book": 3, "brokerage/market/products": 3, "brokerage/market/products/{product_id}": 3, "brokerage/market/products/{product_id}/candles": 3, "brokerage/market/products/{product_id}/ticker": 3, }, }, "private": map[string]interface{} { "get": map[string]interface{} { "brokerage/accounts": 1, "brokerage/accounts/{account_uuid}": 1, "brokerage/orders/historical/batch": 1, "brokerage/orders/historical/fills": 1, "brokerage/orders/historical/{order_id}": 1, "brokerage/products": 3, "brokerage/products/{product_id}": 3, "brokerage/products/{product_id}/candles": 3, "brokerage/products/{product_id}/ticker": 3, "brokerage/best_bid_ask": 3, "brokerage/product_book": 3, "brokerage/transaction_summary": 3, "brokerage/portfolios": 1, "brokerage/portfolios/{portfolio_uuid}": 1, "brokerage/convert/trade/{trade_id}": 1, "brokerage/cfm/balance_summary": 1, "brokerage/cfm/positions": 1, "brokerage/cfm/positions/{product_id}": 1, "brokerage/cfm/sweeps": 1, "brokerage/intx/portfolio/{portfolio_uuid}": 1, "brokerage/intx/positions/{portfolio_uuid}": 1, "brokerage/intx/positions/{portfolio_uuid}/{symbol}": 1, "brokerage/payment_methods": 1, "brokerage/payment_methods/{payment_method_id}": 1, }, "post": map[string]interface{} { "brokerage/orders": 1, "brokerage/orders/batch_cancel": 1, "brokerage/orders/edit": 1, "brokerage/orders/edit_preview": 1, "brokerage/orders/preview": 1, "brokerage/portfolios": 1, "brokerage/portfolios/move_funds": 1, "brokerage/convert/quote": 1, "brokerage/convert/trade/{trade_id}": 1, "brokerage/cfm/sweeps/schedule": 1, "brokerage/intx/allocate": 1, "brokerage/orders/close_position": 1, }, "put": map[string]interface{} { "brokerage/portfolios/{portfolio_uuid}": 1, }, "delete": map[string]interface{} { "brokerage/portfolios/{portfolio_uuid}": 1, "brokerage/cfm/sweeps": 1, }, }, }, }, "fees": map[string]interface{} { "trading": map[string]interface{} { "taker": this.ParseNumber("0.012"), "maker": this.ParseNumber("0.006"), "tierBased": true, "percentage": true, "tiers": map[string]interface{} { "taker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.006")}, []interface{}{this.ParseNumber("10000"), this.ParseNumber("0.004")}, []interface{}{this.ParseNumber("50000"), this.ParseNumber("0.0025")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.002")}, []interface{}{this.ParseNumber("1000000"), this.ParseNumber("0.0018")}, []interface{}{this.ParseNumber("15000000"), this.ParseNumber("0.0016")}, []interface{}{this.ParseNumber("75000000"), this.ParseNumber("0.0012")}, []interface{}{this.ParseNumber("250000000"), this.ParseNumber("0.0008")}, []interface{}{this.ParseNumber("400000000"), this.ParseNumber("0.0005")}}, "maker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.004")}, []interface{}{this.ParseNumber("10000"), this.ParseNumber("0.0025")}, []interface{}{this.ParseNumber("50000"), this.ParseNumber("0.0015")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.001")}, []interface{}{this.ParseNumber("1000000"), this.ParseNumber("0.0008")}, []interface{}{this.ParseNumber("15000000"), this.ParseNumber("0.0006")}, []interface{}{this.ParseNumber("75000000"), this.ParseNumber("0.0003")}, []interface{}{this.ParseNumber("250000000"), this.ParseNumber("0.0")}, []interface{}{this.ParseNumber("400000000"), this.ParseNumber("0.0")}}, }, }, }, "precisionMode": TICK_SIZE, "exceptions": map[string]interface{} { "exact": map[string]interface{} { "two_factor_required": AuthenticationError, "param_required": ExchangeError, "validation_error": ExchangeError, "invalid_request": ExchangeError, "personal_details_required": AuthenticationError, "identity_verification_required": AuthenticationError, "jumio_verification_required": AuthenticationError, "jumio_face_match_verification_required": AuthenticationError, "unverified_email": AuthenticationError, "authentication_error": AuthenticationError, "invalid_authentication_method": AuthenticationError, "invalid_token": AuthenticationError, "revoked_token": AuthenticationError, "expired_token": AuthenticationError, "invalid_scope": AuthenticationError, "not_found": ExchangeError, "rate_limit_exceeded": RateLimitExceeded, "internal_server_error": ExchangeError, "UNSUPPORTED_ORDER_CONFIGURATION": BadRequest, "INSUFFICIENT_FUND": BadRequest, "PERMISSION_DENIED": PermissionDenied, "INVALID_ARGUMENT": BadRequest, }, "broad": map[string]interface{} { "request timestamp expired": InvalidNonce, "order with this orderID was not found": OrderNotFound, }, }, "timeframes": map[string]interface{} { "1m": "ONE_MINUTE", "5m": "FIVE_MINUTE", "15m": "FIFTEEN_MINUTE", "30m": "THIRTY_MINUTE", "1h": "ONE_HOUR", "2h": "TWO_HOUR", "6h": "SIX_HOUR", "1d": "ONE_DAY", }, "commonCurrencies": map[string]interface{} { "CGLD": "CELO", }, "options": map[string]interface{} { "usePrivate": false, "brokerId": "ccxt", "stablePairs": []interface{}{"BUSD-USD", "CBETH-ETH", "DAI-USD", "GUSD-USD", "GYEN-USD", "PAX-USD", "PAX-USDT", "USDC-EUR", "USDC-GBP", "USDT-EUR", "USDT-GBP", "USDT-USD", "USDT-USDC", "WBTC-BTC"}, "fetchCurrencies": map[string]interface{} { "expires": 5000, }, "accounts": []interface{}{"wallet", "fiat"}, "v3Accounts": []interface{}{"ACCOUNT_TYPE_CRYPTO", "ACCOUNT_TYPE_FIAT"}, "networks": map[string]interface{} { "ERC20": "ethereum", "XLM": "stellar", }, "createMarketBuyOrderRequiresPrice": true, "advanced": true, "fetchMarkets": "fetchMarketsV3", "timeDifference": 0, "adjustForTimeDifference": false, "fetchTicker": "fetchTickerV3", "fetchTickers": "fetchTickersV3", "fetchAccounts": "fetchAccountsV3", "fetchBalance": "v2PrivateGetAccounts", "fetchTime": "v2PublicGetTime", "user_native_currency": "USD", }, "features": map[string]interface{} { "default": map[string]interface{} { "sandbox": false, "createOrder": map[string]interface{} { "marginMode": true, "triggerPrice": true, "triggerPriceType": nil, "triggerDirection": true, "stopLossPrice": true, "takeProfitPrice": true, "attachedStopLossTakeProfit": nil, "timeInForce": map[string]interface{} { "IOC": true, "FOK": true, "PO": true, "GTD": true, }, "hedged": false, "trailing": false, "leverage": true, "marketBuyByCost": true, "marketBuyRequiresPrice": true, "selfTradePrevention": false, "iceberg": false, }, "createOrders": nil, "fetchMyTrades": map[string]interface{} { "marginMode": false, "limit": 3000, "daysBack": nil, "untilDays": 10000, "symbolRequired": false, }, "fetchOrder": map[string]interface{} { "marginMode": false, "trigger": false, "trailing": false, "symbolRequired": false, }, "fetchOpenOrders": map[string]interface{} { "marginMode": false, "limit": nil, "trigger": false, "trailing": false, "symbolRequired": false, }, "fetchOrders": map[string]interface{} { "marginMode": false, "limit": nil, "daysBack": nil, "untilDays": 10000, "trigger": false, "trailing": false, "symbolRequired": false, }, "fetchClosedOrders": map[string]interface{} { "marginMode": false, "limit": nil, "daysBack": nil, "daysBackCanceled": nil, "untilDays": 10000, "trigger": false, "trailing": false, "symbolRequired": false, }, "fetchOHLCV": map[string]interface{} { "limit": 300, }, }, "spot": map[string]interface{} { "extends": "default", }, "swap": map[string]interface{} { "linear": map[string]interface{} { "extends": "default", }, "inverse": nil, }, "future": map[string]interface{} { "linear": map[string]interface{} { "extends": "default", }, "inverse": nil, }, }, }) } /** * @method * @name coinbase#fetchTime * @description fetches the current integer timestamp in milliseconds from the exchange server * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-time#http-request * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.method] 'v2PublicGetTime' or 'v3PublicGetBrokerageTime' default is 'v2PublicGetTime' * @returns {int} the current integer timestamp in milliseconds from the exchange server */ func (this *coinbase) FetchTime(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params var defaultMethod interface{} = this.SafeString(this.Options, "fetchTime", "v2PublicGetTime") var method interface{} = this.SafeString(params, "method", defaultMethod) params = this.Omit(params, "method") var response interface{} = nil if IsTrue(IsEqual(method, "v2PublicGetTime")) { response = (<-this.V2PublicGetTime(params)) PanicOnError(response) // // { // "data": { // "epoch": 1589295679, // "iso": "2020-05-12T15:01:19Z" // } // } // response = this.SafeDict(response, "data", map[string]interface{} {}) } else { response = (<-this.V3PublicGetBrokerageTime(params)) PanicOnError(response) } ch <- this.SafeTimestamp2(response, "epoch", "epochSeconds") return nil }() return ch } /** * @method * @name coinbase#fetchAccounts * @description fetch all the accounts associated with a profile * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getaccounts * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-accounts#list-accounts * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type */ func (this *coinbase) FetchAccounts(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params var method interface{} = this.SafeString(this.Options, "fetchAccounts", "fetchAccountsV3") if IsTrue(IsEqual(method, "fetchAccountsV3")) { retRes51919 := (<-this.FetchAccountsV3(params)) PanicOnError(retRes51919) ch <- retRes51919 return nil } retRes52115 := (<-this.FetchAccountsV2(params)) PanicOnError(retRes52115) ch <- retRes52115 return nil }() return ch } func (this *coinbase) FetchAccountsV2(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes5258 := (<-this.LoadMarkets()) PanicOnError(retRes5258) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchAccounts", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes52919 := (<-this.FetchPaginatedCallCursor("fetchAccounts", nil, nil, nil, params, "next_starting_after", "starting_after", nil, 100)) PanicOnError(retRes52919) ch <- retRes52919 return nil } var request interface{} = map[string]interface{} { "limit": 100, } response:= (<-this.V2PrivateGetAccounts(this.Extend(request, params))) PanicOnError(response) // // { // "pagination": { // "ending_before": null, // "starting_after": null, // "previous_ending_before": null, // "next_starting_after": null, // "limit": 244, // "order": "desc", // "previous_uri": null, // "next_uri": null // }, // "data": [ // { // "id": "XLM", // "name": "XLM Wallet", // "primary": false, // "type": "wallet", // "currency": { // "code": "XLM", // "name": "Stellar Lumens", // "color": "#000000", // "sort_index": 127, // "exponent": 7, // "type": "crypto", // "address_regex": "^G[A-Z2-7]{55}$", // "asset_id": "13b83335-5ede-595b-821e-5bcdfa80560f", // "destination_tag_name": "XLM Memo ID", // "destination_tag_regex": "^[ -~]{1,28}$" // }, // "balance": { // "amount": "0.0000000", // "currency": "XLM" // }, // "created_at": null, // "updated_at": null, // "resource": "account", // "resource_path": "/v2/accounts/XLM", // "allow_deposits": true, // "allow_withdrawals": true // }, // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var pagination interface{} = this.SafeDict(response, "pagination", map[string]interface{} {}) var cursor interface{} = this.SafeString(pagination, "next_starting_after") var accounts interface{} = this.SafeList(response, "data", []interface{}{}) var length interface{} = GetArrayLength(accounts) var lastIndex interface{} = Subtract(length, 1) var last interface{} = this.SafeDict(accounts, lastIndex) if IsTrue(IsTrue((!IsEqual(cursor, nil))) && IsTrue((!IsEqual(cursor, "")))) { AddElementToObject(last, "next_starting_after", cursor) AddElementToObject(accounts, lastIndex, last) } ch <- this.ParseAccounts(data, params) return nil }() return ch } func (this *coinbase) FetchAccountsV3(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes5948 := (<-this.LoadMarkets()) PanicOnError(retRes5948) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchAccounts", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes59819 := (<-this.FetchPaginatedCallCursor("fetchAccounts", nil, nil, nil, params, "cursor", "cursor", nil, 250)) PanicOnError(retRes59819) ch <- retRes59819 return nil } var request interface{} = map[string]interface{} { "limit": 250, } response:= (<-this.V3PrivateGetBrokerageAccounts(this.Extend(request, params))) PanicOnError(response) // // { // "accounts": [ // { // "uuid": "11111111-1111-1111-1111-111111111111", // "name": "USDC Wallet", // "currency": "USDC", // "available_balance": { // "value": "0.0000000000000000", // "currency": "USDC" // }, // "default": true, // "active": true, // "created_at": "2023-01-04T06:20:06.456Z", // "updated_at": "2023-01-04T06:20:07.181Z", // "deleted_at": null, // "type": "ACCOUNT_TYPE_CRYPTO", // "ready": false, // "hold": { // "value": "0.0000000000000000", // "currency": "USDC" // } // }, // ... // ], // "has_next": false, // "cursor": "", // "size": 9 // } // var accounts interface{} = this.SafeList(response, "accounts", []interface{}{}) var length interface{} = GetArrayLength(accounts) var lastIndex interface{} = Subtract(length, 1) var last interface{} = this.SafeDict(accounts, lastIndex) var cursor interface{} = this.SafeString(response, "cursor") if IsTrue(IsTrue((!IsEqual(cursor, nil))) && IsTrue((!IsEqual(cursor, "")))) { AddElementToObject(last, "cursor", cursor) AddElementToObject(accounts, lastIndex, last) } ch <- this.ParseAccounts(accounts, params) return nil }() return ch } /** * @method * @name coinbase#fetchPortfolios * @description fetch all the portfolios * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getportfolios * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type */ func (this *coinbase) FetchPortfolios(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params response:= (<-this.V3PrivateGetBrokeragePortfolios(params)) PanicOnError(response) var portfolios interface{} = this.SafeList(response, "portfolios", []interface{}{}) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(portfolios)); i++ { var portfolio interface{} = GetValue(portfolios, i) AppendToArray(&result,map[string]interface{} { "id": this.SafeString(portfolio, "uuid"), "type": this.SafeString(portfolio, "type"), "code": nil, "info": portfolio, }) } ch <- result return nil }() return ch } func (this *coinbase) ParseAccount(account interface{}) interface{} { // // fetchAccountsV2 // // { // "id": "XLM", // "name": "XLM Wallet", // "primary": false, // "type": "wallet", // "currency": { // "code": "XLM", // "name": "Stellar Lumens", // "color": "#000000", // "sort_index": 127, // "exponent": 7, // "type": "crypto", // "address_regex": "^G[A-Z2-7]{55}$", // "asset_id": "13b83335-5ede-595b-821e-5bcdfa80560f", // "destination_tag_name": "XLM Memo ID", // "destination_tag_regex": "^[ -~]{1,28}$" // }, // "balance": { // "amount": "0.0000000", // "currency": "XLM" // }, // "created_at": null, // "updated_at": null, // "resource": "account", // "resource_path": "/v2/accounts/XLM", // "allow_deposits": true, // "allow_withdrawals": true // } // // fetchAccountsV3 // // { // "uuid": "11111111-1111-1111-1111-111111111111", // "name": "USDC Wallet", // "currency": "USDC", // "available_balance": { // "value": "0.0000000000000000", // "currency": "USDC" // }, // "default": true, // "active": true, // "created_at": "2023-01-04T06:20:06.456Z", // "updated_at": "2023-01-04T06:20:07.181Z", // "deleted_at": null, // "type": "ACCOUNT_TYPE_CRYPTO", // "ready": false, // "hold": { // "value": "0.0000000000000000", // "currency": "USDC" // } // } // var active interface{} = this.SafeBool(account, "active") var currencyIdV3 interface{} = this.SafeString(account, "currency") var currency interface{} = this.SafeDict(account, "currency", map[string]interface{} {}) var currencyId interface{} = this.SafeString(currency, "code", currencyIdV3) var typeV3 interface{} = this.SafeString(account, "name") var typeV2 interface{} = this.SafeString(account, "type") var parts interface{} = Split(typeV3, " ") return map[string]interface{} { "id": this.SafeString2(account, "id", "uuid"), "type": Ternary(IsTrue((!IsEqual(active, nil))), this.SafeStringLower(parts, 1), typeV2), "code": this.SafeCurrencyCode(currencyId), "info": account, } } /** * @method * @name coinbase#createDepositAddress * @description create a currency deposit address * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-addresses#create-address * @param {string} code unified currency code of the currency for the deposit address * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure} */ func (this *coinbase) CreateDepositAddress(code interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params var accountId interface{} = this.SafeString(params, "account_id") params = this.Omit(params, "account_id") if IsTrue(IsEqual(accountId, nil)) { retRes75412 := (<-this.LoadAccounts()) PanicOnError(retRes75412) for i := 0; IsLessThan(i, GetArrayLength(this.Accounts)); i++ { var account interface{} = GetValue(this.Accounts, i) if IsTrue(IsTrue(IsEqual(GetValue(account, "code"), code)) && IsTrue(IsEqual(GetValue(account, "type"), "wallet"))) { accountId = GetValue(account, "id") break } } } if IsTrue(IsEqual(accountId, nil)) { panic(ExchangeError(Add(Add(Add(this.Id, " createDepositAddress() could not find the account with matching currency code "), code), ", specify an `account_id` extra param to target specific wallet"))) } var request interface{} = map[string]interface{} { "account_id": accountId, } response:= (<-this.V2PrivatePostAccountsAccountIdAddresses(this.Extend(request, params))) PanicOnError(response) // // { // "data": { // "id": "05b1ebbf-9438-5dd4-b297-2ddedc98d0e4", // "address": "coinbasebase", // "address_info": { // "address": "coinbasebase", // "destination_tag": "287594668" // }, // "name": null, // "created_at": "2019-07-01T14:39:29Z", // "updated_at": "2019-07-01T14:39:29Z", // "network": "eosio", // "uri_scheme": "eosio", // "resource": "address", // "resource_path": "/v2/accounts/14cfc769-e852-52f3-b831-711c104d194c/addresses/05b1ebbf-9438-5dd4-b297-2ddedc98d0e4", // "warnings": [ // { // "title": "Only send EOS (EOS) to this address", // "details": "Sending any other cryptocurrency will result in permanent loss.", // "image_url": "https://dynamic-assets.coinbase.com/deaca3d47b10ed4a91a872e9618706eec34081127762d88f2476ac8e99ada4b48525a9565cf2206d18c04053f278f693434af4d4629ca084a9d01b7a286a7e26/asset_icons/1f8489bb280fb0a0fd643c1161312ba49655040e9aaaced5f9ad3eeaf868eadc.png" // }, // { // "title": "Both an address and EOS memo are required to receive EOS", // "details": "If you send funds without an EOS memo or with an incorrect EOS memo, your funds cannot be credited to your account.", // "image_url": "https://www.coinbase.com/assets/receive-warning-2f3269d83547a7748fb39d6e0c1c393aee26669bfea6b9f12718094a1abff155.png" // } // ], // "warning_title": "Only send EOS (EOS) to this address", // "warning_details": "Sending any other cryptocurrency will result in permanent loss.", // "destination_tag": "287594668", // "deposit_uri": "eosio:coinbasebase?dt=287594668", // "callback_url": null // } // } // var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) var tag interface{} = this.SafeString(data, "destination_tag") var address interface{} = this.SafeString(data, "address") ch <- map[string]interface{} { "currency": code, "tag": tag, "address": address, "info": response, } return nil }() return ch } /** * @method * @name coinbase#fetchMySells * @ignore * @description fetch sells * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-sells#list-sells * @param {string} symbol not used by coinbase fetchMySells () * @param {int} [since] timestamp in ms of the earliest sell, default is undefined * @param {int} [limit] max number of sells to return, default is undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [list of order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *coinbase) FetchMySells(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) // v2 did't have an endpoint for all historical trades symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params var request interface{} = this.PrepareAccountRequest(limit, params) retRes8328 := (<-this.LoadMarkets()) PanicOnError(retRes8328) var query interface{} = this.Omit(params, []interface{}{"account_id", "accountId"}) sells:= (<-this.V2PrivateGetAccountsAccountIdSells(this.Extend(request, query))) PanicOnError(sells) ch <- this.ParseTrades(GetValue(sells, "data"), nil, since, limit) return nil }() return ch } /** * @method * @name coinbase#fetchMyBuys * @ignore * @description fetch buys * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-buys#list-buys * @param {string} symbol not used by coinbase fetchMyBuys () * @param {int} [since] timestamp in ms of the earliest buy, default is undefined * @param {int} [limit] max number of buys to return, default is undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *coinbase) FetchMyBuys(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) // v2 did't have an endpoint for all historical trades symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params var request interface{} = this.PrepareAccountRequest(limit, params) retRes8538 := (<-this.LoadMarkets()) PanicOnError(retRes8538) var query interface{} = this.Omit(params, []interface{}{"account_id", "accountId"}) buys:= (<-this.V2PrivateGetAccountsAccountIdBuys(this.Extend(request, query))) PanicOnError(buys) ch <- this.ParseTrades(GetValue(buys, "data"), nil, since, limit) return nil }() return ch } func (this *coinbase) FetchTransactionsWithMethod(method interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params var request interface{} = nil requestparamsVariable := (<-this.PrepareAccountRequestWithCurrencyCode(code, limit, params)); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) retRes8628 := (<-this.LoadMarkets()) PanicOnError(retRes8628) response:= (<-this.callDynamically(method, this.Extend(request, params))) PanicOnError(response) ch <- this.ParseTransactions(GetValue(response, "data"), nil, since, limit) return nil }() return ch } /** * @method * @name coinbase#fetchWithdrawals * @description Fetch all withdrawals made from an account. Won't return crypto withdrawals. Use fetchLedger for those. * @see https://docs.cdp.coinbase.com/coinbase-app/docs/api-withdrawals#list-withdrawals * @param {string} code unified currency code * @param {int} [since] the earliest time in ms to fetch withdrawals for * @param {int} [limit] the maximum number of withdrawals structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.currencyType] "fiat" or "crypto" * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *coinbase) FetchWithdrawals(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params var currencyType interface{} = nil currencyTypeparamsVariable := this.HandleOptionAndParams(params, "fetchWithdrawals", "currencyType"); currencyType = GetValue(currencyTypeparamsVariable,0); params = GetValue(currencyTypeparamsVariable,1) if IsTrue(IsEqual(currencyType, "crypto")) { results:= (<-this.FetchTransactionsWithMethod("v2PrivateGetAccountsAccountIdTransactions", code, since, limit, params)) PanicOnError(results) ch <- this.FilterByArray(results, "type", "withdrawal", false) return nil } retRes88615 := (<-this.FetchTransactionsWithMethod("v2PrivateGetAccountsAccountIdWithdrawals", code, since, limit, params)) PanicOnError(retRes88615) ch <- retRes88615 return nil }() return ch } /** * @method * @name coinbase#fetchDeposits * @description Fetch all fiat deposits made to an account. Won't return crypto deposits or staking rewards. Use fetchLedger for those. * @see https://docs.cdp.coinbase.com/coinbase-app/docs/api-deposits#list-deposits * @param {string} code unified currency code * @param {int} [since] the earliest time in ms to fetch deposits for * @param {int} [limit] the maximum number of deposits structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.currencyType] "fiat" or "crypto" * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *coinbase) FetchDeposits(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params var currencyType interface{} = nil currencyTypeparamsVariable := this.HandleOptionAndParams(params, "fetchWithdrawals", "currencyType"); currencyType = GetValue(currencyTypeparamsVariable,0); params = GetValue(currencyTypeparamsVariable,1) if IsTrue(IsEqual(currencyType, "crypto")) { results:= (<-this.FetchTransactionsWithMethod("v2PrivateGetAccountsAccountIdTransactions", code, since, limit, params)) PanicOnError(results) ch <- this.FilterByArray(results, "type", "deposit", false) return nil } retRes90815 := (<-this.FetchTransactionsWithMethod("v2PrivateGetAccountsAccountIdDeposits", code, since, limit, params)) PanicOnError(retRes90815) ch <- retRes90815 return nil }() return ch } /** * @method * @name coinbase#fetchDepositsWithdrawals * @description fetch history of deposits and withdrawals * @see https://docs.cdp.coinbase.com/coinbase-app/docs/api-transactions * @param {string} [code] unified currency code for the currency of the deposit/withdrawals, default is undefined * @param {int} [since] timestamp in ms of the earliest deposit/withdrawal, default is undefined * @param {int} [limit] max number of deposit/withdrawals to return, default = 50, Min: 1, Max: 100 * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a list of [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *coinbase) FetchDepositsWithdrawals(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes9238 := (<-this.LoadMarkets()) PanicOnError(retRes9238) results:= (<-this.FetchTransactionsWithMethod("v2PrivateGetAccountsAccountIdTransactions", code, since, limit, params)) PanicOnError(results) ch <- this.FilterByArray(results, "type", []interface{}{"deposit", "withdrawal"}, false) return nil }() return ch } func (this *coinbase) ParseTransactionStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "created": "pending", "completed": "ok", "canceled": "canceled", } return this.SafeString(statuses, status, status) } func (this *coinbase) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} { // // fiat deposit // // { // "id": "f34c19f3-b730-5e3d-9f72", // "status": "completed", // "payment_method": { // "id": "a022b31d-f9c7-5043-98f2", // "resource": "payment_method", // "resource_path": "/v2/payment-methods/a022b31d-f9c7-5043-98f2" // }, // "transaction": { // "id": "04ed4113-3732-5b0c-af86-b1d2146977d0", // "resource": "transaction", // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/transactions/04ed4113-3732-5b0c-af86" // }, // "user_reference": "2VTYTH", // "created_at": "2017-02-09T07:01:18Z", // "updated_at": "2017-02-09T07:01:26Z", // "resource": "deposit", // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/deposits/f34c19f3-b730-5e3d-9f72", // "committed": true, // "payout_at": "2017-02-12T07:01:17Z", // "instant": false, // "fee": { "amount": "0.00", "currency": "EUR" }, // "amount": { "amount": "114.02", "currency": "EUR" }, // "subtotal": { "amount": "114.02", "currency": "EUR" }, // "hold_until": null, // "hold_days": 0, // "hold_business_days": 0, // "next_step": null // } // // fiat_withdrawal // // { // "id": "cfcc3b4a-eeb6-5e8c-8058", // "status": "completed", // "payment_method": { // "id": "8b94cfa4-f7fd-5a12-a76a", // "resource": "payment_method", // "resource_path": "/v2/payment-methods/8b94cfa4-f7fd-5a12-a76a" // }, // "transaction": { // "id": "fcc2550b-5104-5f83-a444", // "resource": "transaction", // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/transactions/fcc2550b-5104-5f83-a444" // }, // "user_reference": "MEUGK", // "created_at": "2018-07-26T08:55:12Z", // "updated_at": "2018-07-26T08:58:18Z", // "resource": "withdrawal", // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/withdrawals/cfcc3b4a-eeb6-5e8c-8058", // "committed": true, // "payout_at": "2018-07-31T08:55:12Z", // "instant": false, // "fee": { "amount": "0.15", "currency": "EUR" }, // "amount": { "amount": "13130.69", "currency": "EUR" }, // "subtotal": { "amount": "13130.84", "currency": "EUR" }, // "idem": "e549dee5-63ed-4e79-8a96", // "next_step": null // } // // withdraw // // { // "id": "a1794ecf-5693-55fa-70cf-ef731748ed82", // "type": "send", // "status": "pending", // "amount": { // "amount": "-14.008308", // "currency": "USDC" // }, // "native_amount": { // "amount": "-18.74", // "currency": "CAD" // }, // "description": null, // "created_at": "2024-01-12T01:27:31Z", // "updated_at": "2024-01-12T01:27:31Z", // "resource": "transaction", // "resource_path": "/v2/accounts/a34bgfad-ed67-538b-bffc-730c98c10da0/transactions/a1794ecf-5693-55fa-70cf-ef731748ed82", // "instant_exchange": false, // "network": { // "status": "pending", // "status_description": "Pending (est. less than 10 minutes)", // "transaction_fee": { // "amount": "4.008308", // "currency": "USDC" // }, // "transaction_amount": { // "amount": "10.000000", // "currency": "USDC" // }, // "confirmations": 0 // }, // "to": { // "resource": "ethereum_address", // "address": "0x9...", // "currency": "USDC", // "address_info": { // "address": "0x9..." // } // }, // "idem": "748d8591-dg9a-7831-a45b-crd61dg78762", // "details": { // "title": "Sent USDC", // "subtitle": "To USDC address on Ethereum network", // "header": "Sent 14.008308 USDC ($18.74)", // "health": "warning" // }, // "hide_native_amount": false // } // // // crypto deposit & withdrawal (using `/transactions` endpoint) // { // "amount": { // "amount": "0.00014200", (negative for withdrawal) // "currency": "BTC" // }, // "created_at": "2024-03-29T15:48:30Z", // "id": "0031a605-241d-514d-a97b-d4b99f3225d3", // "idem": "092a979b-017e-4403-940a-2ca57811f442", // field present only in case of withdrawal // "native_amount": { // "amount": "9.85", (negative for withdrawal) // "currency": "USD" // }, // "network": { // "status": "pending", // if status is `off_blockchain` then no more other fields are present in this object // "hash": "5jYuvrNsvX2DZoMnzGYzVpYxJLfYu4GSK3xetG1H5LHrSovsuFCFYdFMwNRoiht3s6fBk92MM8QLLnz65xuEFTrE", // "network_name": "solana", // "transaction_fee": { // "amount": "0.000100000", // "currency": "SOL" // } // }, // "resource": "transaction", // "resource_path": "/v2/accounts/dc504b1c-248e-5b68-a3b0-b991f7fa84e6/transactions/0031a605-241d-514d-a97b-d4b99f3225d3", // "status": "completed", // "type": "send", // "from": { // in some cases, field might be present for deposit // "id": "7fd10cd7-b091-5cee-ba41-c29e49a7cccf", // "name": "Coinbase", // "resource": "user" // }, // "to": { // field only present for withdrawal // "address": "5HA12BNthAvBwNYARYf9y5MqqCpB4qhCNFCs1Qw48ACE", // "resource": "address" // }, // "description": "C3 - One Time BTC Credit . Reference Case # 123.", // in some cases, field might be present for deposit // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var transactionType interface{} = this.SafeString(transaction, "type") var amountAndCurrencyObject interface{} = nil var feeObject interface{} = nil var network interface{} = this.SafeDict(transaction, "network", map[string]interface{} {}) if IsTrue(IsEqual(transactionType, "send")) { amountAndCurrencyObject = this.SafeDict(network, "transaction_amount") feeObject = this.SafeDict(network, "transaction_fee", map[string]interface{} {}) } else { amountAndCurrencyObject = this.SafeDict(transaction, "subtotal") feeObject = this.SafeDict(transaction, "fee", map[string]interface{} {}) } if IsTrue(IsEqual(amountAndCurrencyObject, nil)) { amountAndCurrencyObject = this.SafeDict(transaction, "amount") } var amountString interface{} = this.SafeString(amountAndCurrencyObject, "amount") var amountStringAbs interface{} = Precise.StringAbs(amountString) var status interface{} = this.ParseTransactionStatus(this.SafeString(transaction, "status")) if IsTrue(IsEqual(status, nil)) { var committed interface{} = this.SafeBool(transaction, "committed") status = Ternary(IsTrue(committed), "ok", "pending") } var id interface{} = this.SafeString(transaction, "id") var currencyId interface{} = this.SafeString(amountAndCurrencyObject, "currency") var feeCurrencyId interface{} = this.SafeString(feeObject, "currency") var datetime interface{} = this.SafeString(transaction, "created_at") var resource interface{} = this.SafeString(transaction, "resource") var typeVar interface{} = resource if !IsTrue(this.InArray(typeVar, []interface{}{"deposit", "withdrawal"})) { if IsTrue(Precise.StringGt(amountString, "0")) { typeVar = "deposit" } else if IsTrue(Precise.StringLt(amountString, "0")) { typeVar = "withdrawal" } } var toObject interface{} = this.SafeDict(transaction, "to") var addressTo interface{} = this.SafeString(toObject, "address") var networkId interface{} = this.SafeString(network, "network_name") return map[string]interface{} { "info": transaction, "id": id, "txid": this.SafeString(network, "hash", id), "timestamp": this.Parse8601(datetime), "datetime": datetime, "network": this.NetworkIdToCode(networkId), "address": addressTo, "addressTo": addressTo, "addressFrom": nil, "tag": nil, "tagTo": nil, "tagFrom": nil, "type": typeVar, "amount": this.ParseNumber(amountStringAbs), "currency": this.SafeCurrencyCode(currencyId, currency), "status": status, "updated": this.Parse8601(this.SafeString(transaction, "updated_at")), "fee": map[string]interface{} { "cost": this.SafeNumber(feeObject, "amount"), "currency": this.SafeCurrencyCode(feeCurrencyId), }, } } func (this *coinbase) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} { // // fetchMyBuys, fetchMySells // // { // "id": "67e0eaec-07d7-54c4-a72c-2e92826897df", // "status": "completed", // "payment_method": { // "id": "83562370-3e5c-51db-87da-752af5ab9559", // "resource": "payment_method", // "resource_path": "/v2/payment-methods/83562370-3e5c-51db-87da-752af5ab9559" // }, // "transaction": { // "id": "441b9494-b3f0-5b98-b9b0-4d82c21c252a", // "resource": "transaction", // "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/transactions/441b9494-b3f0-5b98-b9b0-4d82c21c252a" // }, // "amount": { "amount": "1.00000000", "currency": "BTC" }, // "total": { "amount": "10.25", "currency": "USD" }, // "subtotal": { "amount": "10.10", "currency": "USD" }, // "created_at": "2015-01-31T20:49:02Z", // "updated_at": "2015-02-11T16:54:02-08:00", // "resource": "buy", // "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/buys/67e0eaec-07d7-54c4-a72c-2e92826897df", // "committed": true, // "instant": false, // "fee": { "amount": "0.15", "currency": "USD" }, // "payout_at": "2015-02-18T16:54:00-08:00" // } // // fetchTrades // // { // "trade_id": "10092327", // "product_id": "BTC-USDT", // "price": "17488.12", // "size": "0.0000623", // "time": "2023-01-11T00:52:37.557001Z", // "side": "BUY", // "bid": "", // "ask": "" // } // // fetchMyTrades // // { // "entry_id": "b88b82cc89e326a2778874795102cbafd08dd979a2a7a3c69603fc4c23c2e010", // "trade_id": "cdc39e45-bbd3-44ec-bf02-61742dfb16a1", // "order_id": "813a53c5-3e39-47bb-863d-2faf685d22d8", // "trade_time": "2023-01-18T01:37:38.091377090Z", // "trade_type": "FILL", // "price": "21220.64", // "size": "0.0046830664333996", // "commission": "0.0000280983986004", // "product_id": "BTC-USDT", // "sequence_timestamp": "2023-01-18T01:37:38.092520Z", // "liquidity_indicator": "UNKNOWN_LIQUIDITY_INDICATOR", // "size_in_quote": true, // "user_id": "1111111-1111-1111-1111-111111111111", // "side": "BUY" // } // market := GetArg(optionalArgs, 0, nil) _ = market var symbol interface{} = nil var totalObject interface{} = this.SafeDict(trade, "total", map[string]interface{} {}) var amountObject interface{} = this.SafeDict(trade, "amount", map[string]interface{} {}) var subtotalObject interface{} = this.SafeDict(trade, "subtotal", map[string]interface{} {}) var feeObject interface{} = this.SafeDict(trade, "fee", map[string]interface{} {}) var marketId interface{} = this.SafeString(trade, "product_id") market = this.SafeMarket(marketId, market, "-") if IsTrue(!IsEqual(market, nil)) { symbol = GetValue(market, "symbol") } else { var baseId interface{} = this.SafeString(amountObject, "currency") var quoteId interface{} = this.SafeString(totalObject, "currency") if IsTrue(IsTrue((!IsEqual(baseId, nil))) && IsTrue((!IsEqual(quoteId, nil)))) { var base interface{} = this.SafeCurrencyCode(baseId) var quote interface{} = this.SafeCurrencyCode(quoteId) symbol = Add(Add(base, "/"), quote) } } var sizeInQuote interface{} = this.SafeBool(trade, "size_in_quote") var v3Price interface{} = this.SafeString(trade, "price") var v3Cost interface{} = nil var v3Amount interface{} = this.SafeString(trade, "size") if IsTrue(sizeInQuote) { // calculate base size v3Cost = v3Amount v3Amount = Precise.StringDiv(v3Amount, v3Price) } var v3FeeCost interface{} = this.SafeString(trade, "commission") var amountString interface{} = this.SafeString(amountObject, "amount", v3Amount) var costString interface{} = this.SafeString(subtotalObject, "amount", v3Cost) var priceString interface{} = nil var cost interface{} = nil if IsTrue(IsTrue((!IsEqual(costString, nil))) && IsTrue((!IsEqual(amountString, nil)))) { priceString = Precise.StringDiv(costString, amountString) } else { priceString = v3Price } if IsTrue(IsTrue((!IsEqual(priceString, nil))) && IsTrue((!IsEqual(amountString, nil)))) { cost = Precise.StringMul(priceString, amountString) } else { cost = costString } var feeCurrencyId interface{} = this.SafeString(feeObject, "currency") var feeCost interface{} = this.SafeNumber(feeObject, "amount", this.ParseNumber(v3FeeCost)) if IsTrue(IsTrue(IsTrue((IsEqual(feeCurrencyId, nil))) && IsTrue((!IsEqual(market, nil)))) && IsTrue((!IsEqual(feeCost, nil)))) { feeCurrencyId = GetValue(market, "quote") } var datetime interface{} = this.SafeStringN(trade, []interface{}{"created_at", "trade_time", "time"}) var side interface{} = this.SafeStringLower2(trade, "resource", "side") var takerOrMaker interface{} = this.SafeStringLower(trade, "liquidity_indicator") return this.SafeTrade(map[string]interface{} { "info": trade, "id": this.SafeString2(trade, "id", "trade_id"), "order": this.SafeString(trade, "order_id"), "timestamp": this.Parse8601(datetime), "datetime": datetime, "symbol": symbol, "type": nil, "side": Ternary(IsTrue((IsEqual(side, "unknown_order_side"))), nil, side), "takerOrMaker": Ternary(IsTrue((IsEqual(takerOrMaker, "unknown_liquidity_indicator"))), nil, takerOrMaker), "price": priceString, "amount": amountString, "cost": cost, "fee": map[string]interface{} { "cost": feeCost, "currency": this.SafeCurrencyCode(feeCurrencyId), }, }) } /** * @method * @name coinbase#fetchMarkets * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpublicproducts * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-currencies#get-fiat-currencies * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates * @description retrieves data on all markets for coinbase * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.usePrivate] use private endpoint for fetching markets * @returns {object[]} an array of objects representing market data */ func (this *coinbase) FetchMarkets(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params if IsTrue(GetValue(this.Options, "adjustForTimeDifference")) { retRes129812 := (<-this.LoadTimeDifference()) PanicOnError(retRes129812) } var method interface{} = this.SafeString(this.Options, "fetchMarkets", "fetchMarketsV3") if IsTrue(IsEqual(method, "fetchMarketsV3")) { retRes130219 := (<-this.FetchMarketsV3(params)) PanicOnError(retRes130219) ch <- retRes130219 return nil } retRes130415 := (<-this.FetchMarketsV2(params)) PanicOnError(retRes130415) ch <- retRes130415 return nil }() return ch } func (this *coinbase) FetchMarketsV2(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params response:= (<-this.FetchCurrenciesFromCache(params)) PanicOnError(response) var currencies interface{} = this.SafeDict(response, "currencies", map[string]interface{} {}) var exchangeRates interface{} = this.SafeDict(response, "exchangeRates", map[string]interface{} {}) var data interface{} = this.SafeList(currencies, "data", []interface{}{}) var dataById interface{} = this.IndexBy(data, "id") var rates interface{} = this.SafeDict(this.SafeDict(exchangeRates, "data", map[string]interface{} {}), "rates", map[string]interface{} {}) var baseIds interface{} = ObjectKeys(rates) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(baseIds)); i++ { var baseId interface{} = GetValue(baseIds, i) var base interface{} = this.SafeCurrencyCode(baseId) var typeVar interface{} = Ternary(IsTrue((InOp(dataById, baseId))), "fiat", "crypto") // https://github.com/ccxt/ccxt/issues/6066 if IsTrue(IsEqual(typeVar, "crypto")) { for j := 0; IsLessThan(j, GetArrayLength(data)); j++ { var quoteCurrency interface{} = GetValue(data, j) var quoteId interface{} = this.SafeString(quoteCurrency, "id") var quote interface{} = this.SafeCurrencyCode(quoteId) AppendToArray(&result,this.SafeMarketStructure(map[string]interface{} { "id": Add(Add(baseId, "-"), quoteId), "symbol": Add(Add(base, "/"), quote), "base": base, "quote": quote, "settle": nil, "baseId": baseId, "quoteId": quoteId, "settleId": nil, "type": "spot", "spot": true, "margin": false, "swap": false, "future": false, "option": false, "active": nil, "contract": false, "linear": nil, "inverse": nil, "contractSize": nil, "expiry": nil, "expiryDatetime": nil, "strike": nil, "optionType": nil, "precision": map[string]interface{} { "amount": nil, "price": nil, }, "limits": map[string]interface{} { "leverage": map[string]interface{} { "min": nil, "max": nil, }, "amount": map[string]interface{} { "min": nil, "max": nil, }, "price": map[string]interface{} { "min": nil, "max": nil, }, "cost": map[string]interface{} { "min": this.SafeNumber(quoteCurrency, "min_size"), "max": nil, }, }, "info": quoteCurrency, })) } } } ch <- result return nil }() return ch } func (this *coinbase) FetchMarketsV3(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params var usePrivate interface{} = false usePrivateparamsVariable := this.HandleOptionAndParams(params, "fetchMarkets", "usePrivate", false); usePrivate = GetValue(usePrivateparamsVariable,0); params = GetValue(usePrivateparamsVariable,1) var spotUnresolvedPromises interface{} = []interface{}{} if IsTrue(usePrivate) { AppendToArray(&spotUnresolvedPromises,this.V3PrivateGetBrokerageProducts(params)) } else { AppendToArray(&spotUnresolvedPromises,this.V3PublicGetBrokerageMarketProducts(params)) } // // { // products: [ // { // product_id: 'BTC-USD', // price: '67060', // price_percentage_change_24h: '3.30054960636883', // volume_24h: '10967.87426597', // volume_percentage_change_24h: '141.73048325503036', // base_increment: '0.00000001', // quote_increment: '0.01', // quote_min_size: '1', // quote_max_size: '150000000', // base_min_size: '0.00000001', // base_max_size: '3400', // base_name: 'Bitcoin', // quote_name: 'US Dollar', // watched: false, // is_disabled: false, // new: false, // status: 'online', // cancel_only: false, // limit_only: false, // post_only: false, // trading_disabled: false, // auction_mode: false, // product_type: 'SPOT', // quote_currency_id: 'USD', // base_currency_id: 'BTC', // fcm_trading_session_details: null, // mid_market_price: '', // alias: '', // alias_to: [ 'BTC-USDC' ], // base_display_symbol: 'BTC', // quote_display_symbol: 'USD', // view_only: false, // price_increment: '0.01', // display_name: 'BTC-USD', // product_venue: 'CBE' // }, // ... // ], // num_products: '646' // } // if IsTrue(this.CheckRequiredCredentials(false)) { AppendToArray(&spotUnresolvedPromises,this.V3PrivateGetBrokerageTransactionSummary(params)) } // // { // total_volume: '9.995989116664404', // total_fees: '0.07996791093331522', // fee_tier: { // pricing_tier: 'Advanced 1', // usd_from: '0', // usd_to: '1000', // taker_fee_rate: '0.008', // maker_fee_rate: '0.006', // aop_from: '', // aop_to: '' // }, // margin_rate: null, // goods_and_services_tax: null, // advanced_trade_only_volume: '9.995989116664404', // advanced_trade_only_fees: '0.07996791093331522', // coinbase_pro_volume: '0', // coinbase_pro_fees: '0', // total_balance: '', // has_promo_fee: false // } // var unresolvedContractPromises interface{} = []interface{}{} { ret__ := func(this *coinbase) (ret_ interface{}) { defer func() { if e := recover(); e != nil { if e == "break" { return } ret_ = func(this *coinbase) interface{} { // catch block: unresolvedContractPromises = []interface{}{} // the sync version of ccxt won't have the promise.all line so the request is made here. Some users can't access perpetual products return nil }(this) } }() // try block: unresolvedContractPromises = []interface{}{this.V3PublicGetBrokerageMarketProducts(this.Extend(params, map[string]interface{} { "product_type": "FUTURE", })), this.V3PublicGetBrokerageMarketProducts(this.Extend(params, map[string]interface{} { "product_type": "FUTURE", "contract_expiry_type": "PERPETUAL", }))} if IsTrue(this.CheckRequiredCredentials(false)) { AppendToArray(&unresolvedContractPromises,this.Extend(params, map[string]interface{} { "product_type": "FUTURE", })) AppendToArray(&unresolvedContractPromises,this.Extend(params, map[string]interface{} { "product_type": "FUTURE", "contract_expiry_type": "PERPETUAL", })) } return nil }(this) if ret__ != nil { return ret__ } } promises:= (<-promiseAll(spotUnresolvedPromises)) PanicOnError(promises) var contractPromises interface{} = nil { ret__ := func(this *coinbase) (ret_ interface{}) { defer func() { if e := recover(); e != nil { if e == "break" { return } ret_ = func(this *coinbase) interface{} { // catch block: contractPromises = []interface{}{} return nil }(this) } }() // try block: contractPromises = (<-promiseAll(unresolvedContractPromises)) PanicOnError(contractPromises) // some users don't have access to contracts return nil }(this) if ret__ != nil { return ret__ } } var spot interface{} = this.SafeDict(promises, 0, map[string]interface{} {}) var fees interface{} = this.SafeDict(promises, 1, map[string]interface{} {}) var expiringFutures interface{} = this.SafeDict(contractPromises, 0, map[string]interface{} {}) var perpetualFutures interface{} = this.SafeDict(contractPromises, 1, map[string]interface{} {}) var expiringFees interface{} = this.SafeDict(contractPromises, 2, map[string]interface{} {}) var perpetualFees interface{} = this.SafeDict(contractPromises, 3, map[string]interface{} {}) // // { // "total_volume": 0, // "total_fees": 0, // "fee_tier": { // "pricing_tier": "", // "usd_from": "0", // "usd_to": "10000", // "taker_fee_rate": "0.006", // "maker_fee_rate": "0.004" // }, // "margin_rate": null, // "goods_and_services_tax": null, // "advanced_trade_only_volume": 0, // "advanced_trade_only_fees": 0, // "coinbase_pro_volume": 0, // "coinbase_pro_fees": 0 // } // var feeTier interface{} = this.SafeDict(fees, "fee_tier", map[string]interface{} {}) var expiringFeeTier interface{} = this.SafeDict(expiringFees, "fee_tier", map[string]interface{} {}) // fee tier null? var perpetualFeeTier interface{} = this.SafeDict(perpetualFees, "fee_tier", map[string]interface{} {}) // fee tier null? var data interface{} = this.SafeList(spot, "products", []interface{}{}) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { AppendToArray(&result,this.ParseSpotMarket(GetValue(data, i), feeTier)) } var futureData interface{} = this.SafeList(expiringFutures, "products", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(futureData)); i++ { AppendToArray(&result,this.ParseContractMarket(GetValue(futureData, i), expiringFeeTier)) } var perpetualData interface{} = this.SafeList(perpetualFutures, "products", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(perpetualData)); i++ { AppendToArray(&result,this.ParseContractMarket(GetValue(perpetualData, i), perpetualFeeTier)) } ch <- result return nil }() return ch } func (this *coinbase) ParseSpotMarket(market interface{}, feeTier interface{}) interface{} { // // { // "product_id": "TONE-USD", // "price": "0.01523", // "price_percentage_change_24h": "1.94109772423025", // "volume_24h": "19773129", // "volume_percentage_change_24h": "437.0170530929949", // "base_increment": "1", // "quote_increment": "0.00001", // "quote_min_size": "1", // "quote_max_size": "10000000", // "base_min_size": "26.7187147229469674", // "base_max_size": "267187147.2294696735908216", // "base_name": "TE-FOOD", // "quote_name": "US Dollar", // "watched": false, // "is_disabled": false, // "new": false, // "status": "online", // "cancel_only": false, // "limit_only": false, // "post_only": false, // "trading_disabled": false, // "auction_mode": false, // "product_type": "SPOT", // "quote_currency_id": "USD", // "base_currency_id": "TONE", // "fcm_trading_session_details": null, // "mid_market_price": "" // } // var id interface{} = this.SafeString(market, "product_id") var baseId interface{} = this.SafeString(market, "base_currency_id") var quoteId interface{} = this.SafeString(market, "quote_currency_id") var base interface{} = this.SafeCurrencyCode(baseId) var quote interface{} = this.SafeCurrencyCode(quoteId) var marketType interface{} = this.SafeStringLower(market, "product_type") var tradingDisabled interface{} = this.SafeBool(market, "trading_disabled") var stablePairs interface{} = this.SafeList(this.Options, "stablePairs", []interface{}{}) var defaultTakerFee interface{} = this.SafeNumber(GetValue(this.Fees, "trading"), "taker") var defaultMakerFee interface{} = this.SafeNumber(GetValue(this.Fees, "trading"), "maker") var takerFee interface{} = Ternary(IsTrue(this.InArray(id, stablePairs)), 0.00001, this.SafeNumber(feeTier, "taker_fee_rate", defaultTakerFee)) var makerFee interface{} = Ternary(IsTrue(this.InArray(id, stablePairs)), 0, this.SafeNumber(feeTier, "maker_fee_rate", defaultMakerFee)) return this.SafeMarketStructure(map[string]interface{} { "id": id, "symbol": Add(Add(base, "/"), quote), "base": base, "quote": quote, "settle": nil, "baseId": baseId, "quoteId": quoteId, "settleId": nil, "type": marketType, "spot": (IsEqual(marketType, "spot")), "margin": nil, "swap": false, "future": false, "option": false, "active": !IsTrue(tradingDisabled), "contract": false, "linear": nil, "inverse": nil, "taker": takerFee, "maker": makerFee, "contractSize": nil, "expiry": nil, "expiryDatetime": nil, "strike": nil, "optionType": nil, "precision": map[string]interface{} { "amount": this.SafeNumber(market, "base_increment"), "price": this.SafeNumber2(market, "price_increment", "quote_increment"), }, "limits": map[string]interface{} { "leverage": map[string]interface{} { "min": nil, "max": nil, }, "amount": map[string]interface{} { "min": this.SafeNumber(market, "base_min_size"), "max": this.SafeNumber(market, "base_max_size"), }, "price": map[string]interface{} { "min": nil, "max": nil, }, "cost": map[string]interface{} { "min": this.SafeNumber(market, "quote_min_size"), "max": this.SafeNumber(market, "quote_max_size"), }, }, "created": nil, "info": market, }) } func (this *coinbase) ParseContractMarket(market interface{}, feeTier interface{}) interface{} { // expiring // // { // "product_id":"BIT-26APR24-CDE", // "price":"71145", // "price_percentage_change_24h":"-2.36722931247427", // "volume_24h":"108549", // "volume_percentage_change_24h":"155.78255337197794", // "base_increment":"1", // "quote_increment":"0.01", // "quote_min_size":"0", // "quote_max_size":"100000000", // "base_min_size":"1", // "base_max_size":"100000000", // "base_name":"", // "quote_name":"US Dollar", // "watched":false, // "is_disabled":false, // "new":false, // "status":"", // "cancel_only":false, // "limit_only":false, // "post_only":false, // "trading_disabled":false, // "auction_mode":false, // "product_type":"FUTURE", // "quote_currency_id":"USD", // "base_currency_id":"", // "fcm_trading_session_details":{ // "is_session_open":true, // "open_time":"2024-04-08T22:00:00Z", // "close_time":"2024-04-09T21:00:00Z" // }, // "mid_market_price":"71105", // "alias":"", // "alias_to":[ // ], // "base_display_symbol":"", // "quote_display_symbol":"USD", // "view_only":false, // "price_increment":"5", // "display_name":"BTC 26 APR 24", // "product_venue":"FCM", // "future_product_details":{ // "venue":"cde", // "contract_code":"BIT", // "contract_expiry":"2024-04-26T15:00:00Z", // "contract_size":"0.01", // "contract_root_unit":"BTC", // "group_description":"Nano Bitcoin Futures", // "contract_expiry_timezone":"Europe/London", // "group_short_description":"Nano BTC", // "risk_managed_by":"MANAGED_BY_FCM", // "contract_expiry_type":"EXPIRING", // "contract_display_name":"BTC 26 APR 24" // } // } // // perpetual // // { // "product_id":"ETH-PERP-INTX", // "price":"3630.98", // "price_percentage_change_24h":"0.65142426292038", // "volume_24h":"114020.1501", // "volume_percentage_change_24h":"63.33650787154869", // "base_increment":"0.0001", // "quote_increment":"0.01", // "quote_min_size":"10", // "quote_max_size":"50000000", // "base_min_size":"0.0001", // "base_max_size":"50000", // "base_name":"", // "quote_name":"USDC", // "watched":false, // "is_disabled":false, // "new":false, // "status":"", // "cancel_only":false, // "limit_only":false, // "post_only":false, // "trading_disabled":false, // "auction_mode":false, // "product_type":"FUTURE", // "quote_currency_id":"USDC", // "base_currency_id":"", // "fcm_trading_session_details":null, // "mid_market_price":"3630.975", // "alias":"", // "alias_to":[], // "base_display_symbol":"", // "quote_display_symbol":"USDC", // "view_only":false, // "price_increment":"0.01", // "display_name":"ETH PERP", // "product_venue":"INTX", // "future_product_details":{ // "venue":"", // "contract_code":"ETH", // "contract_expiry":null, // "contract_size":"1", // "contract_root_unit":"ETH", // "group_description":"", // "contract_expiry_timezone":"", // "group_short_description":"", // "risk_managed_by":"MANAGED_BY_VENUE", // "contract_expiry_type":"PERPETUAL", // "perpetual_details":{ // "open_interest":"0", // "funding_rate":"0.000016", // "funding_time":"2024-04-09T09:00:00.000008Z", // "max_leverage":"10" // }, // "contract_display_name":"ETH PERPETUAL" // } // } // var id interface{} = this.SafeString(market, "product_id") var futureProductDetails interface{} = this.SafeDict(market, "future_product_details", map[string]interface{} {}) var contractExpiryType interface{} = this.SafeString(futureProductDetails, "contract_expiry_type") var contractSize interface{} = this.SafeNumber(futureProductDetails, "contract_size") var contractExpire interface{} = this.SafeString(futureProductDetails, "contract_expiry") var expireTimestamp interface{} = this.Parse8601(contractExpire) var expireDateTime interface{} = this.Iso8601(expireTimestamp) var isSwap interface{} = (IsEqual(contractExpiryType, "PERPETUAL")) var baseId interface{} = this.SafeString(futureProductDetails, "contract_root_unit") var quoteId interface{} = this.SafeString(market, "quote_currency_id") var base interface{} = this.SafeCurrencyCode(baseId) var quote interface{} = this.SafeCurrencyCode(quoteId) var tradingDisabled interface{} = this.SafeBool(market, "is_disabled") var symbol interface{} = Add(Add(base, "/"), quote) var typeVar interface{} = nil if IsTrue(isSwap) { typeVar = "swap" symbol = Add(Add(symbol, ":"), quote) } else { typeVar = "future" symbol = Add(Add(Add(Add(symbol, ":"), quote), "-"), this.Yymmdd(expireTimestamp)) } var takerFeeRate interface{} = this.SafeNumber(feeTier, "taker_fee_rate") var makerFeeRate interface{} = this.SafeNumber(feeTier, "maker_fee_rate") var taker interface{} = Ternary(IsTrue(takerFeeRate), takerFeeRate, this.ParseNumber("0.06")) var maker interface{} = Ternary(IsTrue(makerFeeRate), makerFeeRate, this.ParseNumber("0.04")) return this.SafeMarketStructure(map[string]interface{} { "id": id, "symbol": symbol, "base": base, "quote": quote, "settle": quote, "baseId": baseId, "quoteId": quoteId, "settleId": quoteId, "type": typeVar, "spot": false, "margin": false, "swap": isSwap, "future": !IsTrue(isSwap), "option": false, "active": !IsTrue(tradingDisabled), "contract": true, "linear": true, "inverse": false, "taker": taker, "maker": maker, "contractSize": contractSize, "expiry": expireTimestamp, "expiryDatetime": expireDateTime, "strike": nil, "optionType": nil, "precision": map[string]interface{} { "amount": this.SafeNumber(market, "base_increment"), "price": this.SafeNumber2(market, "price_increment", "quote_increment"), }, "limits": map[string]interface{} { "leverage": map[string]interface{} { "min": nil, "max": nil, }, "amount": map[string]interface{} { "min": this.SafeNumber(market, "base_min_size"), "max": this.SafeNumber(market, "base_max_size"), }, "price": map[string]interface{} { "min": nil, "max": nil, }, "cost": map[string]interface{} { "min": this.SafeNumber(market, "quote_min_size"), "max": this.SafeNumber(market, "quote_max_size"), }, }, "created": nil, "info": market, }) } func (this *coinbase) FetchCurrenciesFromCache(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params var options interface{} = this.SafeDict(this.Options, "fetchCurrencies", map[string]interface{} {}) var timestamp interface{} = this.SafeInteger(options, "timestamp") var expires interface{} = this.SafeInteger(options, "expires", 1000) var now interface{} = this.Milliseconds() if IsTrue(IsTrue((IsEqual(timestamp, nil))) || IsTrue((IsGreaterThan((Subtract(now, timestamp)), expires)))) { var promises interface{} = []interface{}{this.V2PublicGetCurrencies(params), this.V2PublicGetCurrenciesCrypto(params)} promisesResult:= (<-promiseAll(promises)) PanicOnError(promisesResult) var fiatResponse interface{} = this.SafeDict(promisesResult, 0, map[string]interface{} {}) // // [ // "data": { // id: 'IMP', // name: 'Isle of Man Pound', // min_size: '0.01' // }, // ... // ] // var cryptoResponse interface{} = this.SafeDict(promisesResult, 1, map[string]interface{} {}) // // { // asset_id: '9476e3be-b731-47fa-82be-347fabc573d9', // code: 'AERO', // name: 'Aerodrome Finance', // color: '#0433FF', // sort_index: '340', // exponent: '8', // type: 'crypto', // address_regex: '^(?:0x)?[0-9a-fA-F]{40}$' // } // var fiatData interface{} = this.SafeList(fiatResponse, "data", []interface{}{}) var cryptoData interface{} = this.SafeList(cryptoResponse, "data", []interface{}{}) exchangeRates:= (<-this.V2PublicGetExchangeRates(params)) PanicOnError(exchangeRates) AddElementToObject(this.Options, "fetchCurrencies", this.Extend(options, map[string]interface{} { "currencies": this.ArrayConcat(fiatData, cryptoData), "exchangeRates": exchangeRates, "timestamp": now, })) } ch <- this.SafeDict(this.Options, "fetchCurrencies", map[string]interface{} {}) return nil }() return ch } /** * @method * @name coinbase#fetchCurrencies * @description fetches all available currencies on an exchange * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-currencies#get-fiat-currencies * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an associative dictionary of currencies */ func (this *coinbase) FetchCurrencies(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params response:= (<-this.FetchCurrenciesFromCache(params)) PanicOnError(response) var currencies interface{} = this.SafeList(response, "currencies", []interface{}{}) // // fiat // // { // id: 'IMP', // name: 'Isle of Man Pound', // min_size: '0.01' // }, // // crypto // // { // asset_id: '9476e3be-b731-47fa-82be-347fabc573d9', // code: 'AERO', // name: 'Aerodrome Finance', // color: '#0433FF', // sort_index: '340', // exponent: '8', // type: 'crypto', // address_regex: '^(?:0x)?[0-9a-fA-F]{40}$' // } // // // { // "data":{ // "currency":"USD", // "rates":{ // "AED":"3.67", // "AFN":"78.21", // "ALL":"110.42", // "AMD":"474.18", // "ANG":"1.75", // ... // }, // } // } // var result interface{} = map[string]interface{} {} var networks interface{} = map[string]interface{} {} var networksById interface{} = map[string]interface{} {} for i := 0; IsLessThan(i, GetArrayLength(currencies)); i++ { var currency interface{} = GetValue(currencies, i) var assetId interface{} = this.SafeString(currency, "asset_id") var id interface{} = this.SafeString2(currency, "id", "code") var code interface{} = this.SafeCurrencyCode(id) var name interface{} = this.SafeString(currency, "name") AddElementToObject(GetValue(this.Options, "networks"), code, ToLower(name)) AddElementToObject(GetValue(this.Options, "networksById"), code, ToLower(name)) AddElementToObject(result, code, map[string]interface{} { "info": currency, "id": id, "code": code, "type": Ternary(IsTrue((!IsEqual(assetId, nil))), "crypto", "fiat"), "name": this.SafeString(currency, "name"), "active": true, "deposit": nil, "withdraw": nil, "fee": nil, "precision": nil, "limits": map[string]interface{} { "amount": map[string]interface{} { "min": this.SafeNumber(currency, "min_size"), "max": nil, }, "withdraw": map[string]interface{} { "min": nil, "max": nil, }, }, }) if IsTrue(!IsEqual(assetId, nil)) { var lowerCaseName interface{} = ToLower(name) AddElementToObject(networks, code, lowerCaseName) AddElementToObject(networksById, lowerCaseName, code) } } AddElementToObject(this.Options, "networks", this.Extend(networks, GetValue(this.Options, "networks"))) AddElementToObject(this.Options, "networksById", this.Extend(networksById, GetValue(this.Options, "networksById"))) ch <- result return nil }() return ch } /** * @method * @name coinbase#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getproducts * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.usePrivate] use private endpoint for fetching tickers * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ func (this *coinbase) FetchTickers(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbols := GetArg(optionalArgs, 0, nil) _ = symbols params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params var method interface{} = this.SafeString(this.Options, "fetchTickers", "fetchTickersV3") if IsTrue(IsEqual(method, "fetchTickersV3")) { retRes197219 := (<-this.FetchTickersV3(symbols, params)) PanicOnError(retRes197219) ch <- retRes197219 return nil } retRes197415 := (<-this.FetchTickersV2(symbols, params)) PanicOnError(retRes197415) ch <- retRes197415 return nil }() return ch } func (this *coinbase) FetchTickersV2(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbols := GetArg(optionalArgs, 0, nil) _ = symbols params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes19788 := (<-this.LoadMarkets()) PanicOnError(retRes19788) symbols = this.MarketSymbols(symbols) var request interface{} = map[string]interface{} {} response:= (<-this.V2PublicGetExchangeRates(this.Extend(request, params))) PanicOnError(response) // // { // "data":{ // "currency":"USD", // "rates":{ // "AED":"3.6731", // "AFN":"103.163942", // "ALL":"106.973038", // } // } // } // var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) var rates interface{} = this.SafeDict(data, "rates", map[string]interface{} {}) var quoteId interface{} = this.SafeString(data, "currency") var result interface{} = map[string]interface{} {} var baseIds interface{} = ObjectKeys(rates) var delimiter interface{} = "-" for i := 0; IsLessThan(i, GetArrayLength(baseIds)); i++ { var baseId interface{} = GetValue(baseIds, i) var marketId interface{} = Add(Add(baseId, delimiter), quoteId) var market interface{} = this.SafeMarket(marketId, nil, delimiter) var symbol interface{} = GetValue(market, "symbol") AddElementToObject(result, symbol, this.ParseTicker(GetValue(rates, baseId), market)) } ch <- this.FilterByArrayTickers(result, "symbol", symbols) return nil }() return ch } func (this *coinbase) FetchTickersV3(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbols := GetArg(optionalArgs, 0, nil) _ = symbols params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes20138 := (<-this.LoadMarkets()) PanicOnError(retRes20138) symbols = this.MarketSymbols(symbols) var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(symbols, nil)) { AddElementToObject(request, "product_ids", this.MarketIds(symbols)) } var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchTickers", this.GetMarketFromSymbols(symbols), params, "default"); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) if IsTrue(IsTrue(!IsEqual(marketType, nil)) && IsTrue(!IsEqual(marketType, "default"))) { AddElementToObject(request, "product_type", Ternary(IsTrue((IsEqual(marketType, "swap"))), "FUTURE", "SPOT")) } var response interface{} = nil var usePrivate interface{} = false usePrivateparamsVariable := this.HandleOptionAndParams(params, "fetchTickers", "usePrivate", false); usePrivate = GetValue(usePrivateparamsVariable,0); params = GetValue(usePrivateparamsVariable,1) if IsTrue(usePrivate) { response = (<-this.V3PrivateGetBrokerageProducts(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.V3PublicGetBrokerageMarketProducts(this.Extend(request, params))) PanicOnError(response) } // // { // "products": [ // { // "product_id": "TONE-USD", // "price": "0.01523", // "price_percentage_change_24h": "1.94109772423025", // "volume_24h": "19773129", // "volume_percentage_change_24h": "437.0170530929949", // "base_increment": "1", // "quote_increment": "0.00001", // "quote_min_size": "1", // "quote_max_size": "10000000", // "base_min_size": "26.7187147229469674", // "base_max_size": "267187147.2294696735908216", // "base_name": "TE-FOOD", // "quote_name": "US Dollar", // "watched": false, // "is_disabled": false, // "new": false, // "status": "online", // "cancel_only": false, // "limit_only": false, // "post_only": false, // "trading_disabled": false, // "auction_mode": false, // "product_type": "SPOT", // "quote_currency_id": "USD", // "base_currency_id": "TONE", // "fcm_trading_session_details": null, // "mid_market_price": "" // }, // ... // ], // "num_products": 549 // } // var data interface{} = this.SafeList(response, "products", []interface{}{}) var result interface{} = map[string]interface{} {} for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var entry interface{} = GetValue(data, i) var marketId interface{} = this.SafeString(entry, "product_id") var market interface{} = this.SafeMarket(marketId, nil, "-") var symbol interface{} = GetValue(market, "symbol") AddElementToObject(result, symbol, this.ParseTicker(entry, market)) } ch <- this.FilterByArrayTickers(result, "symbol", symbols) return nil }() return ch } /** * @method * @name coinbase#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getmarkettrades * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-spot-price * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-buy-price * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-sell-price * @param {string} symbol unified symbol of the market to fetch the ticker for * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.usePrivate] whether to use the private endpoint for fetching the ticker * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ func (this *coinbase) FetchTicker(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params var method interface{} = this.SafeString(this.Options, "fetchTicker", "fetchTickerV3") if IsTrue(IsEqual(method, "fetchTickerV3")) { retRes209719 := (<-this.FetchTickerV3(symbol, params)) PanicOnError(retRes209719) ch <- retRes209719 return nil } retRes209915 := (<-this.FetchTickerV2(symbol, params)) PanicOnError(retRes209915) ch <- retRes209915 return nil }() return ch } func (this *coinbase) FetchTickerV2(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes21038 := (<-this.LoadMarkets()) PanicOnError(retRes21038) var market interface{} = this.Market(symbol) var request interface{} = this.Extend(map[string]interface{} { "symbol": GetValue(market, "id"), }, params) spot:= (<-this.V2PublicGetPricesSymbolSpot(request)) PanicOnError(spot) // // {"data":{"base":"BTC","currency":"USD","amount":"48691.23"}} // ask:= (<-this.V2PublicGetPricesSymbolBuy(request)) PanicOnError(ask) // // {"data":{"base":"BTC","currency":"USD","amount":"48691.23"}} // bid:= (<-this.V2PublicGetPricesSymbolSell(request)) PanicOnError(bid) // // {"data":{"base":"BTC","currency":"USD","amount":"48691.23"}} // var spotData interface{} = this.SafeDict(spot, "data", map[string]interface{} {}) var askData interface{} = this.SafeDict(ask, "data", map[string]interface{} {}) var bidData interface{} = this.SafeDict(bid, "data", map[string]interface{} {}) var bidAskLast interface{} = map[string]interface{} { "bid": this.SafeNumber(bidData, "amount"), "ask": this.SafeNumber(askData, "amount"), "price": this.SafeNumber(spotData, "amount"), } ch <- this.ParseTicker(bidAskLast, market) return nil }() return ch } func (this *coinbase) FetchTickerV3(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes21328 := (<-this.LoadMarkets()) PanicOnError(retRes21328) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "product_id": GetValue(market, "id"), "limit": 1, } var usePrivate interface{} = false usePrivateparamsVariable := this.HandleOptionAndParams(params, "fetchTicker", "usePrivate", false); usePrivate = GetValue(usePrivateparamsVariable,0); params = GetValue(usePrivateparamsVariable,1) var response interface{} = nil if IsTrue(usePrivate) { response = (<-this.V3PrivateGetBrokerageProductsProductIdTicker(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.V3PublicGetBrokerageMarketProductsProductIdTicker(this.Extend(request, params))) PanicOnError(response) } // // { // "trades": [ // { // "trade_id": "518078013", // "product_id": "BTC-USD", // "price": "28208.1", // "size": "0.00659179", // "time": "2023-04-04T23:05:34.492746Z", // "side": "BUY", // "bid": "", // "ask": "" // } // ], // "best_bid": "28208.61", // "best_ask": "28208.62" // } // var data interface{} = this.SafeList(response, "trades", []interface{}{}) var ticker interface{} = this.ParseTicker(GetValue(data, 0), market) AddElementToObject(ticker, "bid", this.SafeNumber(response, "best_bid")) AddElementToObject(ticker, "ask", this.SafeNumber(response, "best_ask")) ch <- ticker return nil }() return ch } func (this *coinbase) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} { // // fetchTickerV2 // // { // "bid": 20713.37, // "ask": 20924.65, // "price": 20809.83 // } // // fetchTickerV3 // // { // "trade_id": "10209805", // "product_id": "BTC-USDT", // "price": "19381.27", // "size": "0.1", // "time": "2023-01-13T20:35:41.865970Z", // "side": "BUY", // "bid": "", // "ask": "" // } // // fetchTickersV2 // // "48691.23" // // fetchTickersV3 // // [ // { // "product_id": "TONE-USD", // "price": "0.01523", // "price_percentage_change_24h": "1.94109772423025", // "volume_24h": "19773129", // "volume_percentage_change_24h": "437.0170530929949", // "base_increment": "1", // "quote_increment": "0.00001", // "quote_min_size": "1", // "quote_max_size": "10000000", // "base_min_size": "26.7187147229469674", // "base_max_size": "267187147.2294696735908216", // "base_name": "TE-FOOD", // "quote_name": "US Dollar", // "watched": false, // "is_disabled": false, // "new": false, // "status": "online", // "cancel_only": false, // "limit_only": false, // "post_only": false, // "trading_disabled": false, // "auction_mode": false, // "product_type": "SPOT", // "quote_currency_id": "USD", // "base_currency_id": "TONE", // "fcm_trading_session_details": null, // "mid_market_price": "" // }, // ... // ] // // fetchBidsAsks // // { // "product_id": "TRAC-EUR", // "bids": [ // { // "price": "0.2384", // "size": "386.1" // } // ], // "asks": [ // { // "price": "0.2406", // "size": "672" // } // ], // "time": "2023-06-30T07:15:24.656044Z" // } // market := GetArg(optionalArgs, 0, nil) _ = market var bid interface{} = this.SafeNumber(ticker, "bid") var ask interface{} = this.SafeNumber(ticker, "ask") var bidVolume interface{} = nil var askVolume interface{} = nil if IsTrue((InOp(ticker, "bids"))) { var bids interface{} = this.SafeList(ticker, "bids", []interface{}{}) var asks interface{} = this.SafeList(ticker, "asks", []interface{}{}) bid = this.SafeNumber(GetValue(bids, 0), "price") bidVolume = this.SafeNumber(GetValue(bids, 0), "size") ask = this.SafeNumber(GetValue(asks, 0), "price") askVolume = this.SafeNumber(GetValue(asks, 0), "size") } var marketId interface{} = this.SafeString(ticker, "product_id") var last interface{} = this.SafeNumber(ticker, "price") var datetime interface{} = this.SafeString(ticker, "time") return this.SafeTicker(map[string]interface{} { "symbol": this.SafeSymbol(marketId, market), "timestamp": this.Parse8601(datetime), "datetime": datetime, "bid": bid, "ask": ask, "last": last, "high": nil, "low": nil, "bidVolume": bidVolume, "askVolume": askVolume, "vwap": nil, "open": nil, "close": last, "previousClose": nil, "change": nil, "percentage": this.SafeNumber(ticker, "price_percentage_change_24h"), "average": nil, "baseVolume": nil, "quoteVolume": nil, "info": ticker, }, market) } func (this *coinbase) ParseCustomBalance(response interface{}, optionalArgs ...interface{}) interface{} { params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params var balances interface{} = this.SafeList2(response, "data", "accounts", []interface{}{}) var accounts interface{} = this.SafeList(params, "type", GetValue(this.Options, "accounts")) var v3Accounts interface{} = this.SafeList(params, "type", GetValue(this.Options, "v3Accounts")) var result interface{} = map[string]interface{} { "info": response, } for b := 0; IsLessThan(b, GetArrayLength(balances)); b++ { var balance interface{} = GetValue(balances, b) var typeVar interface{} = this.SafeString(balance, "type") if IsTrue(this.InArray(typeVar, accounts)) { var value interface{} = this.SafeDict(balance, "balance") if IsTrue(!IsEqual(value, nil)) { var currencyId interface{} = this.SafeString(value, "currency") var code interface{} = this.SafeCurrencyCode(currencyId) var total interface{} = this.SafeString(value, "amount") var free interface{} = total var account interface{} = this.SafeDict(result, code) if IsTrue(IsEqual(account, nil)) { account = this.Account() AddElementToObject(account, "free", free) AddElementToObject(account, "total", total) } else { AddElementToObject(account, "free", Precise.StringAdd(GetValue(account, "free"), total)) AddElementToObject(account, "total", Precise.StringAdd(GetValue(account, "total"), total)) } AddElementToObject(result, code, account) } } else if IsTrue(this.InArray(typeVar, v3Accounts)) { var available interface{} = this.SafeDict(balance, "available_balance") var hold interface{} = this.SafeDict(balance, "hold") if IsTrue(IsTrue(!IsEqual(available, nil)) && IsTrue(!IsEqual(hold, nil))) { var currencyId interface{} = this.SafeString(available, "currency") var code interface{} = this.SafeCurrencyCode(currencyId) var used interface{} = this.SafeString(hold, "value") var free interface{} = this.SafeString(available, "value") var total interface{} = Precise.StringAdd(used, free) var account interface{} = this.SafeDict(result, code) if IsTrue(IsEqual(account, nil)) { account = this.Account() AddElementToObject(account, "free", free) AddElementToObject(account, "used", used) AddElementToObject(account, "total", total) } else { AddElementToObject(account, "free", Precise.StringAdd(GetValue(account, "free"), free)) AddElementToObject(account, "used", Precise.StringAdd(GetValue(account, "used"), used)) AddElementToObject(account, "total", Precise.StringAdd(GetValue(account, "total"), total)) } AddElementToObject(result, code, account) } } } return this.SafeBalance(result) } /** * @method * @name coinbase#fetchBalance * @description query for balance and get the amount of funds available for trading or funds locked in orders * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getaccounts * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-accounts#list-accounts * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfcmbalancesummary * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.v3] default false, set true to use v3 api endpoint * @param {string} [params.type] "spot" (default) or "swap" or "future" * @param {int} [params.limit] default 250, maximum number of accounts to return * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure} */ func (this *coinbase) FetchBalance(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes23588 := (<-this.LoadMarkets()) PanicOnError(retRes23588) var request interface{} = map[string]interface{} {} var response interface{} = nil var isV3 interface{} = this.SafeBool(params, "v3", false) params = this.Omit(params, []interface{}{"v3"}) var marketType interface{} = nil marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchBalance", nil, params); marketType = GetValue(marketTypeparamsVariable,0); params = GetValue(marketTypeparamsVariable,1) var method interface{} = this.SafeString(this.Options, "fetchBalance", "v3PrivateGetBrokerageAccounts") if IsTrue(IsEqual(marketType, "future")) { response = (<-this.V3PrivateGetBrokerageCfmBalanceSummary(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsTrue((isV3)) || IsTrue((IsEqual(method, "v3PrivateGetBrokerageAccounts")))) { AddElementToObject(request, "limit", 250) response = (<-this.V3PrivateGetBrokerageAccounts(this.Extend(request, params))) PanicOnError(response) } else { AddElementToObject(request, "limit", 250) response = (<-this.V2PrivateGetAccounts(this.Extend(request, params))) PanicOnError(response) } // // v2PrivateGetAccounts // { // "pagination":{ // "ending_before":null, // "starting_after":null, // "previous_ending_before":null, // "next_starting_after":"6b17acd6-2e68-5eb0-9f45-72d67cef578b", // "limit":100, // "order":"desc", // "previous_uri":null, // "next_uri":"/v2/accounts?limit=100\u0026starting_after=6b17acd6-2e68-5eb0-9f45-72d67cef578b" // }, // "data":[ // { // "id":"94ad58bc-0f15-5309-b35a-a4c86d7bad60", // "name":"MINA Wallet", // "primary":false, // "type":"wallet", // "currency":{ // "code":"MINA", // "name":"Mina", // "color":"#EA6B48", // "sort_index":397, // "exponent":9, // "type":"crypto", // "address_regex":"^(B62)[A-Za-z0-9]{52}$", // "asset_id":"a4ffc575-942c-5e26-b70c-cb3befdd4229", // "slug":"mina" // }, // "balance":{"amount":"0.000000000","currency":"MINA"}, // "created_at":"2022-03-25T00:36:16Z", // "updated_at":"2022-03-25T00:36:16Z", // "resource":"account", // "resource_path":"/v2/accounts/94ad58bc-0f15-5309-b35a-a4c86d7bad60", // "allow_deposits":true, // "allow_withdrawals":true // }, // ] // } // // v3PrivateGetBrokerageAccounts // { // "accounts": [ // { // "uuid": "11111111-1111-1111-1111-111111111111", // "name": "USDC Wallet", // "currency": "USDC", // "available_balance": { // "value": "0.0000000000000000", // "currency": "USDC" // }, // "default": true, // "active": true, // "created_at": "2023-01-04T06:20:06.456Z", // "updated_at": "2023-01-04T06:20:07.181Z", // "deleted_at": null, // "type": "ACCOUNT_TYPE_CRYPTO", // "ready": false, // "hold": { // "value": "0.0000000000000000", // "currency": "USDC" // } // }, // ... // ], // "has_next": false, // "cursor": "", // "size": 9 // } // AddElementToObject(params, "type", marketType) ch <- this.ParseCustomBalance(response, params) return nil }() return ch } /** * @method * @name coinbase#fetchLedger * @description Fetch the history of changes, i.e. actions done by the user or operations that altered the balance. Will return staking rewards, and crypto deposits or withdrawals. * @see https://docs.cdp.coinbase.com/coinbase-app/docs/api-transactions#list-transactions * @param {string} [code] unified currency code, default is undefined * @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined * @param {int} [limit] max number of ledger entries to return, default is undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger} */ func (this *coinbase) FetchLedger(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes24638 := (<-this.LoadMarkets()) PanicOnError(retRes24638) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchLedger", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes246719 := (<-this.FetchPaginatedCallCursor("fetchLedger", code, since, limit, params, "next_starting_after", "starting_after", nil, 100)) PanicOnError(retRes246719) ch <- retRes246719 return nil } var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) } var request interface{} = nil requestparamsVariable := (<-this.PrepareAccountRequestWithCurrencyCode(code, limit, params)); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) // for pagination use parameter 'starting_after' // the value for the next page can be obtained from the result of the previous call in the 'pagination' field // eg: instance.last_http_response -> pagination.next_starting_after response:= (<-this.V2PrivateGetAccountsAccountIdTransactions(this.Extend(request, params))) PanicOnError(response) var ledger interface{} = this.ParseLedger(GetValue(response, "data"), currency, since, limit) var length interface{} = GetArrayLength(ledger) if IsTrue(IsEqual(length, 0)) { ch <- ledger return nil } var lastIndex interface{} = Subtract(length, 1) var last interface{} = this.SafeDict(ledger, lastIndex) var pagination interface{} = this.SafeDict(response, "pagination", map[string]interface{} {}) var cursor interface{} = this.SafeString(pagination, "next_starting_after") if IsTrue(IsTrue((!IsEqual(cursor, nil))) && IsTrue((!IsEqual(cursor, "")))) { AddElementToObject(GetValue(last, "info"), "next_starting_after", cursor) AddElementToObject(ledger, lastIndex, last) } ch <- ledger return nil }() return ch } func (this *coinbase) ParseLedgerEntryStatus(status interface{}) interface{} { var types interface{} = map[string]interface{} { "completed": "ok", } return this.SafeString(types, status, status) } func (this *coinbase) ParseLedgerEntryType(typeVar interface{}) interface{} { var types interface{} = map[string]interface{} { "buy": "trade", "sell": "trade", "fiat_deposit": "transaction", "fiat_withdrawal": "transaction", "exchange_deposit": "transaction", "exchange_withdrawal": "transaction", "send": "transaction", "pro_deposit": "transaction", "pro_withdrawal": "transaction", } return this.SafeString(types, typeVar, typeVar) } func (this *coinbase) ParseLedgerEntry(item interface{}, optionalArgs ...interface{}) interface{} { // // crypto deposit transaction // // { // "id": "34e4816b-4c8c-5323-a01c-35a9fa26e490", // "type": "send", // "status": "completed", // "amount": { amount: "28.31976528", currency: "BCH" }, // "native_amount": { amount: "2799.65", currency: "GBP" }, // "description": null, // "created_at": "2019-02-28T12:35:20Z", // "updated_at": "2019-02-28T12:43:24Z", // "resource": "transaction", // "resource_path": "/v2/accounts/c01d7364-edd7-5f3a-bd1d-de53d4cbb25e/transactions/34e4816b-4c8c-5323-a01c-35a9fa26e490", // "instant_exchange": false, // "network": { // "status": "confirmed", // "hash": "56222d865dae83774fccb2efbd9829cf08c75c94ce135bfe4276f3fb46d49701", // "transaction_url": "https://bch.btc.com/56222d865dae83774fccb2efbd9829cf08c75c94ce135bfe4276f3fb46d49701" // }, // "from": { resource: "bitcoin_cash_network", currency: "BCH" }, // "details": { title: 'Received Bitcoin Cash', subtitle: "From Bitcoin Cash address" } // } // // crypto withdrawal transaction // // { // "id": "459aad99-2c41-5698-ac71-b6b81a05196c", // "type": "send", // "status": "completed", // "amount": { amount: "-0.36775642", currency: "BTC" }, // "native_amount": { amount: "-1111.65", currency: "GBP" }, // "description": null, // "created_at": "2019-03-20T08:37:07Z", // "updated_at": "2019-03-20T08:49:33Z", // "resource": "transaction", // "resource_path": "/v2/accounts/c6afbd34-4bd0-501e-8616-4862c193cd84/transactions/459aad99-2c41-5698-ac71-b6b81a05196c", // "instant_exchange": false, // "network": { // "status": "confirmed", // "hash": "2732bbcf35c69217c47b36dce64933d103895277fe25738ffb9284092701e05b", // "transaction_url": "https://blockchain.info/tx/2732bbcf35c69217c47b36dce64933d103895277fe25738ffb9284092701e05b", // "transaction_fee": { amount: "0.00000000", currency: "BTC" }, // "transaction_amount": { amount: "0.36775642", currency: "BTC" }, // "confirmations": 15682 // }, // "to": { // "resource": "bitcoin_address", // "address": "1AHnhqbvbYx3rnZx8uC7NbFZaTe4tafFHX", // "currency": "BTC", // "address_info": { address: "1AHnhqbvbYx3rnZx8uC7NbFZaTe4tafFHX" } // }, // "idem": "da0a2f14-a2af-4c5a-a37e-d4484caf582bsend", // "application": { // "id": "5756ab6e-836b-553b-8950-5e389451225d", // "resource": "application", // "resource_path": "/v2/applications/5756ab6e-836b-553b-8950-5e389451225d" // }, // "details": { title: 'Sent Bitcoin', subtitle: "To Bitcoin address" } // } // // withdrawal transaction from coinbase to coinbasepro // // { // "id": "5b1b9fb8-5007-5393-b923-02903b973fdc", // "type": "pro_deposit", // "status": "completed", // "amount": { amount: "-0.00001111", currency: "BCH" }, // "native_amount": { amount: "0.00", currency: "GBP" }, // "description": null, // "created_at": "2019-02-28T13:31:58Z", // "updated_at": "2019-02-28T13:31:58Z", // "resource": "transaction", // "resource_path": "/v2/accounts/c01d7364-edd7-5f3a-bd1d-de53d4cbb25e/transactions/5b1b9fb8-5007-5393-b923-02903b973fdc", // "instant_exchange": false, // "application": { // "id": "5756ab6e-836b-553b-8950-5e389451225d", // "resource": "application", // "resource_path": "/v2/applications/5756ab6e-836b-553b-8950-5e389451225d" // }, // "details": { title: 'Transferred Bitcoin Cash', subtitle: "To Coinbase Pro" } // } // // withdrawal transaction from coinbase to gdax // // { // "id": "badb7313-a9d3-5c07-abd0-00f8b44199b1", // "type": "exchange_deposit", // "status": "completed", // "amount": { amount: "-0.43704149", currency: "BCH" }, // "native_amount": { amount: "-51.90", currency: "GBP" }, // "description": null, // "created_at": "2019-03-19T10:30:40Z", // "updated_at": "2019-03-19T10:30:40Z", // "resource": "transaction", // "resource_path": "/v2/accounts/c01d7364-edd7-5f3a-bd1d-de53d4cbb25e/transactions/badb7313-a9d3-5c07-abd0-00f8b44199b1", // "instant_exchange": false, // "details": { title: 'Transferred Bitcoin Cash', subtitle: "To GDAX" } // } // // deposit transaction from gdax to coinbase // // { // "id": "9c4b642c-8688-58bf-8962-13cef64097de", // "type": "exchange_withdrawal", // "status": "completed", // "amount": { amount: "0.57729420", currency: "BTC" }, // "native_amount": { amount: "4418.72", currency: "GBP" }, // "description": null, // "created_at": "2018-02-17T11:33:33Z", // "updated_at": "2018-02-17T11:33:33Z", // "resource": "transaction", // "resource_path": "/v2/accounts/c6afbd34-4bd0-501e-8616-4862c193cd84/transactions/9c4b642c-8688-58bf-8962-13cef64097de", // "instant_exchange": false, // "details": { title: 'Transferred Bitcoin', subtitle: "From GDAX" } // } // // deposit transaction from coinbasepro to coinbase // // { // "id": "8d6dd0b9-3416-568a-889d-8f112fae9e81", // "type": "pro_withdrawal", // "status": "completed", // "amount": { amount: "0.40555386", currency: "BTC" }, // "native_amount": { amount: "1140.27", currency: "GBP" }, // "description": null, // "created_at": "2019-03-04T19:41:58Z", // "updated_at": "2019-03-04T19:41:58Z", // "resource": "transaction", // "resource_path": "/v2/accounts/c6afbd34-4bd0-501e-8616-4862c193cd84/transactions/8d6dd0b9-3416-568a-889d-8f112fae9e81", // "instant_exchange": false, // "application": { // "id": "5756ab6e-836b-553b-8950-5e389451225d", // "resource": "application", // "resource_path": "/v2/applications/5756ab6e-836b-553b-8950-5e389451225d" // }, // "details": { title: 'Transferred Bitcoin', subtitle: "From Coinbase Pro" } // } // // sell trade // // { // "id": "a9409207-df64-585b-97ab-a50780d2149e", // "type": "sell", // "status": "completed", // "amount": { amount: "-9.09922880", currency: "BTC" }, // "native_amount": { amount: "-7285.73", currency: "GBP" }, // "description": null, // "created_at": "2017-03-27T15:38:34Z", // "updated_at": "2017-03-27T15:38:34Z", // "resource": "transaction", // "resource_path": "/v2/accounts/c6afbd34-4bd0-501e-8616-4862c193cd84/transactions/a9409207-df64-585b-97ab-a50780d2149e", // "instant_exchange": false, // "sell": { // "id": "e3550b4d-8ae6-5de3-95fe-1fb01ba83051", // "resource": "sell", // "resource_path": "/v2/accounts/c6afbd34-4bd0-501e-8616-4862c193cd84/sells/e3550b4d-8ae6-5de3-95fe-1fb01ba83051" // }, // "details": { // "title": "Sold Bitcoin", // "subtitle": "Using EUR Wallet", // "payment_method_name": "EUR Wallet" // } // } // // buy trade // // { // "id": "63eeed67-9396-5912-86e9-73c4f10fe147", // "type": "buy", // "status": "completed", // "amount": { amount: "2.39605772", currency: "ETH" }, // "native_amount": { amount: "98.31", currency: "GBP" }, // "description": null, // "created_at": "2017-03-27T09:07:56Z", // "updated_at": "2017-03-27T09:07:57Z", // "resource": "transaction", // "resource_path": "/v2/accounts/8902f85d-4a69-5d74-82fe-8e390201bda7/transactions/63eeed67-9396-5912-86e9-73c4f10fe147", // "instant_exchange": false, // "buy": { // "id": "20b25b36-76c6-5353-aa57-b06a29a39d82", // "resource": "buy", // "resource_path": "/v2/accounts/8902f85d-4a69-5d74-82fe-8e390201bda7/buys/20b25b36-76c6-5353-aa57-b06a29a39d82" // }, // "details": { // "title": "Bought Ethereum", // "subtitle": "Using EUR Wallet", // "payment_method_name": "EUR Wallet" // } // } // // fiat deposit transaction // // { // "id": "04ed4113-3732-5b0c-af86-b1d2146977d0", // "type": "fiat_deposit", // "status": "completed", // "amount": { amount: "114.02", currency: "EUR" }, // "native_amount": { amount: "97.23", currency: "GBP" }, // "description": null, // "created_at": "2017-02-09T07:01:21Z", // "updated_at": "2017-02-09T07:01:22Z", // "resource": "transaction", // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/transactions/04ed4113-3732-5b0c-af86-b1d2146977d0", // "instant_exchange": false, // "fiat_deposit": { // "id": "f34c19f3-b730-5e3d-9f72-96520448677a", // "resource": "fiat_deposit", // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/deposits/f34c19f3-b730-5e3d-9f72-96520448677a" // }, // "details": { // "title": "Deposited funds", // "subtitle": "From SEPA Transfer (GB47 BARC 20..., reference CBADVI)", // "payment_method_name": "SEPA Transfer (GB47 BARC 20..., reference CBADVI)" // } // } // // fiat withdrawal transaction // // { // "id": "957d98e2-f80e-5e2f-a28e-02945aa93079", // "type": "fiat_withdrawal", // "status": "completed", // "amount": { amount: "-11000.00", currency: "EUR" }, // "native_amount": { amount: "-9698.22", currency: "GBP" }, // "description": null, // "created_at": "2017-12-06T13:19:19Z", // "updated_at": "2017-12-06T13:19:19Z", // "resource": "transaction", // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/transactions/957d98e2-f80e-5e2f-a28e-02945aa93079", // "instant_exchange": false, // "fiat_withdrawal": { // "id": "f4bf1fd9-ab3b-5de7-906d-ed3e23f7a4e7", // "resource": "fiat_withdrawal", // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/withdrawals/f4bf1fd9-ab3b-5de7-906d-ed3e23f7a4e7" // }, // "details": { // "title": "Withdrew funds", // "subtitle": "To HSBC BANK PLC (GB74 MIDL...)", // "payment_method_name": "HSBC BANK PLC (GB74 MIDL...)" // } // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var amountInfo interface{} = this.SafeDict(item, "amount", map[string]interface{} {}) var amount interface{} = this.SafeString(amountInfo, "amount") var direction interface{} = nil if IsTrue(Precise.StringLt(amount, "0")) { direction = "out" amount = Precise.StringNeg(amount) } else { direction = "in" } var currencyId interface{} = this.SafeString(amountInfo, "currency") var code interface{} = this.SafeCurrencyCode(currencyId, currency) currency = this.SafeCurrency(currencyId, currency) // // the address and txid do not belong to the unified ledger structure // // let address = undefined; // if (item['to']) { // address = this.safeString (item['to'], 'address'); // } // let txid = undefined; // var fee interface{} = nil var networkInfo interface{} = this.SafeDict(item, "network", map[string]interface{} {}) // txid = network['hash']; // txid does not belong to the unified ledger structure var feeInfo interface{} = this.SafeDict(networkInfo, "transaction_fee") if IsTrue(!IsEqual(feeInfo, nil)) { var feeCurrencyId interface{} = this.SafeString(feeInfo, "currency") var feeCurrencyCode interface{} = this.SafeCurrencyCode(feeCurrencyId, currency) var feeAmount interface{} = this.SafeNumber(feeInfo, "amount") fee = map[string]interface{} { "cost": feeAmount, "currency": feeCurrencyCode, } } var timestamp interface{} = this.Parse8601(this.SafeString(item, "created_at")) var id interface{} = this.SafeString(item, "id") var typeVar interface{} = this.ParseLedgerEntryType(this.SafeString(item, "type")) var status interface{} = this.ParseLedgerEntryStatus(this.SafeString(item, "status")) var path interface{} = this.SafeString(item, "resource_path") var accountId interface{} = nil if IsTrue(!IsEqual(path, nil)) { var parts interface{} = Split(path, "/") var numParts interface{} = GetArrayLength(parts) if IsTrue(IsGreaterThan(numParts, 3)) { accountId = GetValue(parts, 3) } } return this.SafeLedgerEntry(map[string]interface{} { "info": item, "id": id, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "direction": direction, "account": accountId, "referenceId": nil, "referenceAccount": nil, "type": typeVar, "currency": code, "amount": this.ParseNumber(amount), "before": nil, "after": nil, "status": status, "fee": fee, }, currency) } func (this *coinbase) FindAccountId(code interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes28288 := (<-this.LoadMarkets()) PanicOnError(retRes28288) retRes28298 := (<-this.LoadAccounts(false, params)) PanicOnError(retRes28298) for i := 0; IsLessThan(i, GetArrayLength(this.Accounts)); i++ { var account interface{} = GetValue(this.Accounts, i) if IsTrue(IsEqual(GetValue(account, "code"), code)) { ch <- GetValue(account, "id") return nil } } return nil }() return ch } func (this *coinbase) PrepareAccountRequest(optionalArgs ...interface{}) interface{} { limit := GetArg(optionalArgs, 0, nil) _ = limit params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params var accountId interface{} = this.SafeString2(params, "account_id", "accountId") if IsTrue(IsEqual(accountId, nil)) { panic(ArgumentsRequired(Add(this.Id, " prepareAccountRequest() method requires an account_id (or accountId) parameter"))) } var request interface{} = map[string]interface{} { "account_id": accountId, } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } return request } func (this *coinbase) PrepareAccountRequestWithCurrencyCode(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code limit := GetArg(optionalArgs, 1, nil) _ = limit params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params var accountId interface{} = this.SafeString2(params, "account_id", "accountId") params = this.Omit(params, []interface{}{"account_id", "accountId"}) if IsTrue(IsEqual(accountId, nil)) { if IsTrue(IsEqual(code, nil)) { panic(ArgumentsRequired(Add(this.Id, " prepareAccountRequestWithCurrencyCode() method requires an account_id (or accountId) parameter OR a currency code argument"))) } accountId = (<-this.FindAccountId(code, params)) PanicOnError(accountId) if IsTrue(IsEqual(accountId, nil)) { panic(ExchangeError(Add(Add(this.Id, " prepareAccountRequestWithCurrencyCode() could not find account id for "), code))) } } var request interface{} = map[string]interface{} { "account_id": accountId, } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } ch <- []interface{}{request, params} return nil }() return ch } /** * @method * @name coinbase#createMarketBuyOrderWithCost * @description create a market buy order by providing the symbol and cost * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_postorder * @param {string} symbol unified symbol of the market to create an order in * @param {float} cost how much you want to trade in units of the quote currency * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *coinbase) CreateMarketBuyOrderWithCost(symbol interface{}, cost interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes28858 := (<-this.LoadMarkets()) PanicOnError(retRes28858) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "spot")) { panic(NotSupported(Add(this.Id, " createMarketBuyOrderWithCost() supports spot orders only"))) } AddElementToObject(params, "createMarketBuyOrderRequiresPrice", false) retRes289115 := (<-this.CreateOrder(symbol, "market", "buy", cost, nil, params)) PanicOnError(retRes289115) ch <- retRes289115 return nil }() return ch } /** * @method * @name coinbase#createOrder * @description create a trade order * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_postorder * @param {string} symbol unified symbol of the market to create an order in * @param {string} type 'market' or 'limit' * @param {string} side 'buy' or 'sell' * @param {float} amount how much you want to trade in units of the base currency, quote currency for 'market' 'buy' orders * @param {float} [price] the price to fulfill the order, in units of the quote currency, ignored in market orders * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {float} [params.stopPrice] price to trigger stop orders * @param {float} [params.triggerPrice] price to trigger stop orders * @param {float} [params.stopLossPrice] price to trigger stop-loss orders * @param {float} [params.takeProfitPrice] price to trigger take-profit orders * @param {bool} [params.postOnly] true or false * @param {string} [params.timeInForce] 'GTC', 'IOC', 'GTD' or 'PO', 'FOK' * @param {string} [params.stop_direction] 'UNKNOWN_STOP_DIRECTION', 'STOP_DIRECTION_STOP_UP', 'STOP_DIRECTION_STOP_DOWN' the direction the stopPrice is triggered from * @param {string} [params.end_time] '2023-05-25T17:01:05.092Z' for 'GTD' orders * @param {float} [params.cost] *spot market buy only* the quote quantity that can be used as an alternative for the amount * @param {boolean} [params.preview] default to false, wether to use the test/preview endpoint or not * @param {float} [params.leverage] default to 1, the leverage to use for the order * @param {string} [params.marginMode] 'cross' or 'isolated' * @param {string} [params.retail_portfolio_id] portfolio uid * @param {boolean} [params.is_max] Used in conjunction with tradable_balance to indicate the user wants to use their entire tradable balance * @param {string} [params.tradable_balance] amount of tradable balance * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *coinbase) CreateOrder(symbol interface{}, typeVar interface{}, side interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) price := GetArg(optionalArgs, 0, nil) _ = price params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes29238 := (<-this.LoadMarkets()) PanicOnError(retRes29238) var market interface{} = this.Market(symbol) var id interface{} = this.SafeString(this.Options, "brokerId", "ccxt") var request interface{} = map[string]interface{} { "client_order_id": Add(Add(id, "-"), this.Uuid()), "product_id": GetValue(market, "id"), "side": ToUpper(side), } var triggerPrice interface{} = this.SafeNumberN(params, []interface{}{"stopPrice", "stop_price", "triggerPrice"}) var stopLossPrice interface{} = this.SafeNumber(params, "stopLossPrice") var takeProfitPrice interface{} = this.SafeNumber(params, "takeProfitPrice") var isStop interface{} = !IsEqual(triggerPrice, nil) var isStopLoss interface{} = !IsEqual(stopLossPrice, nil) var isTakeProfit interface{} = !IsEqual(takeProfitPrice, nil) var timeInForce interface{} = this.SafeString(params, "timeInForce") var postOnly interface{} = Ternary(IsTrue((IsEqual(timeInForce, "PO"))), true, this.SafeBool2(params, "postOnly", "post_only", false)) var endTime interface{} = this.SafeString(params, "end_time") var stopDirection interface{} = this.SafeString(params, "stop_direction") if IsTrue(IsEqual(typeVar, "limit")) { if IsTrue(isStop) { if IsTrue(IsEqual(stopDirection, nil)) { stopDirection = Ternary(IsTrue((IsEqual(side, "buy"))), "STOP_DIRECTION_STOP_DOWN", "STOP_DIRECTION_STOP_UP") } if IsTrue(IsTrue((IsEqual(timeInForce, "GTD"))) || IsTrue((!IsEqual(endTime, nil)))) { if IsTrue(IsEqual(endTime, nil)) { panic(ExchangeError(Add(this.Id, " createOrder() requires an end_time parameter for a GTD order"))) } AddElementToObject(request, "order_configuration", map[string]interface{} { "stop_limit_stop_limit_gtd": map[string]interface{} { "base_size": this.AmountToPrecision(symbol, amount), "limit_price": this.PriceToPrecision(symbol, price), "stop_price": this.PriceToPrecision(symbol, triggerPrice), "stop_direction": stopDirection, "end_time": endTime, }, }) } else { AddElementToObject(request, "order_configuration", map[string]interface{} { "stop_limit_stop_limit_gtc": map[string]interface{} { "base_size": this.AmountToPrecision(symbol, amount), "limit_price": this.PriceToPrecision(symbol, price), "stop_price": this.PriceToPrecision(symbol, triggerPrice), "stop_direction": stopDirection, }, }) } } else if IsTrue(IsTrue(isStopLoss) || IsTrue(isTakeProfit)) { var tpslPrice interface{} = nil if IsTrue(isStopLoss) { if IsTrue(IsEqual(stopDirection, nil)) { stopDirection = Ternary(IsTrue((IsEqual(side, "buy"))), "STOP_DIRECTION_STOP_UP", "STOP_DIRECTION_STOP_DOWN") } tpslPrice = this.PriceToPrecision(symbol, stopLossPrice) } else { if IsTrue(IsEqual(stopDirection, nil)) { stopDirection = Ternary(IsTrue((IsEqual(side, "buy"))), "STOP_DIRECTION_STOP_DOWN", "STOP_DIRECTION_STOP_UP") } tpslPrice = this.PriceToPrecision(symbol, takeProfitPrice) } AddElementToObject(request, "order_configuration", map[string]interface{} { "stop_limit_stop_limit_gtc": map[string]interface{} { "base_size": this.AmountToPrecision(symbol, amount), "limit_price": this.PriceToPrecision(symbol, price), "stop_price": tpslPrice, "stop_direction": stopDirection, }, }) } else { if IsTrue(IsTrue((IsEqual(timeInForce, "GTD"))) || IsTrue((!IsEqual(endTime, nil)))) { if IsTrue(IsEqual(endTime, nil)) { panic(ExchangeError(Add(this.Id, " createOrder() requires an end_time parameter for a GTD order"))) } AddElementToObject(request, "order_configuration", map[string]interface{} { "limit_limit_gtd": map[string]interface{} { "base_size": this.AmountToPrecision(symbol, amount), "limit_price": this.PriceToPrecision(symbol, price), "end_time": endTime, "post_only": postOnly, }, }) } else if IsTrue(IsEqual(timeInForce, "IOC")) { AddElementToObject(request, "order_configuration", map[string]interface{} { "sor_limit_ioc": map[string]interface{} { "base_size": this.AmountToPrecision(symbol, amount), "limit_price": this.PriceToPrecision(symbol, price), }, }) } else if IsTrue(IsEqual(timeInForce, "FOK")) { AddElementToObject(request, "order_configuration", map[string]interface{} { "limit_limit_fok": map[string]interface{} { "base_size": this.AmountToPrecision(symbol, amount), "limit_price": this.PriceToPrecision(symbol, price), }, }) } else { AddElementToObject(request, "order_configuration", map[string]interface{} { "limit_limit_gtc": map[string]interface{} { "base_size": this.AmountToPrecision(symbol, amount), "limit_price": this.PriceToPrecision(symbol, price), "post_only": postOnly, }, }) } } } else { if IsTrue(IsTrue(IsTrue(isStop) || IsTrue(isStopLoss)) || IsTrue(isTakeProfit)) { panic(NotSupported(Add(this.Id, " createOrder() only stop limit orders are supported"))) } if IsTrue(IsTrue(GetValue(market, "spot")) && IsTrue((IsEqual(side, "buy")))) { var total interface{} = nil var createMarketBuyOrderRequiresPrice interface{} = true createMarketBuyOrderRequiresPriceparamsVariable := this.HandleOptionAndParams(params, "createOrder", "createMarketBuyOrderRequiresPrice", true); createMarketBuyOrderRequiresPrice = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,0); params = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,1) var cost interface{} = this.SafeNumber(params, "cost") params = this.Omit(params, "cost") if IsTrue(!IsEqual(cost, nil)) { total = this.CostToPrecision(symbol, cost) } else if IsTrue(createMarketBuyOrderRequiresPrice) { if IsTrue(IsEqual(price, nil)) { panic(InvalidOrder(Add(this.Id, " createOrder() requires a price argument for market buy orders on spot markets to calculate the total amount to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend in the amount argument"))) } else { var amountString interface{} = this.NumberToString(amount) var priceString interface{} = this.NumberToString(price) var costRequest interface{} = Precise.StringMul(amountString, priceString) total = this.CostToPrecision(symbol, costRequest) } } else { total = this.CostToPrecision(symbol, amount) } AddElementToObject(request, "order_configuration", map[string]interface{} { "market_market_ioc": map[string]interface{} { "quote_size": total, }, }) } else { AddElementToObject(request, "order_configuration", map[string]interface{} { "market_market_ioc": map[string]interface{} { "base_size": this.AmountToPrecision(symbol, amount), }, }) } } var marginMode interface{} = this.SafeString(params, "marginMode") if IsTrue(!IsEqual(marginMode, nil)) { if IsTrue(IsEqual(marginMode, "isolated")) { AddElementToObject(request, "margin_type", "ISOLATED") } else if IsTrue(IsEqual(marginMode, "cross")) { AddElementToObject(request, "margin_type", "CROSS") } } params = this.Omit(params, []interface{}{"timeInForce", "triggerPrice", "stopLossPrice", "takeProfitPrice", "stopPrice", "stop_price", "stopDirection", "stop_direction", "clientOrderId", "postOnly", "post_only", "end_time", "marginMode"}) var preview interface{} = this.SafeBool2(params, "preview", "test", false) var response interface{} = nil if IsTrue(preview) { params = this.Omit(params, []interface{}{"preview", "test"}) request = this.Omit(request, "client_order_id") response = (<-this.V3PrivatePostBrokerageOrdersPreview(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.V3PrivatePostBrokerageOrders(this.Extend(request, params))) PanicOnError(response) } // // successful order // // { // "success": true, // "failure_reason": "UNKNOWN_FAILURE_REASON", // "order_id": "52cfe5e2-0b29-4c19-a245-a6a773de5030", // "success_response": { // "order_id": "52cfe5e2-0b29-4c19-a245-a6a773de5030", // "product_id": "LTC-BTC", // "side": "SELL", // "client_order_id": "4d760580-6fca-4094-a70b-ebcca8626288" // }, // "order_configuration": null // } // // failed order // // { // "success": false, // "failure_reason": "UNKNOWN_FAILURE_REASON", // "order_id": "", // "error_response": { // "error": "UNSUPPORTED_ORDER_CONFIGURATION", // "message": "source is not enabled for trading", // "error_details": "", // "new_order_failure_reason": "UNSUPPORTED_ORDER_CONFIGURATION" // }, // "order_configuration": { // "limit_limit_gtc": { // "base_size": "100", // "limit_price": "40000", // "post_only": false // } // } // } // var success interface{} = this.SafeBool(response, "success") if IsTrue(!IsEqual(success, true)) { var errorResponse interface{} = this.SafeDict(response, "error_response") var errorTitle interface{} = this.SafeString(errorResponse, "error") var errorMessage interface{} = this.SafeString(errorResponse, "message") if IsTrue(!IsEqual(errorResponse, nil)) { this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), errorTitle, errorMessage) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), errorTitle, errorMessage) panic(ExchangeError(errorMessage)) } } var data interface{} = this.SafeDict(response, "success_response", map[string]interface{} {}) ch <- this.ParseOrder(data, market) return nil }() return ch } func (this *coinbase) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} { // // createOrder // // { // "order_id": "52cfe5e2-0b29-4c19-a245-a6a773de5030", // "product_id": "LTC-BTC", // "side": "SELL", // "client_order_id": "4d760580-6fca-4094-a70b-ebcca8626288" // } // // cancelOrder, cancelOrders // // { // "success": true, // "failure_reason": "UNKNOWN_CANCEL_FAILURE_REASON", // "order_id": "bb8851a3-4fda-4a2c-aa06-9048db0e0f0d" // } // // fetchOrder, fetchOrders, fetchOpenOrders, fetchClosedOrders, fetchCanceledOrders // // { // "order_id": "9bc1eb3b-5b46-4b71-9628-ae2ed0cca75b", // "product_id": "LTC-BTC", // "user_id": "1111111-1111-1111-1111-111111111111", // "order_configuration": { // "limit_limit_gtc": { // "base_size": "0.2", // "limit_price": "0.006", // "post_only": false // }, // "stop_limit_stop_limit_gtc": { // "base_size": "48.54", // "limit_price": "6.998", // "stop_price": "7.0687", // "stop_direction": "STOP_DIRECTION_STOP_DOWN" // } // }, // "side": "SELL", // "client_order_id": "e5fe8482-05bb-428f-ad4d-dbc8ce39239c", // "status": "OPEN", // "time_in_force": "GOOD_UNTIL_CANCELLED", // "created_time": "2023-01-16T23:37:23.947030Z", // "completion_percentage": "0", // "filled_size": "0", // "average_filled_price": "0", // "fee": "", // "number_of_fills": "0", // "filled_value": "0", // "pending_cancel": false, // "size_in_quote": false, // "total_fees": "0", // "size_inclusive_of_fees": false, // "total_value_after_fees": "0", // "trigger_status": "INVALID_ORDER_TYPE", // "order_type": "LIMIT", // "reject_reason": "REJECT_REASON_UNSPECIFIED", // "settled": false, // "product_type": "SPOT", // "reject_message": "", // "cancel_message": "" // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(order, "product_id") var symbol interface{} = this.SafeSymbol(marketId, market, "-") if IsTrue(!IsEqual(symbol, nil)) { market = this.SafeMarket(symbol, market) } var orderConfiguration interface{} = this.SafeDict(order, "order_configuration", map[string]interface{} {}) var limitGTC interface{} = this.SafeDict(orderConfiguration, "limit_limit_gtc") var limitGTD interface{} = this.SafeDict(orderConfiguration, "limit_limit_gtd") var limitIOC interface{} = this.SafeDict(orderConfiguration, "sor_limit_ioc") var stopLimitGTC interface{} = this.SafeDict(orderConfiguration, "stop_limit_stop_limit_gtc") var stopLimitGTD interface{} = this.SafeDict(orderConfiguration, "stop_limit_stop_limit_gtd") var marketIOC interface{} = this.SafeDict(orderConfiguration, "market_market_ioc") var isLimit interface{} = (IsTrue(IsTrue((!IsEqual(limitGTC, nil))) || IsTrue((!IsEqual(limitGTD, nil)))) || IsTrue((!IsEqual(limitIOC, nil)))) var isStop interface{} = (IsTrue((!IsEqual(stopLimitGTC, nil))) || IsTrue((!IsEqual(stopLimitGTD, nil)))) var price interface{} = nil var amount interface{} = nil var postOnly interface{} = nil var triggerPrice interface{} = nil if IsTrue(isLimit) { var target interface{} = nil if IsTrue(!IsEqual(limitGTC, nil)) { target = limitGTC } else if IsTrue(!IsEqual(limitGTD, nil)) { target = limitGTD } else { target = limitIOC } price = this.SafeString(target, "limit_price") amount = this.SafeString(target, "base_size") postOnly = this.SafeBool(target, "post_only") } else if IsTrue(isStop) { var stopTarget interface{} = Ternary(IsTrue((!IsEqual(stopLimitGTC, nil))), stopLimitGTC, stopLimitGTD) price = this.SafeString(stopTarget, "limit_price") amount = this.SafeString(stopTarget, "base_size") postOnly = this.SafeBool(stopTarget, "post_only") triggerPrice = this.SafeString(stopTarget, "stop_price") } else { amount = this.SafeString(marketIOC, "base_size") } var datetime interface{} = this.SafeString(order, "created_time") var totalFees interface{} = this.SafeString(order, "total_fees") var currencyFee interface{} = nil if IsTrue(IsTrue((!IsEqual(totalFees, nil))) && IsTrue((!IsEqual(market, nil)))) { currencyFee = GetValue(market, "quote") } return this.SafeOrder(map[string]interface{} { "info": order, "id": this.SafeString(order, "order_id"), "clientOrderId": this.SafeString(order, "client_order_id"), "timestamp": this.Parse8601(datetime), "datetime": datetime, "lastTradeTimestamp": nil, "symbol": symbol, "type": this.ParseOrderType(this.SafeString(order, "order_type")), "timeInForce": this.ParseTimeInForce(this.SafeString(order, "time_in_force")), "postOnly": postOnly, "side": this.SafeStringLower(order, "side"), "price": price, "triggerPrice": triggerPrice, "amount": amount, "filled": this.SafeString(order, "filled_size"), "remaining": nil, "cost": nil, "average": this.SafeString(order, "average_filled_price"), "status": this.ParseOrderStatus(this.SafeString(order, "status")), "fee": map[string]interface{} { "cost": this.SafeString(order, "total_fees"), "currency": currencyFee, }, "trades": nil, }, market) } func (this *coinbase) ParseOrderStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "OPEN": "open", "FILLED": "closed", "CANCELLED": "canceled", "EXPIRED": "canceled", "FAILED": "canceled", "UNKNOWN_ORDER_STATUS": nil, } return this.SafeString(statuses, status, status) } func (this *coinbase) ParseOrderType(typeVar interface{}) interface{} { if IsTrue(IsEqual(typeVar, "UNKNOWN_ORDER_TYPE")) { return nil } var types interface{} = map[string]interface{} { "MARKET": "market", "LIMIT": "limit", "STOP": "limit", "STOP_LIMIT": "limit", } return this.SafeString(types, typeVar, typeVar) } func (this *coinbase) ParseTimeInForce(timeInForce interface{}) interface{} { var timeInForces interface{} = map[string]interface{} { "GOOD_UNTIL_CANCELLED": "GTC", "GOOD_UNTIL_DATE_TIME": "GTD", "IMMEDIATE_OR_CANCEL": "IOC", "FILL_OR_KILL": "FOK", "UNKNOWN_TIME_IN_FORCE": nil, } return this.SafeString(timeInForces, timeInForce, timeInForce) } /** * @method * @name coinbase#cancelOrder * @description cancels an open order * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_cancelorders * @param {string} id order id * @param {string} symbol not used by coinbase cancelOrder() * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *coinbase) CancelOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes33178 := (<-this.LoadMarkets()) PanicOnError(retRes33178) orders:= (<-this.CancelOrders([]interface{}{id}, symbol, params)) PanicOnError(orders) ch <- this.SafeDict(orders, 0, map[string]interface{} {}) return nil }() return ch } /** * @method * @name coinbase#cancelOrders * @description cancel multiple orders * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_cancelorders * @param {string[]} ids order ids * @param {string} symbol not used by coinbase cancelOrders() * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *coinbase) CancelOrders(ids interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes33338 := (<-this.LoadMarkets()) PanicOnError(retRes33338) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var request interface{} = map[string]interface{} { "order_ids": ids, } response:= (<-this.V3PrivatePostBrokerageOrdersBatchCancel(this.Extend(request, params))) PanicOnError(response) // // { // "results": [ // { // "success": true, // "failure_reason": "UNKNOWN_CANCEL_FAILURE_REASON", // "order_id": "bb8851a3-4fda-4a2c-aa06-9048db0e0f0d" // } // ] // } // var orders interface{} = this.SafeList(response, "results", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ { var success interface{} = this.SafeBool(GetValue(orders, i), "success") if IsTrue(!IsEqual(success, true)) { panic(BadRequest(Add(this.Id, " cancelOrders() has failed, check your arguments and parameters"))) } } ch <- this.ParseOrders(orders, market) return nil }() return ch } /** * @method * @name coinbase#editOrder * @description edit a trade order * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_editorder * @param {string} id cancel order id * @param {string} symbol unified symbol of the market to create an order in * @param {string} type 'market' or 'limit' * @param {string} side 'buy' or 'sell' * @param {float} amount how much of currency you want to trade in units of base currency * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.preview] default to false, wether to use the test/preview endpoint or not * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *coinbase) EditOrder(id interface{}, symbol interface{}, typeVar interface{}, side interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) amount := GetArg(optionalArgs, 0, nil) _ = amount price := GetArg(optionalArgs, 1, nil) _ = price params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params retRes33798 := (<-this.LoadMarkets()) PanicOnError(retRes33798) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "order_id": id, } if IsTrue(!IsEqual(amount, nil)) { AddElementToObject(request, "size", this.AmountToPrecision(symbol, amount)) } if IsTrue(!IsEqual(price, nil)) { AddElementToObject(request, "price", this.PriceToPrecision(symbol, price)) } var preview interface{} = this.SafeBool2(params, "preview", "test", false) var response interface{} = nil if IsTrue(preview) { params = this.Omit(params, []interface{}{"preview", "test"}) response = (<-this.V3PrivatePostBrokerageOrdersEditPreview(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.V3PrivatePostBrokerageOrdersEdit(this.Extend(request, params))) PanicOnError(response) } // // { // "success": true, // "errors": { // "edit_failure_reason": "UNKNOWN_EDIT_ORDER_FAILURE_REASON", // "preview_failure_reason": "UNKNOWN_PREVIEW_FAILURE_REASON" // } // } // ch <- this.ParseOrder(response, market) return nil }() return ch } /** * @method * @name coinbase#fetchOrder * @description fetches information on an order made by the user * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorder * @param {string} id the order id * @param {string} symbol unified market symbol that the order was made in * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *coinbase) FetchOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes34218 := (<-this.LoadMarkets()) PanicOnError(retRes34218) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var request interface{} = map[string]interface{} { "order_id": id, } response:= (<-this.V3PrivateGetBrokerageOrdersHistoricalOrderId(this.Extend(request, params))) PanicOnError(response) // // { // "order": { // "order_id": "9bc1eb3b-5b46-4b71-9628-ae2ed0cca75b", // "product_id": "LTC-BTC", // "user_id": "1111111-1111-1111-1111-111111111111", // "order_configuration": { // "limit_limit_gtc": { // "base_size": "0.2", // "limit_price": "0.006", // "post_only": false // } // }, // "side": "SELL", // "client_order_id": "e5fe8482-05bb-428f-ad4d-dbc8ce39239c", // "status": "OPEN", // "time_in_force": "GOOD_UNTIL_CANCELLED", // "created_time": "2023-01-16T23:37:23.947030Z", // "completion_percentage": "0", // "filled_size": "0", // "average_filled_price": "0", // "fee": "", // "number_of_fills": "0", // "filled_value": "0", // "pending_cancel": false, // "size_in_quote": false, // "total_fees": "0", // "size_inclusive_of_fees": false, // "total_value_after_fees": "0", // "trigger_status": "INVALID_ORDER_TYPE", // "order_type": "LIMIT", // "reject_reason": "REJECT_REASON_UNSPECIFIED", // "settled": false, // "product_type": "SPOT", // "reject_message": "", // "cancel_message": "" // } // } // var order interface{} = this.SafeDict(response, "order", map[string]interface{} {}) ch <- this.ParseOrder(order, market) return nil }() return ch } /** * @method * @name coinbase#fetchOrders * @description fetches information on multiple orders made by the user * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorders * @param {string} symbol unified market symbol that the orders were made in * @param {int} [since] the earliest time in ms to fetch orders * @param {int} [limit] the maximum number of order structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] the latest time in ms to fetch trades for * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *coinbase) FetchOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, 100) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes34878 := (<-this.LoadMarkets()) PanicOnError(retRes34878) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOrders", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes349119 := (<-this.FetchPaginatedCallCursor("fetchOrders", symbol, since, limit, params, "cursor", "cursor", nil, 1000)) PanicOnError(retRes349119) ch <- retRes349119 return nil } var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(market, nil)) { AddElementToObject(request, "product_id", GetValue(market, "id")) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start_date", this.Iso8601(since)) } var until interface{} = this.SafeIntegerN(params, []interface{}{"until"}) if IsTrue(!IsEqual(until, nil)) { params = this.Omit(params, []interface{}{"until"}) AddElementToObject(request, "end_date", this.Iso8601(until)) } response:= (<-this.V3PrivateGetBrokerageOrdersHistoricalBatch(this.Extend(request, params))) PanicOnError(response) // // { // "orders": [ // { // "order_id": "813a53c5-3e39-47bb-863d-2faf685d22d8", // "product_id": "BTC-USDT", // "user_id": "1111111-1111-1111-1111-111111111111", // "order_configuration": { // "market_market_ioc": { // "quote_size": "6.36" // } // }, // "side": "BUY", // "client_order_id": "18eb9947-db49-4874-8e7b-39b8fe5f4317", // "status": "FILLED", // "time_in_force": "IMMEDIATE_OR_CANCEL", // "created_time": "2023-01-18T01:37:37.975552Z", // "completion_percentage": "100", // "filled_size": "0.000297920684505", // "average_filled_price": "21220.6399999973697697", // "fee": "", // "number_of_fills": "2", // "filled_value": "6.3220675944333996", // "pending_cancel": false, // "size_in_quote": true, // "total_fees": "0.0379324055666004", // "size_inclusive_of_fees": true, // "total_value_after_fees": "6.36", // "trigger_status": "INVALID_ORDER_TYPE", // "order_type": "MARKET", // "reject_reason": "REJECT_REASON_UNSPECIFIED", // "settled": true, // "product_type": "SPOT", // "reject_message": "", // "cancel_message": "Internal error" // }, // ], // "sequence": "0", // "has_next": false, // "cursor": "" // } // var orders interface{} = this.SafeList(response, "orders", []interface{}{}) var first interface{} = this.SafeDict(orders, 0) var cursor interface{} = this.SafeString(response, "cursor") if IsTrue(IsTrue((!IsEqual(cursor, nil))) && IsTrue((!IsEqual(cursor, "")))) { AddElementToObject(first, "cursor", cursor) AddElementToObject(orders, 0, first) } ch <- this.ParseOrders(orders, market, since, limit) return nil }() return ch } func (this *coinbase) FetchOrdersByStatus(status interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes35668 := (<-this.LoadMarkets()) PanicOnError(retRes35668) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var request interface{} = map[string]interface{} { "order_status": status, } if IsTrue(!IsEqual(market, nil)) { AddElementToObject(request, "product_id", GetValue(market, "id")) } if IsTrue(IsEqual(limit, nil)) { limit = 100 } AddElementToObject(request, "limit", limit) if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start_date", this.Iso8601(since)) } var until interface{} = this.SafeIntegerN(params, []interface{}{"until"}) if IsTrue(!IsEqual(until, nil)) { params = this.Omit(params, []interface{}{"until"}) AddElementToObject(request, "end_date", this.Iso8601(until)) } response:= (<-this.V3PrivateGetBrokerageOrdersHistoricalBatch(this.Extend(request, params))) PanicOnError(response) // // { // "orders": [ // { // "order_id": "813a53c5-3e39-47bb-863d-2faf685d22d8", // "product_id": "BTC-USDT", // "user_id": "1111111-1111-1111-1111-111111111111", // "order_configuration": { // "market_market_ioc": { // "quote_size": "6.36" // } // }, // "side": "BUY", // "client_order_id": "18eb9947-db49-4874-8e7b-39b8fe5f4317", // "status": "FILLED", // "time_in_force": "IMMEDIATE_OR_CANCEL", // "created_time": "2023-01-18T01:37:37.975552Z", // "completion_percentage": "100", // "filled_size": "0.000297920684505", // "average_filled_price": "21220.6399999973697697", // "fee": "", // "number_of_fills": "2", // "filled_value": "6.3220675944333996", // "pending_cancel": false, // "size_in_quote": true, // "total_fees": "0.0379324055666004", // "size_inclusive_of_fees": true, // "total_value_after_fees": "6.36", // "trigger_status": "INVALID_ORDER_TYPE", // "order_type": "MARKET", // "reject_reason": "REJECT_REASON_UNSPECIFIED", // "settled": true, // "product_type": "SPOT", // "reject_message": "", // "cancel_message": "Internal error" // }, // ], // "sequence": "0", // "has_next": false, // "cursor": "" // } // var orders interface{} = this.SafeList(response, "orders", []interface{}{}) var first interface{} = this.SafeDict(orders, 0) var cursor interface{} = this.SafeString(response, "cursor") if IsTrue(IsTrue((!IsEqual(cursor, nil))) && IsTrue((!IsEqual(cursor, "")))) { AddElementToObject(first, "cursor", cursor) AddElementToObject(orders, 0, first) } ch <- this.ParseOrders(orders, market, since, limit) return nil }() return ch } /** * @method * @name coinbase#fetchOpenOrders * @description fetches information on all currently open orders * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorders * @param {string} symbol unified market symbol of the orders * @param {int} [since] timestamp in ms of the earliest order, default is undefined * @param {int} [limit] the maximum number of open order structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @param {int} [params.until] the latest time in ms to fetch trades for * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *coinbase) FetchOpenOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes36568 := (<-this.LoadMarkets()) PanicOnError(retRes36568) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOpenOrders", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes366019 := (<-this.FetchPaginatedCallCursor("fetchOpenOrders", symbol, since, limit, params, "cursor", "cursor", nil, 100)) PanicOnError(retRes366019) ch <- retRes366019 return nil } retRes366215 := (<-this.FetchOrdersByStatus("OPEN", symbol, since, limit, params)) PanicOnError(retRes366215) ch <- retRes366215 return nil }() return ch } /** * @method * @name coinbase#fetchClosedOrders * @description fetches information on multiple closed orders made by the user * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorders * @param {string} symbol unified market symbol of the orders * @param {int} [since] timestamp in ms of the earliest order, default is undefined * @param {int} [limit] the maximum number of closed order structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @param {int} [params.until] the latest time in ms to fetch trades for * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *coinbase) FetchClosedOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes36798 := (<-this.LoadMarkets()) PanicOnError(retRes36798) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchClosedOrders", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes368319 := (<-this.FetchPaginatedCallCursor("fetchClosedOrders", symbol, since, limit, params, "cursor", "cursor", nil, 100)) PanicOnError(retRes368319) ch <- retRes368319 return nil } retRes368515 := (<-this.FetchOrdersByStatus("FILLED", symbol, since, limit, params)) PanicOnError(retRes368515) ch <- retRes368515 return nil }() return ch } /** * @method * @name coinbase#fetchCanceledOrders * @description fetches information on multiple canceled orders made by the user * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorders * @param {string} symbol unified market symbol of the orders * @param {int} [since] timestamp in ms of the earliest order, default is undefined * @param {int} [limit] the maximum number of canceled order structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *coinbase) FetchCanceledOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes370015 := (<-this.FetchOrdersByStatus("CANCELLED", symbol, since, limit, params)) PanicOnError(retRes370015) ch <- retRes370015 return nil }() return ch } /** * @method * @name coinbase#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpubliccandles * @param {string} symbol unified symbol of the market to fetch OHLCV data for * @param {string} timeframe the length of time each candle represents * @param {int} [since] timestamp in ms of the earliest candle to fetch * @param {int} [limit] the maximum amount of candles to fetch, not used by coinbase * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] the latest time in ms to fetch trades for * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @param {boolean} [params.usePrivate] default false, when true will use the private endpoint to fetch the candles * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ func (this *coinbase) FetchOHLCV(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) timeframe := GetArg(optionalArgs, 0, "1m") _ = timeframe since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes37198 := (<-this.LoadMarkets()) PanicOnError(retRes37198) var maxLimit interface{} = 300 limit = Ternary(IsTrue((IsEqual(limit, nil))), maxLimit, mathMin(limit, maxLimit)) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOHLCV", "paginate", false); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes372519 := (<-this.FetchPaginatedCallDeterministic("fetchOHLCV", symbol, since, limit, timeframe, params, Subtract(maxLimit, 1))) PanicOnError(retRes372519) ch <- retRes372519 return nil } var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "product_id": GetValue(market, "id"), "granularity": this.SafeString(this.Timeframes, timeframe, timeframe), } var until interface{} = this.SafeIntegerN(params, []interface{}{"until", "end"}) params = this.Omit(params, []interface{}{"until"}) var duration interface{} = this.ParseTimeframe(timeframe) var requestedDuration interface{} = Multiply(limit, duration) var sinceString interface{} = nil if IsTrue(!IsEqual(since, nil)) { sinceString = this.NumberToString(this.ParseToInt(Divide(since, 1000))) } else { var now interface{} = ToString(this.Seconds()) sinceString = Precise.StringSub(now, ToString(requestedDuration)) } AddElementToObject(request, "start", sinceString) if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "end", this.NumberToString(this.ParseToInt(Divide(until, 1000)))) } else { // 300 candles max AddElementToObject(request, "end", Precise.StringAdd(sinceString, ToString(requestedDuration))) } var response interface{} = nil var usePrivate interface{} = false usePrivateparamsVariable := this.HandleOptionAndParams(params, "fetchOHLCV", "usePrivate", false); usePrivate = GetValue(usePrivateparamsVariable,0); params = GetValue(usePrivateparamsVariable,1) if IsTrue(usePrivate) { response = (<-this.V3PrivateGetBrokerageProductsProductIdCandles(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.V3PublicGetBrokerageMarketProductsProductIdCandles(this.Extend(request, params))) PanicOnError(response) } // // { // "candles": [ // { // "start": "1673391780", // "low": "17414.36", // "high": "17417.99", // "open": "17417.74", // "close": "17417.38", // "volume": "1.87780853" // }, // ] // } // var candles interface{} = this.SafeList(response, "candles", []interface{}{}) ch <- this.ParseOHLCVs(candles, market, timeframe, since, limit) return nil }() return ch } func (this *coinbase) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} { // // [ // { // "start": "1673391780", // "low": "17414.36", // "high": "17417.99", // "open": "17417.74", // "close": "17417.38", // "volume": "1.87780853" // }, // ] // market := GetArg(optionalArgs, 0, nil) _ = market return []interface{}{this.SafeTimestamp(ohlcv, "start"), this.SafeNumber(ohlcv, "open"), this.SafeNumber(ohlcv, "high"), this.SafeNumber(ohlcv, "low"), this.SafeNumber(ohlcv, "close"), this.SafeNumber(ohlcv, "volume")} } /** * @method * @name coinbase#fetchTrades * @description get the list of most recent trades for a particular symbol * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpublicmarkettrades * @param {string} symbol unified market symbol of the trades * @param {int} [since] not used by coinbase fetchTrades * @param {int} [limit] the maximum number of trade structures to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.usePrivate] default false, when true will use the private endpoint to fetch the trades * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades} */ func (this *coinbase) FetchTrades(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) since := GetArg(optionalArgs, 0, nil) _ = since limit := GetArg(optionalArgs, 1, nil) _ = limit params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params retRes38128 := (<-this.LoadMarkets()) PanicOnError(retRes38128) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "product_id": GetValue(market, "id"), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", this.NumberToString(this.ParseToInt(Divide(since, 1000)))) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", mathMin(limit, 1000)) } var until interface{} = nil untilparamsVariable := this.HandleOptionAndParams(params, "fetchTrades", "until"); until = GetValue(untilparamsVariable,0); params = GetValue(untilparamsVariable,1) if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "end", this.NumberToString(this.ParseToInt(Divide(until, 1000)))) } else if IsTrue(!IsEqual(since, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchTrades() requires a `until` parameter when you use `since` argument"))) } var response interface{} = nil var usePrivate interface{} = false usePrivateparamsVariable := this.HandleOptionAndParams(params, "fetchTrades", "usePrivate", false); usePrivate = GetValue(usePrivateparamsVariable,0); params = GetValue(usePrivateparamsVariable,1) if IsTrue(usePrivate) { response = (<-this.V3PrivateGetBrokerageProductsProductIdTicker(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.V3PublicGetBrokerageMarketProductsProductIdTicker(this.Extend(request, params))) PanicOnError(response) } // // { // "trades": [ // { // "trade_id": "10092327", // "product_id": "BTC-USDT", // "price": "17488.12", // "size": "0.0000623", // "time": "2023-01-11T00:52:37.557001Z", // "side": "BUY", // "bid": "", // "ask": "" // }, // ] // } // var trades interface{} = this.SafeList(response, "trades", []interface{}{}) ch <- this.ParseTrades(trades, market, since, limit) return nil }() return ch } /** * @method * @name coinbase#fetchMyTrades * @description fetch all trades made by the user * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfills * @param {string} symbol unified market symbol of the trades * @param {int} [since] timestamp in ms of the earliest order, default is undefined * @param {int} [limit] the maximum number of trade structures to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] the latest time in ms to fetch trades for * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ func (this *coinbase) FetchMyTrades(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes38728 := (<-this.LoadMarkets()) PanicOnError(retRes38728) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchMyTrades", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes387619 := (<-this.FetchPaginatedCallCursor("fetchMyTrades", symbol, since, limit, params, "cursor", "cursor", nil, 250)) PanicOnError(retRes387619) ch <- retRes387619 return nil } var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(market, nil)) { AddElementToObject(request, "product_id", GetValue(market, "id")) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start_sequence_timestamp", this.Iso8601(since)) } var until interface{} = this.SafeIntegerN(params, []interface{}{"until"}) if IsTrue(!IsEqual(until, nil)) { params = this.Omit(params, []interface{}{"until"}) AddElementToObject(request, "end_sequence_timestamp", this.Iso8601(until)) } response:= (<-this.V3PrivateGetBrokerageOrdersHistoricalFills(this.Extend(request, params))) PanicOnError(response) // // { // "fills": [ // { // "entry_id": "b88b82cc89e326a2778874795102cbafd08dd979a2a7a3c69603fc4c23c2e010", // "trade_id": "cdc39e45-bbd3-44ec-bf02-61742dfb16a1", // "order_id": "813a53c5-3e39-47bb-863d-2faf685d22d8", // "trade_time": "2023-01-18T01:37:38.091377090Z", // "trade_type": "FILL", // "price": "21220.64", // "size": "0.0046830664333996", // "commission": "0.0000280983986004", // "product_id": "BTC-USDT", // "sequence_timestamp": "2023-01-18T01:37:38.092520Z", // "liquidity_indicator": "UNKNOWN_LIQUIDITY_INDICATOR", // "size_in_quote": true, // "user_id": "1111111-1111-1111-1111-111111111111", // "side": "BUY" // }, // ], // "cursor": "" // } // var trades interface{} = this.SafeList(response, "fills", []interface{}{}) var first interface{} = this.SafeDict(trades, 0) var cursor interface{} = this.SafeString(response, "cursor") if IsTrue(IsTrue((!IsEqual(cursor, nil))) && IsTrue((!IsEqual(cursor, "")))) { AddElementToObject(first, "cursor", cursor) AddElementToObject(trades, 0, first) } ch <- this.ParseTrades(trades, market, since, limit) return nil }() return ch } /** * @method * @name coinbase#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpublicproductbook * @param {string} symbol unified symbol of the market to fetch the order book for * @param {int} [limit] the maximum amount of order book entries to return * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.usePrivate] default false, when true will use the private endpoint to fetch the order book * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols */ func (this *coinbase) FetchOrderBook(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) limit := GetArg(optionalArgs, 0, nil) _ = limit params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes39438 := (<-this.LoadMarkets()) PanicOnError(retRes39438) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "product_id": GetValue(market, "id"), } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } var response interface{} = nil var usePrivate interface{} = false usePrivateparamsVariable := this.HandleOptionAndParams(params, "fetchOrderBook", "usePrivate", false); usePrivate = GetValue(usePrivateparamsVariable,0); params = GetValue(usePrivateparamsVariable,1) if IsTrue(usePrivate) { response = (<-this.V3PrivateGetBrokerageProductBook(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.V3PublicGetBrokerageMarketProductBook(this.Extend(request, params))) PanicOnError(response) } // // { // "pricebook": { // "product_id": "BTC-USDT", // "bids": [ // { // "price": "30757.85", // "size": "0.115" // }, // ], // "asks": [ // { // "price": "30759.07", // "size": "0.04877659" // }, // ], // "time": "2023-06-30T04:02:40.533606Z" // } // } // var data interface{} = this.SafeDict(response, "pricebook", map[string]interface{} {}) var time interface{} = this.SafeString(data, "time") var timestamp interface{} = this.Parse8601(time) ch <- this.ParseOrderBook(data, symbol, timestamp, "bids", "asks", "price", "size") return nil }() return ch } /** * @method * @name coinbase#fetchBidsAsks * @description fetches the bid and ask price and volume for multiple markets * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getbestbidask * @param {string[]} [symbols] unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ func (this *coinbase) FetchBidsAsks(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbols := GetArg(optionalArgs, 0, nil) _ = symbols params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes39958 := (<-this.LoadMarkets()) PanicOnError(retRes39958) symbols = this.MarketSymbols(symbols) var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(symbols, nil)) { AddElementToObject(request, "product_ids", this.MarketIds(symbols)) } response:= (<-this.V3PrivateGetBrokerageBestBidAsk(this.Extend(request, params))) PanicOnError(response) // // { // "pricebooks": [ // { // "product_id": "TRAC-EUR", // "bids": [ // { // "price": "0.2384", // "size": "386.1" // } // ], // "asks": [ // { // "price": "0.2406", // "size": "672" // } // ], // "time": "2023-06-30T07:15:24.656044Z" // }, // ] // } // var tickers interface{} = this.SafeList(response, "pricebooks", []interface{}{}) ch <- this.ParseTickers(tickers, symbols) return nil }() return ch } /** * @method * @name coinbase#withdraw * @description make a withdrawal * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-transactions#send-money * @param {string} code unified currency code * @param {float} amount the amount to withdraw * @param {string} address the address to withdraw to * @param {string} [tag] an optional tag for the withdrawal * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *coinbase) Withdraw(code interface{}, amount interface{}, address interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) tag := GetArg(optionalArgs, 0, nil) _ = tag params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params tagparamsVariable := this.HandleWithdrawTagAndParams(tag, params); tag = GetValue(tagparamsVariable,0); params = GetValue(tagparamsVariable,1) this.CheckAddress(address) retRes40438 := (<-this.LoadMarkets()) PanicOnError(retRes40438) var currency interface{} = this.Currency(code) var accountId interface{} = this.SafeString2(params, "account_id", "accountId") params = this.Omit(params, []interface{}{"account_id", "accountId"}) if IsTrue(IsEqual(accountId, nil)) { if IsTrue(IsEqual(code, nil)) { panic(ArgumentsRequired(Add(this.Id, " withdraw() requires an account_id (or accountId) parameter OR a currency code argument"))) } accountId = (<-this.FindAccountId(code, params)) PanicOnError(accountId) if IsTrue(IsEqual(accountId, nil)) { panic(ExchangeError(Add(Add(this.Id, " withdraw() could not find account id for "), code))) } } var request interface{} = map[string]interface{} { "account_id": accountId, "type": "send", "to": address, "amount": amount, "currency": GetValue(currency, "id"), } if IsTrue(!IsEqual(tag, nil)) { AddElementToObject(request, "destination_tag", tag) } response:= (<-this.V2PrivatePostAccountsAccountIdTransactions(this.Extend(request, params))) PanicOnError(response) // // { // "data": { // "id": "a1794ecf-5693-55fa-70cf-ef731748ed82", // "type": "send", // "status": "pending", // "amount": { // "amount": "-14.008308", // "currency": "USDC" // }, // "native_amount": { // "amount": "-18.74", // "currency": "CAD" // }, // "description": null, // "created_at": "2024-01-12T01:27:31Z", // "updated_at": "2024-01-12T01:27:31Z", // "resource": "transaction", // "resource_path": "/v2/accounts/a34bgfad-ed67-538b-bffc-730c98c10da0/transactions/a1794ecf-5693-55fa-70cf-ef731748ed82", // "instant_exchange": false, // "network": { // "status": "pending", // "status_description": "Pending (est. less than 10 minutes)", // "transaction_fee": { // "amount": "4.008308", // "currency": "USDC" // }, // "transaction_amount": { // "amount": "10.000000", // "currency": "USDC" // }, // "confirmations": 0 // }, // "to": { // "resource": "ethereum_address", // "address": "0x9...", // "currency": "USDC", // "address_info": { // "address": "0x9..." // } // }, // "idem": "748d8591-dg9a-7831-a45b-crd61dg78762", // "details": { // "title": "Sent USDC", // "subtitle": "To USDC address on Ethereum network", // "header": "Sent 14.008308 USDC ($18.74)", // "health": "warning" // }, // "hide_native_amount": false // } // } // var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) ch <- this.ParseTransaction(data, currency) return nil }() return ch } /** * @method * @name coinbase#fetchDepositAddress * @description fetch the deposit address for a currency associated with this account * @see https://docs.cloud.coinbase.com/exchange/reference/exchangerestapi_postcoinbaseaccountaddresses * @param {string} code unified currency code * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure} */ func (this *coinbase) FetchDepositAddressesByNetwork(code interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes41338 := (<-this.LoadMarkets()) PanicOnError(retRes41338) var currency interface{} = this.Currency(code) var request interface{} = nil requestparamsVariable := (<-this.PrepareAccountRequestWithCurrencyCode(GetValue(currency, "code"), nil, params)); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) response:= (<-this.V2PrivateGetAccountsAccountIdAddresses(this.Extend(request, params))) PanicOnError(response) // // { // pagination: { // ending_before: null, // starting_after: null, // previous_ending_before: null, // next_starting_after: null, // limit: '25', // order: 'desc', // previous_uri: null, // next_uri: null // }, // data: [ // { // id: '64ceb5f1-5fa2-5310-a4ff-9fd46271003d', // address: '5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk', // address_info: { address: '5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk' }, // name: null, // created_at: '2023-05-29T21:12:12Z', // updated_at: '2023-05-29T21:12:12Z', // network: 'solana', // uri_scheme: 'solana', // resource: 'address', // resource_path: '/v2/accounts/a7b3d387-bfb8-5ce7-b8da-1f507e81cf25/addresses/64ceb5f1-5fa2-5310-a4ff-9fd46271003d', // warnings: [ // { // type: 'correct_address_warning', // title: 'This is an ERC20 USDC address.', // details: 'Only send ERC20 USD Coin (USDC) to this address.', // image_url: 'https://www.coinbase.com/assets/addresses/global-receive-warning-a3d91807e61c717e5a38d270965003dcc025ca8a3cea40ec3d7835b7c86087fa.png', // options: [ { text: 'I understand', style: 'primary', id: 'dismiss' } ] // } // ], // qr_code_image_url: 'https://static-assets.coinbase.com/p2p/l2/asset_network_combinations/v5/usdc-solana.png', // address_label: 'USDC address (Solana)', // default_receive: true, // deposit_uri: 'solana:5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk?spl-token=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // callback_url: null, // share_address_copy: { // line1: '5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk', // line2: 'This address can only receive USDC-SPL from Solana network. Don’t send USDC from other networks, other SPL tokens or NFTs, or it may result in a loss of funds.' // }, // receive_subtitle: 'ERC-20', // inline_warning: { // text: 'This address can only receive USDC-SPL from Solana network. Don’t send USDC from other networks, other SPL tokens or NFTs, or it may result in a loss of funds.', // tooltip: { // title: 'USDC (Solana)', // subtitle: 'This address can only receive USDC-SPL from Solana network.' // } // } // }, // ... // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) var addressStructures interface{} = this.ParseDepositAddresses(data, nil, false) ch <- this.IndexBy(addressStructures, "network") return nil }() return ch } func (this *coinbase) ParseDepositAddress(depositAddress interface{}, optionalArgs ...interface{}) interface{} { // // { // id: '64ceb5f1-5fa2-5310-a4ff-9fd46271003d', // address: '5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk', // address_info: { // address: 'GCF74576I7AQ56SLMKBQAP255EGUOWCRVII3S44KEXVNJEOIFVBDMXVL', // destination_tag: '3722061866' // }, // name: null, // created_at: '2023-05-29T21:12:12Z', // updated_at: '2023-05-29T21:12:12Z', // network: 'solana', // uri_scheme: 'solana', // resource: 'address', // resource_path: '/v2/accounts/a7b3d387-bfb8-5ce7-b8da-1f507e81cf25/addresses/64ceb5f1-5fa2-5310-a4ff-9fd46271003d', // warnings: [ // { // type: 'correct_address_warning', // title: 'This is an ERC20 USDC address.', // details: 'Only send ERC20 USD Coin (USDC) to this address.', // image_url: 'https://www.coinbase.com/assets/addresses/global-receive-warning-a3d91807e61c717e5a38d270965003dcc025ca8a3cea40ec3d7835b7c86087fa.png', // options: [ { text: 'I understand', style: 'primary', id: 'dismiss' } ] // } // ], // qr_code_image_url: 'https://static-assets.coinbase.com/p2p/l2/asset_network_combinations/v5/usdc-solana.png', // address_label: 'USDC address (Solana)', // default_receive: true, // deposit_uri: 'solana:5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk?spl-token=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // callback_url: null, // share_address_copy: { // line1: '5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk', // line2: 'This address can only receive USDC-SPL from Solana network. Don’t send USDC from other networks, other SPL tokens or NFTs, or it may result in a loss of funds.' // }, // receive_subtitle: 'ERC-20', // inline_warning: { // text: 'This address can only receive USDC-SPL from Solana network. Don’t send USDC from other networks, other SPL tokens or NFTs, or it may result in a loss of funds.', // tooltip: { // title: 'USDC (Solana)', // subtitle: 'This address can only receive USDC-SPL from Solana network.' // } // } // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var address interface{} = this.SafeString(depositAddress, "address") this.CheckAddress(address) var networkId interface{} = this.SafeString(depositAddress, "network") var code interface{} = this.SafeCurrencyCode(nil, currency) var addressLabel interface{} = this.SafeString(depositAddress, "address_label") var currencyId interface{} = nil if IsTrue(!IsEqual(addressLabel, nil)) { var splitAddressLabel interface{} = Split(addressLabel, " ") currencyId = this.SafeString(splitAddressLabel, 0) } var addressInfo interface{} = this.SafeDict(depositAddress, "address_info") return map[string]interface{} { "info": depositAddress, "currency": this.SafeCurrencyCode(currencyId, currency), "network": this.NetworkIdToCode(networkId, code), "address": address, "tag": this.SafeString(addressInfo, "destination_tag"), } } /** * @method * @name coinbase#deposit * @description make a deposit * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-deposits#deposit-funds * @param {string} code unified currency code * @param {float} amount the amount to deposit * @param {string} id the payment method id to be used for the deposit, can be retrieved from v2PrivateGetPaymentMethods * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.accountId] the id of the account to deposit into * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *coinbase) Deposit(code interface{}, amount interface{}, id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes42758 := (<-this.LoadMarkets()) PanicOnError(retRes42758) var accountId interface{} = this.SafeString2(params, "account_id", "accountId") params = this.Omit(params, []interface{}{"account_id", "accountId"}) if IsTrue(IsEqual(accountId, nil)) { if IsTrue(IsEqual(code, nil)) { panic(ArgumentsRequired(Add(this.Id, " deposit() requires an account_id (or accountId) parameter OR a currency code argument"))) } accountId = (<-this.FindAccountId(code, params)) PanicOnError(accountId) if IsTrue(IsEqual(accountId, nil)) { panic(ExchangeError(Add(Add(this.Id, " deposit() could not find account id for "), code))) } } var request interface{} = map[string]interface{} { "account_id": accountId, "amount": this.NumberToString(amount), "currency": ToUpper(code), "payment_method": id, } response:= (<-this.V2PrivatePostAccountsAccountIdDeposits(this.Extend(request, params))) PanicOnError(response) // // { // "data": { // "id": "67e0eaec-07d7-54c4-a72c-2e92826897df", // "status": "created", // "payment_method": { // "id": "83562370-3e5c-51db-87da-752af5ab9559", // "resource": "payment_method", // "resource_path": "/v2/payment-methods/83562370-3e5c-51db-87da-752af5ab9559" // }, // "transaction": { // "id": "441b9494-b3f0-5b98-b9b0-4d82c21c252a", // "resource": "transaction", // "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/transactions/441b9494-b3f0-5b98-b9b0-4d82c21c252a" // }, // "amount": { // "amount": "10.00", // "currency": "USD" // }, // "subtotal": { // "amount": "10.00", // "currency": "USD" // }, // "created_at": "2015-01-31T20:49:02Z", // "updated_at": "2015-02-11T16:54:02-08:00", // "resource": "deposit", // "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/deposits/67e0eaec-07d7-54c4-a72c-2e92826897df", // "committed": true, // "fee": { // "amount": "0.00", // "currency": "USD" // }, // "payout_at": "2015-02-18T16:54:00-08:00" // } // } // var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) ch <- this.ParseTransaction(data) return nil }() return ch } /** * @method * @name coinbase#fetchDeposit * @description fetch information on a deposit, fiat only, for crypto transactions use fetchLedger * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-deposits#show-deposit * @param {string} id deposit id * @param {string} [code] unified currency code * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.accountId] the id of the account that the funds were deposited into * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *coinbase) FetchDeposit(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes43468 := (<-this.LoadMarkets()) PanicOnError(retRes43468) var accountId interface{} = this.SafeString2(params, "account_id", "accountId") params = this.Omit(params, []interface{}{"account_id", "accountId"}) if IsTrue(IsEqual(accountId, nil)) { if IsTrue(IsEqual(code, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchDeposit() requires an account_id (or accountId) parameter OR a currency code argument"))) } accountId = (<-this.FindAccountId(code, params)) PanicOnError(accountId) if IsTrue(IsEqual(accountId, nil)) { panic(ExchangeError(Add(Add(this.Id, " fetchDeposit() could not find account id for "), code))) } } var request interface{} = map[string]interface{} { "account_id": accountId, "deposit_id": id, } response:= (<-this.V2PrivateGetAccountsAccountIdDepositsDepositId(this.Extend(request, params))) PanicOnError(response) // // { // "data": { // "id": "67e0eaec-07d7-54c4-a72c-2e92826897df", // "status": "completed", // "payment_method": { // "id": "83562370-3e5c-51db-87da-752af5ab9559", // "resource": "payment_method", // "resource_path": "/v2/payment-methods/83562370-3e5c-51db-87da-752af5ab9559" // }, // "transaction": { // "id": "441b9494-b3f0-5b98-b9b0-4d82c21c252a", // "resource": "transaction", // "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/transactions/441b9494-b3f0-5b98-b9b0-4d82c21c252a" // }, // "amount": { // "amount": "10.00", // "currency": "USD" // }, // "subtotal": { // "amount": "10.00", // "currency": "USD" // }, // "created_at": "2015-01-31T20:49:02Z", // "updated_at": "2015-02-11T16:54:02-08:00", // "resource": "deposit", // "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/deposits/67e0eaec-07d7-54c4-a72c-2e92826897df", // "committed": true, // "fee": { // "amount": "0.00", // "currency": "USD" // }, // "payout_at": "2015-02-18T16:54:00-08:00" // } // } // var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) ch <- this.ParseTransaction(data) return nil }() return ch } /** * @method * @name coinbase#fetchDepositMethodIds * @description fetch the deposit id for a fiat currency associated with this account * @see https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpaymentmethods * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an array of [deposit id structures]{@link https://docs.ccxt.com/#/?id=deposit-id-structure} */ func (this *coinbase) FetchDepositMethodIds(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes44128 := (<-this.LoadMarkets()) PanicOnError(retRes44128) response:= (<-this.V3PrivateGetBrokeragePaymentMethods(params)) PanicOnError(response) // // { // "payment_methods": [ // { // "id": "21b39a5d-f7b46876fb2e", // "type": "COINBASE_FIAT_ACCOUNT", // "name": "CAD Wallet", // "currency": "CAD", // "verified": true, // "allow_buy": false, // "allow_sell": true, // "allow_deposit": false, // "allow_withdraw": false, // "created_at": "2023-06-29T19:58:46Z", // "updated_at": "2023-10-30T20:25:01Z" // } // ] // } // var result interface{} = this.SafeList(response, "payment_methods", []interface{}{}) ch <- this.ParseDepositMethodIds(result) return nil }() return ch } /** * @method * @name coinbase#fetchDepositMethodId * @description fetch the deposit id for a fiat currency associated with this account * @see https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpaymentmethod * @param {string} id the deposit payment method id * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [deposit id structure]{@link https://docs.ccxt.com/#/?id=deposit-id-structure} */ func (this *coinbase) FetchDepositMethodId(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes44478 := (<-this.LoadMarkets()) PanicOnError(retRes44478) var request interface{} = map[string]interface{} { "payment_method_id": id, } response:= (<-this.V3PrivateGetBrokeragePaymentMethodsPaymentMethodId(this.Extend(request, params))) PanicOnError(response) // // { // "payment_method": { // "id": "21b39a5d-f7b46876fb2e", // "type": "COINBASE_FIAT_ACCOUNT", // "name": "CAD Wallet", // "currency": "CAD", // "verified": true, // "allow_buy": false, // "allow_sell": true, // "allow_deposit": false, // "allow_withdraw": false, // "created_at": "2023-06-29T19:58:46Z", // "updated_at": "2023-10-30T20:25:01Z" // } // } // var result interface{} = this.SafeDict(response, "payment_method", map[string]interface{} {}) ch <- this.ParseDepositMethodId(result) return nil }() return ch } func (this *coinbase) ParseDepositMethodIds(ids interface{}, optionalArgs ...interface{}) interface{} { params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ { var id interface{} = this.Extend(this.ParseDepositMethodId(GetValue(ids, i)), params) AppendToArray(&result,id) } return result } func (this *coinbase) ParseDepositMethodId(depositId interface{}) interface{} { return map[string]interface{} { "info": depositId, "id": this.SafeString(depositId, "id"), "currency": this.SafeString(depositId, "currency"), "verified": this.SafeBool(depositId, "verified"), "tag": this.SafeString(depositId, "name"), } } /** * @method * @name coinbase#fetchConvertQuote * @description fetch a quote for converting from one currency to another * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_createconvertquote * @param {string} fromCode the currency that you want to sell and convert from * @param {string} toCode the currency that you want to buy and convert into * @param {float} [amount] how much you want to trade in units of the from currency * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {object} [params.trade_incentive_metadata] an object to fill in user incentive data * @param {string} [params.trade_incentive_metadata.user_incentive_id] the id of the incentive * @param {string} [params.trade_incentive_metadata.code_val] the code value of the incentive * @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure} */ func (this *coinbase) FetchConvertQuote(fromCode interface{}, toCode interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) amount := GetArg(optionalArgs, 0, nil) _ = amount params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes45078 := (<-this.LoadMarkets()) PanicOnError(retRes45078) var request interface{} = map[string]interface{} { "from_account": fromCode, "to_account": toCode, "amount": this.NumberToString(amount), } response:= (<-this.V3PrivatePostBrokerageConvertQuote(this.Extend(request, params))) PanicOnError(response) var data interface{} = this.SafeDict(response, "trade", map[string]interface{} {}) ch <- this.ParseConversion(data) return nil }() return ch } /** * @method * @name coinbase#createConvertTrade * @description convert from one currency to another * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_commitconverttrade * @param {string} id the id of the trade that you want to make * @param {string} fromCode the currency that you want to sell and convert from * @param {string} toCode the currency that you want to buy and convert into * @param {float} [amount] how much you want to trade in units of the from currency * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure} */ func (this *coinbase) CreateConvertTrade(id interface{}, fromCode interface{}, toCode interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) amount := GetArg(optionalArgs, 0, nil) _ = amount params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes45318 := (<-this.LoadMarkets()) PanicOnError(retRes45318) var request interface{} = map[string]interface{} { "trade_id": id, "from_account": fromCode, "to_account": toCode, } response:= (<-this.V3PrivatePostBrokerageConvertTradeTradeId(this.Extend(request, params))) PanicOnError(response) var data interface{} = this.SafeDict(response, "trade", map[string]interface{} {}) ch <- this.ParseConversion(data) return nil }() return ch } /** * @method * @name coinbase#fetchConvertTrade * @description fetch the data for a conversion trade * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getconverttrade * @param {string} id the id of the trade that you want to commit * @param {string} code the unified currency code that was converted from * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {strng} params.toCode the unified currency code that was converted into * @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure} */ func (this *coinbase) FetchConvertTrade(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes45548 := (<-this.LoadMarkets()) PanicOnError(retRes45548) if IsTrue(IsEqual(code, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchConvertTrade() requires a code argument"))) } var toCode interface{} = this.SafeString(params, "toCode") if IsTrue(IsEqual(toCode, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchConvertTrade() requires a toCode parameter"))) } params = this.Omit(params, "toCode") var request interface{} = map[string]interface{} { "trade_id": id, "from_account": code, "to_account": toCode, } response:= (<-this.V3PrivateGetBrokerageConvertTradeTradeId(this.Extend(request, params))) PanicOnError(response) var data interface{} = this.SafeDict(response, "trade", map[string]interface{} {}) ch <- this.ParseConversion(data) return nil }() return ch } func (this *coinbase) ParseConversion(conversion interface{}, optionalArgs ...interface{}) interface{} { fromCurrency := GetArg(optionalArgs, 0, nil) _ = fromCurrency toCurrency := GetArg(optionalArgs, 1, nil) _ = toCurrency var fromCoin interface{} = this.SafeString(conversion, "source_currency") var fromCode interface{} = this.SafeCurrencyCode(fromCoin, fromCurrency) var to interface{} = this.SafeString(conversion, "target_currency") var toCode interface{} = this.SafeCurrencyCode(to, toCurrency) var fromAmountStructure interface{} = this.SafeDict(conversion, "user_entered_amount") var feeStructure interface{} = this.SafeDict(conversion, "total_fee") var feeAmountStructure interface{} = this.SafeDict(feeStructure, "amount") return map[string]interface{} { "info": conversion, "timestamp": nil, "datetime": nil, "id": this.SafeString(conversion, "id"), "fromCurrency": fromCode, "fromAmount": this.SafeNumber(fromAmountStructure, "value"), "toCurrency": toCode, "toAmount": nil, "price": nil, "fee": this.SafeNumber(feeAmountStructure, "value"), } } /** * @method * @name coinbase#closePosition * @description *futures only* closes open positions for a market * @see https://coinbase-api.github.io/docs/#/en-us/swapV2/trade-api.html#One-Click%20Close%20All%20Positions * @param {string} symbol Unified CCXT market symbol * @param {string} [side] not used by coinbase * @param {object} [params] extra parameters specific to the coinbase api endpoint * @param {string} params.clientOrderId *mandatory* the client order id of the position to close * @param {float} [params.size] the size of the position to close, optional * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *coinbase) ClosePosition(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) side := GetArg(optionalArgs, 0, nil) _ = side params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes46088 := (<-this.LoadMarkets()) PanicOnError(retRes46088) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "future")) { panic(NotSupported(Add(this.Id, " closePosition() only supported for futures markets"))) } var clientOrderId interface{} = this.SafeString2(params, "client_order_id", "clientOrderId") params = this.Omit(params, "clientOrderId") var request interface{} = map[string]interface{} { "product_id": GetValue(market, "id"), } if IsTrue(IsEqual(clientOrderId, nil)) { panic(ArgumentsRequired(Add(this.Id, " closePosition() requires a clientOrderId parameter"))) } AddElementToObject(request, "client_order_id", clientOrderId) response:= (<-this.V3PrivatePostBrokerageOrdersClosePosition(this.Extend(request, params))) PanicOnError(response) var order interface{} = this.SafeDict(response, "success_response", map[string]interface{} {}) ch <- this.ParseOrder(order) return nil }() return ch } /** * @method * @name coinbase#fetchPositions * @description fetch all open positions * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfcmpositions * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getintxpositions * @param {string[]} [symbols] list of unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.portfolio] the portfolio UUID to fetch positions for * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *coinbase) FetchPositions(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbols := GetArg(optionalArgs, 0, nil) _ = symbols params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes46398 := (<-this.LoadMarkets()) PanicOnError(retRes46398) symbols = this.MarketSymbols(symbols) var market interface{} = nil if IsTrue(!IsEqual(symbols, nil)) { market = this.Market(GetValue(symbols, 0)) } var typeVar interface{} = nil typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchPositions", market, params); typeVar = GetValue(typeVarparamsVariable,0); params = GetValue(typeVarparamsVariable,1) var response interface{} = nil if IsTrue(IsEqual(typeVar, "future")) { response = (<-this.V3PrivateGetBrokerageCfmPositions(params)) PanicOnError(response) } else { var portfolio interface{} = nil portfolioparamsVariable := this.HandleOptionAndParams(params, "fetchPositions", "portfolio"); portfolio = GetValue(portfolioparamsVariable,0); params = GetValue(portfolioparamsVariable,1) if IsTrue(IsEqual(portfolio, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchPositions() requires a \"portfolio\" value in params (eg: dbcb91e7-2bc9-515), or set as exchange.options[\"portfolio\"]. You can get a list of portfolios with fetchPortfolios()"))) } var request interface{} = map[string]interface{} { "portfolio_uuid": portfolio, } response = (<-this.V3PrivateGetBrokerageIntxPositionsPortfolioUuid(this.Extend(request, params))) PanicOnError(response) } var positions interface{} = this.SafeList(response, "positions", []interface{}{}) ch <- this.ParsePositions(positions, symbols) return nil }() return ch } /** * @method * @name coinbase#fetchPosition * @description fetch data on a single open contract trade position * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getintxposition * @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfcmposition * @param {string} symbol unified market symbol of the market the position is held in, default is undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.product_id] *futures only* the product id of the position to fetch, required for futures markets only * @param {string} [params.portfolio] *perpetual/swaps only* the portfolio UUID to fetch the position for, required for perpetual/swaps markets only * @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *coinbase) FetchPosition(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes46788 := (<-this.LoadMarkets()) PanicOnError(retRes46788) var market interface{} = this.Market(symbol) var response interface{} = nil if IsTrue(GetValue(market, "future")) { var productId interface{} = this.SafeString(market, "product_id") if IsTrue(IsEqual(productId, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchPosition() requires a \"product_id\" in params"))) } var futureRequest interface{} = map[string]interface{} { "product_id": productId, } response = (<-this.V3PrivateGetBrokerageCfmPositionsProductId(this.Extend(futureRequest, params))) PanicOnError(response) } else { var portfolio interface{} = nil portfolioparamsVariable := this.HandleOptionAndParams(params, "fetchPositions", "portfolio"); portfolio = GetValue(portfolioparamsVariable,0); params = GetValue(portfolioparamsVariable,1) if IsTrue(IsEqual(portfolio, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchPosition() requires a \"portfolio\" value in params (eg: dbcb91e7-2bc9-515), or set as exchange.options[\"portfolio\"]. You can get a list of portfolios with fetchPortfolios()"))) } var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), "portfolio_uuid": portfolio, } response = (<-this.V3PrivateGetBrokerageIntxPositionsPortfolioUuidSymbol(this.Extend(request, params))) PanicOnError(response) } var position interface{} = this.SafeDict(response, "position", map[string]interface{} {}) ch <- this.ParsePosition(position, market) return nil }() return ch } func (this *coinbase) ParsePosition(position interface{}, optionalArgs ...interface{}) interface{} { // // { // "product_id": "1r4njf84-0-0", // "product_uuid": "cd34c18b-3665-4ed8-9305-3db277c49fc5", // "symbol": "ADA-PERP-INTX", // "vwap": { // "value": "0.6171", // "currency": "USDC" // }, // "position_side": "POSITION_SIDE_LONG", // "net_size": "20", // "buy_order_size": "0", // "sell_order_size": "0", // "im_contribution": "0.1", // "unrealized_pnl": { // "value": "0.074", // "currency": "USDC" // }, // "mark_price": { // "value": "0.6208", // "currency": "USDC" // }, // "liquidation_price": { // "value": "0", // "currency": "USDC" // }, // "leverage": "1", // "im_notional": { // "value": "12.342", // "currency": "USDC" // }, // "mm_notional": { // "value": "0.814572", // "currency": "USDC" // }, // "position_notional": { // "value": "12.342", // "currency": "USDC" // }, // "margin_type": "MARGIN_TYPE_CROSS", // "liquidation_buffer": "19.677828", // "liquidation_percentage": "4689.3506", // "portfolio_summary": { // "portfolio_uuid": "018ebd63-1f6d-7c8e-ada9-0761c5a2235f", // "collateral": "20.4184", // "position_notional": "12.342", // "open_position_notional": "12.342", // "pending_fees": "0", // "borrow": "0", // "accrued_interest": "0", // "rolling_debt": "0", // "portfolio_initial_margin": "0.1", // "portfolio_im_notional": { // "value": "12.342", // "currency": "USDC" // }, // "portfolio_maintenance_margin": "0.066", // "portfolio_mm_notional": { // "value": "0.814572", // "currency": "USDC" // }, // "liquidation_percentage": "4689.3506", // "liquidation_buffer": "19.677828", // "margin_type": "MARGIN_TYPE_CROSS", // "margin_flags": "PORTFOLIO_MARGIN_FLAGS_UNSPECIFIED", // "liquidation_status": "PORTFOLIO_LIQUIDATION_STATUS_NOT_LIQUIDATING", // "unrealized_pnl": { // "value": "0.074", // "currency": "USDC" // }, // "buying_power": { // "value": "8.1504", // "currency": "USDC" // }, // "total_balance": { // "value": "20.4924", // "currency": "USDC" // }, // "max_withdrawal": { // "value": "8.0764", // "currency": "USDC" // } // }, // "entry_vwap": { // "value": "0.6091", // "currency": "USDC" // } // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(position, "symbol", "") market = this.SafeMarket(marketId, market) var rawMargin interface{} = this.SafeString(position, "margin_type") var marginMode interface{} = nil if IsTrue(!IsEqual(rawMargin, nil)) { marginMode = Ternary(IsTrue((IsEqual(rawMargin, "MARGIN_TYPE_CROSS"))), "cross", "isolated") } var notionalObject interface{} = this.SafeDict(position, "position_notional", map[string]interface{} {}) var positionSide interface{} = this.SafeString(position, "position_side") var side interface{} = Ternary(IsTrue((IsEqual(positionSide, "POSITION_SIDE_LONG"))), "long", "short") var unrealizedPNLObject interface{} = this.SafeDict(position, "unrealized_pnl", map[string]interface{} {}) var liquidationPriceObject interface{} = this.SafeDict(position, "liquidation_price", map[string]interface{} {}) var liquidationPrice interface{} = this.SafeNumber(liquidationPriceObject, "value") var vwapObject interface{} = this.SafeDict(position, "vwap", map[string]interface{} {}) var summaryObject interface{} = this.SafeDict(position, "portfolio_summary", map[string]interface{} {}) return this.SafePosition(map[string]interface{} { "info": position, "id": this.SafeString(position, "product_id"), "symbol": this.SafeSymbol(marketId, market), "notional": this.SafeNumber(notionalObject, "value"), "marginMode": marginMode, "liquidationPrice": liquidationPrice, "entryPrice": this.SafeNumber(vwapObject, "value"), "unrealizedPnl": this.SafeNumber(unrealizedPNLObject, "value"), "realizedPnl": nil, "percentage": nil, "contracts": this.SafeNumber(position, "net_size"), "contractSize": GetValue(market, "contractSize"), "markPrice": nil, "lastPrice": nil, "side": side, "hedged": nil, "timestamp": nil, "datetime": nil, "lastUpdateTimestamp": nil, "maintenanceMargin": nil, "maintenanceMarginPercentage": nil, "collateral": this.SafeNumber(summaryObject, "collateral"), "initialMargin": nil, "initialMarginPercentage": nil, "leverage": this.SafeNumber(position, "leverage"), "marginRatio": nil, "stopLossPrice": nil, "takeProfitPrice": nil, }) } /** * @method * @name coinbase#fetchTradingFees * @see https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_gettransactionsummary/ * @description fetch the trading fees for multiple markets * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.type] 'spot' or 'swap' * @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols */ func (this *coinbase) FetchTradingFees(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes48538 := (<-this.LoadMarkets()) PanicOnError(retRes48538) var typeVar interface{} = nil typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchTradingFees", nil, params); typeVar = GetValue(typeVarparamsVariable,0); params = GetValue(typeVarparamsVariable,1) var isSpot interface{} = (IsEqual(typeVar, "spot")) var productType interface{} = Ternary(IsTrue(isSpot), "SPOT", "FUTURE") var request interface{} = map[string]interface{} { "product_type": productType, } response:= (<-this.V3PrivateGetBrokerageTransactionSummary(this.Extend(request, params))) PanicOnError(response) // // { // total_volume: '0', // total_fees: '0', // fee_tier: { // pricing_tier: 'Advanced 1', // usd_from: '0', // usd_to: '1000', // taker_fee_rate: '0.008', // maker_fee_rate: '0.006', // aop_from: '', // aop_to: '' // }, // margin_rate: null, // goods_and_services_tax: null, // advanced_trade_only_volume: '0', // advanced_trade_only_fees: '0', // coinbase_pro_volume: '0', // coinbase_pro_fees: '0', // total_balance: '', // has_promo_fee: false // } // var data interface{} = this.SafeDict(response, "fee_tier", map[string]interface{} {}) var taker_fee interface{} = this.SafeNumber(data, "taker_fee_rate") var marker_fee interface{} = this.SafeNumber(data, "maker_fee_rate") var result interface{} = map[string]interface{} {} for i := 0; IsLessThan(i, GetArrayLength(this.Symbols)); i++ { var symbol interface{} = GetValue(this.Symbols, i) var market interface{} = this.Market(symbol) if IsTrue(IsTrue((IsTrue(isSpot) && IsTrue(GetValue(market, "spot")))) || IsTrue((!IsTrue(isSpot) && !IsTrue(GetValue(market, "spot"))))) { AddElementToObject(result, symbol, map[string]interface{} { "info": response, "symbol": symbol, "maker": taker_fee, "taker": marker_fee, "percentage": true, }) } } ch <- result return nil }() return ch } func (this *coinbase) CreateAuthToken(seconds interface{}, optionalArgs ...interface{}) interface{} { // it may not work for v2 method := GetArg(optionalArgs, 0, nil) _ = method url := GetArg(optionalArgs, 1, nil) _ = url var uri interface{} = nil if IsTrue(!IsEqual(url, nil)) { uri = Add(Add(method, " "), Replace(url, "https://", "")) var quesPos interface{} = GetIndexOf(uri, "?") // Due to we use mb_strpos, quesPos could be false in php. In that case, the quesPos >= 0 is true // Also it's not possible that the question mark is first character, only check > 0 here. if IsTrue(IsGreaterThan(quesPos, 0)) { uri = Slice(uri, 0, quesPos) } } var nonce interface{} = this.RandomBytes(16) var request interface{} = map[string]interface{} { "aud": []interface{}{"retail_rest_api_proxy"}, "iss": "coinbase-cloud", "nbf": seconds, "exp": Add(seconds, 120), "sub": this.ApiKey, "iat": seconds, } if IsTrue(!IsEqual(uri, nil)) { AddElementToObject(request, "uri", uri) } var token interface{} = Jwt(request, this.Encode(this.Secret), sha256, false, map[string]interface{} { "kid": this.ApiKey, "nonce": nonce, "alg": "ES256", }) return token } func (this *coinbase) Nonce() interface{} { return Subtract(this.Milliseconds(), GetValue(this.Options, "timeDifference")) } func (this *coinbase) Sign(path interface{}, optionalArgs ...interface{}) interface{} { api := GetArg(optionalArgs, 0, []interface{}{}) _ = api method := GetArg(optionalArgs, 1, "GET") _ = method params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params headers := GetArg(optionalArgs, 3, nil) _ = headers body := GetArg(optionalArgs, 4, nil) _ = body var version interface{} = GetValue(api, 0) var signed interface{} = IsEqual(GetValue(api, 1), "private") var isV3 interface{} = IsEqual(version, "v3") var pathPart interface{} = Ternary(IsTrue((isV3)), "api/v3", "v2") var fullPath interface{} = Add(Add(Add("/", pathPart), "/"), this.ImplodeParams(path, params)) var query interface{} = this.Omit(params, this.ExtractParams(path)) var savedPath interface{} = fullPath if IsTrue(IsEqual(method, "GET")) { if IsTrue(GetArrayLength(ObjectKeys(query))) { fullPath = Add(fullPath, Add("?", this.UrlencodeWithArrayRepeat(query))) } } var url interface{} = Add(GetValue(GetValue(this.Urls, "api"), "rest"), fullPath) if IsTrue(signed) { var authorization interface{} = this.SafeString(this.Headers, "Authorization") var authorizationString interface{} = nil if IsTrue(!IsEqual(authorization, nil)) { authorizationString = authorization } else if IsTrue(IsTrue(this.Token) && !IsTrue(this.CheckRequiredCredentials(false))) { authorizationString = Add("Bearer ", this.Token) } else { this.CheckRequiredCredentials() var seconds interface{} = this.Seconds() var payload interface{} = "" if IsTrue(!IsEqual(method, "GET")) { if IsTrue(GetArrayLength(ObjectKeys(query))) { body = this.Json(query) payload = body } } else { if !IsTrue(isV3) { if IsTrue(GetArrayLength(ObjectKeys(query))) { payload = Add(payload, Add("?", this.Urlencode(query))) } } } // v3: 'GET' doesn't need payload in the signature. inside url is enough // https://docs.cloud.coinbase.com/advanced-trade/docs/auth#example-request // v2: 'GET' require payload in the signature // https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-key-authentication var isCloudAPiKey interface{} = IsTrue((IsGreaterThanOrEqual(GetIndexOf(this.ApiKey, "organizations/"), 0))) || IsTrue((StartsWith(this.Secret, "-----BEGIN"))) if IsTrue(isCloudAPiKey) { if IsTrue(StartsWith(this.ApiKey, "-----BEGIN")) { panic(ArgumentsRequired(Add(this.Id, " apiKey should contain the name (eg: organizations/3b910e93....) and not the public key"))) } // // it may not work for v2 // let uri = method + ' ' + url.replace ('https://', ''); // const quesPos = uri.indexOf ('?'); // // Due to we use mb_strpos, quesPos could be false in php. In that case, the quesPos >= 0 is true // // Also it's not possible that the question mark is first character, only check > 0 here. // if (quesPos > 0) { // uri = uri.slice (0, quesPos); // } // const nonce = this.randomBytes (16); // const request: Dict = { // 'aud': [ 'retail_rest_api_proxy' ], // 'iss': 'coinbase-cloud', // 'nbf': seconds, // 'exp': seconds + 120, // 'sub': this.apiKey, // 'uri': uri, // 'iat': seconds, // }; var token interface{} = this.CreateAuthToken(seconds, method, url) // const token = jwt (request, this.encode (this.secret), sha256, false, { 'kid': this.apiKey, 'nonce': nonce, 'alg': 'ES256' }); authorizationString = Add("Bearer ", token) } else { var nonce interface{} = this.Nonce() var timestamp interface{} = this.ParseToInt(Divide(nonce, 1000)) var timestampString interface{} = ToString(timestamp) var auth interface{} = Add(Add(Add(timestampString, method), savedPath), payload) var signature interface{} = this.Hmac(this.Encode(auth), this.Encode(this.Secret), sha256) headers = map[string]interface{} { "CB-ACCESS-KEY": this.ApiKey, "CB-ACCESS-SIGN": signature, "CB-ACCESS-TIMESTAMP": timestampString, "Content-Type": "application/json", } } } if IsTrue(!IsEqual(authorizationString, nil)) { headers = map[string]interface{} { "Authorization": authorizationString, "Content-Type": "application/json", } if IsTrue(!IsEqual(method, "GET")) { if IsTrue(GetArrayLength(ObjectKeys(query))) { body = this.Json(query) } } } } return map[string]interface{} { "url": url, "method": method, "body": body, "headers": headers, } } func (this *coinbase) HandleErrors(code interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} { if IsTrue(IsEqual(response, nil)) { return nil // fallback to default error handler } var feedback interface{} = Add(Add(this.Id, " "), body) // // {"error": "invalid_request", "error_description": "The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed."} // // or // // { // "errors": [ // { // "id": "not_found", // "message": "Not found" // } // ] // } // or // { // "error": "UNKNOWN_FAILURE_REASON", // "message": "", // "error_details": "", // "preview_failure_reason": "PREVIEW_STOP_PRICE_BELOW_LAST_TRADE_PRICE" // } // var errorCode interface{} = this.SafeString(response, "error") if IsTrue(!IsEqual(errorCode, nil)) { var errorMessage interface{} = this.SafeString2(response, "error_description", "preview_failure_reason") this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), errorCode, feedback) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), errorMessage, feedback) panic(ExchangeError(feedback)) } var errors interface{} = this.SafeList(response, "errors") if IsTrue(!IsEqual(errors, nil)) { if IsTrue(IsArray(errors)) { var numErrors interface{} = GetArrayLength(errors) if IsTrue(IsGreaterThan(numErrors, 0)) { errorCode = this.SafeString(GetValue(errors, 0), "id") var errorMessage interface{} = this.SafeString(GetValue(errors, 0), "message") if IsTrue(!IsEqual(errorCode, nil)) { this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), errorCode, feedback) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), errorMessage, feedback) panic(ExchangeError(feedback)) } } } } var advancedTrade interface{} = GetValue(this.Options, "advanced") if IsTrue(!IsTrue((InOp(response, "data"))) && IsTrue((!IsTrue(advancedTrade)))) { panic(ExchangeError(Add(Add(this.Id, " failed due to a malformed response "), this.Json(response)))) } return nil } func (this *coinbase) Init(userConfig map[string]interface{}) { this.Exchange = Exchange{} this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this) this.Exchange.DerivedExchange = this }