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 hyperliquid struct { Exchange } func NewHyperliquidCore() hyperliquid { p := hyperliquid{} setDefaults(&p) return p } func (this *hyperliquid) Describe() interface{} { return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} { "id": "hyperliquid", "name": "Hyperliquid", "countries": []interface{}{}, "version": "v1", "rateLimit": 50, "certified": true, "pro": true, "dex": true, "has": map[string]interface{} { "CORS": nil, "spot": true, "margin": false, "swap": true, "future": true, "option": false, "addMargin": true, "borrowCrossMargin": false, "borrowIsolatedMargin": false, "cancelAllOrders": false, "cancelAllOrdersAfter": true, "cancelOrder": true, "cancelOrders": true, "cancelOrdersForSymbols": true, "closeAllPositions": false, "closePosition": false, "createMarketBuyOrderWithCost": false, "createMarketOrderWithCost": false, "createMarketSellOrderWithCost": false, "createOrder": true, "createOrders": true, "createReduceOnlyOrder": true, "createStopOrder": true, "createTriggerOrder": true, "editOrder": true, "fetchAccounts": false, "fetchBalance": true, "fetchBorrowInterest": false, "fetchBorrowRateHistories": false, "fetchBorrowRateHistory": false, "fetchCanceledAndClosedOrders": true, "fetchCanceledOrders": true, "fetchClosedOrders": true, "fetchCrossBorrowRate": false, "fetchCrossBorrowRates": false, "fetchCurrencies": true, "fetchDepositAddress": false, "fetchDepositAddresses": false, "fetchDeposits": true, "fetchDepositWithdrawFee": "emulated", "fetchDepositWithdrawFees": false, "fetchFundingHistory": true, "fetchFundingRate": false, "fetchFundingRateHistory": true, "fetchFundingRates": true, "fetchIndexOHLCV": false, "fetchIsolatedBorrowRate": false, "fetchIsolatedBorrowRates": false, "fetchLedger": true, "fetchLeverage": false, "fetchLeverageTiers": false, "fetchLiquidations": false, "fetchMarginMode": nil, "fetchMarketLeverageTiers": false, "fetchMarkets": true, "fetchMarkOHLCV": false, "fetchMyLiquidations": false, "fetchMyTrades": true, "fetchOHLCV": true, "fetchOpenInterest": true, "fetchOpenInterestHistory": false, "fetchOpenInterests": true, "fetchOpenOrders": true, "fetchOrder": true, "fetchOrderBook": true, "fetchOrders": true, "fetchOrderTrades": false, "fetchPosition": true, "fetchPositionMode": false, "fetchPositions": true, "fetchPositionsRisk": false, "fetchPremiumIndexOHLCV": false, "fetchTicker": "emulated", "fetchTickers": true, "fetchTime": false, "fetchTrades": true, "fetchTradingFee": true, "fetchTradingFees": false, "fetchTransfer": false, "fetchTransfers": false, "fetchWithdrawal": false, "fetchWithdrawals": true, "reduceMargin": true, "repayCrossMargin": false, "repayIsolatedMargin": false, "sandbox": true, "setLeverage": true, "setMarginMode": true, "setPositionMode": false, "transfer": true, "withdraw": true, }, "timeframes": map[string]interface{} { "1m": "1m", "3m": "3m", "5m": "5m", "15m": "15m", "30m": "30m", "1h": "1h", "2h": "2h", "4h": "4h", "8h": "8h", "12h": "12h", "1d": "1d", "3d": "3d", "1w": "1w", "1M": "1M", }, "hostname": "hyperliquid.xyz", "urls": map[string]interface{} { "logo": "https://github.com/ccxt/ccxt/assets/43336371/b371bc6c-4a8c-489f-87f4-20a913dd8d4b", "api": map[string]interface{} { "public": "https://api.{hostname}", "private": "https://api.{hostname}", }, "test": map[string]interface{} { "public": "https://api.hyperliquid-testnet.xyz", "private": "https://api.hyperliquid-testnet.xyz", }, "www": "https://hyperliquid.xyz", "doc": "https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api", "fees": "https://hyperliquid.gitbook.io/hyperliquid-docs/trading/fees", "referral": "https://app.hyperliquid.xyz/", }, "api": map[string]interface{} { "public": map[string]interface{} { "post": map[string]interface{} { "info": map[string]interface{} { "cost": 20, "byType": map[string]interface{} { "l2Book": 2, "allMids": 2, "clearinghouseState": 2, "orderStatus": 2, "spotClearinghouseState": 2, "exchangeStatus": 2, }, }, }, }, "private": map[string]interface{} { "post": map[string]interface{} { "exchange": 1, }, }, }, "fees": map[string]interface{} { "swap": map[string]interface{} { "taker": this.ParseNumber("0.00035"), "maker": this.ParseNumber("0.0001"), }, "spot": map[string]interface{} { "taker": this.ParseNumber("0.00035"), "maker": this.ParseNumber("0.0001"), }, }, "requiredCredentials": map[string]interface{} { "apiKey": false, "secret": false, "walletAddress": true, "privateKey": true, }, "exceptions": map[string]interface{} { "exact": map[string]interface{} {}, "broad": map[string]interface{} { "Price must be divisible by tick size.": InvalidOrder, "Order must have minimum value of $10": InvalidOrder, "Insufficient margin to place order.": InsufficientFunds, "Reduce only order would increase position.": InvalidOrder, "Post only order would have immediately matched,": InvalidOrder, "Order could not immediately match against any resting orders.": InvalidOrder, "Invalid TP/SL price.": InvalidOrder, "No liquidity available for market order.": InvalidOrder, "Order was never placed, already canceled, or filled.": OrderNotFound, "User or API Wallet ": InvalidOrder, "Order has invalid size": InvalidOrder, "Order price cannot be more than 80% away from the reference price": InvalidOrder, "Order has zero size.": InvalidOrder, "Insufficient spot balance asset": InsufficientFunds, "Insufficient balance for withdrawal": InsufficientFunds, "Insufficient balance for token transfer": InsufficientFunds, }, }, "precisionMode": TICK_SIZE, "commonCurrencies": map[string]interface{} {}, "options": map[string]interface{} { "defaultType": "swap", "sandboxMode": false, "defaultSlippage": 0.05, "zeroAddress": "0x0000000000000000000000000000000000000000", }, "features": map[string]interface{} { "default": map[string]interface{} { "sandbox": true, "createOrder": map[string]interface{} { "marginMode": false, "triggerPrice": false, "triggerPriceType": nil, "triggerDirection": false, "stopLossPrice": false, "takeProfitPrice": false, "attachedStopLossTakeProfit": nil, "timeInForce": map[string]interface{} { "IOC": true, "FOK": false, "PO": true, "GTD": false, }, "hedged": false, "trailing": false, "leverage": false, "marketBuyByCost": false, "marketBuyRequiresPrice": false, "selfTradePrevention": false, "iceberg": false, }, "createOrders": map[string]interface{} { "max": 1000, }, "fetchMyTrades": map[string]interface{} { "marginMode": false, "limit": 2000, "daysBack": nil, "untilDays": nil, "symbolRequired": true, }, "fetchOrder": map[string]interface{} { "marginMode": false, "trigger": false, "trailing": false, "symbolRequired": true, }, "fetchOpenOrders": map[string]interface{} { "marginMode": false, "limit": 2000, "trigger": false, "trailing": false, "symbolRequired": true, }, "fetchOrders": map[string]interface{} { "marginMode": false, "limit": 2000, "daysBack": nil, "untilDays": nil, "trigger": false, "trailing": false, "symbolRequired": true, }, "fetchClosedOrders": map[string]interface{} { "marginMode": false, "limit": 2000, "daysBack": nil, "daysBackCanceled": nil, "untilDays": nil, "trigger": false, "trailing": false, "symbolRequired": true, }, "fetchOHLCV": map[string]interface{} { "limit": 5000, }, }, "spot": map[string]interface{} { "extends": "default", }, "forPerps": map[string]interface{} { "extends": "default", "createOrder": map[string]interface{} { "stopLossPrice": true, "takeProfitPrice": true, "attachedStopLossTakeProfit": nil, }, }, "swap": map[string]interface{} { "linear": map[string]interface{} { "extends": "forPerps", }, "inverse": map[string]interface{} { "extends": "forPerps", }, }, "future": map[string]interface{} { "linear": map[string]interface{} { "extends": "forPerps", }, "inverse": map[string]interface{} { "extends": "forPerps", }, }, }, }) } func (this *hyperliquid) SetSandboxMode(enabled interface{}) { this.Exchange.SetSandboxMode(enabled) AddElementToObject(this.Options, "sandboxMode", enabled) } /** * @method * @name hyperliquid#fetchCurrencies * @description fetches all available currencies on an exchange * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-perpetuals-metadata * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an associative dictionary of currencies */ func (this *hyperliquid) 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 var request interface{} = map[string]interface{} { "type": "meta", } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // [ // { // "universe": [ // { // "maxLeverage": 50, // "name": "SOL", // "onlyIsolated": false, // "szDecimals": 2 // } // ] // } // ] // var meta interface{} = this.SafeList(response, "universe", []interface{}{}) var result interface{} = map[string]interface{} {} for i := 0; IsLessThan(i, GetArrayLength(meta)); i++ { var data interface{} = this.SafeDict(meta, i, map[string]interface{} {}) var id interface{} = i var name interface{} = this.SafeString(data, "name") var code interface{} = this.SafeCurrencyCode(name) AddElementToObject(result, code, map[string]interface{} { "id": id, "name": name, "code": code, "precision": nil, "info": data, "active": nil, "deposit": nil, "withdraw": nil, "networks": nil, "fee": nil, "limits": map[string]interface{} { "amount": map[string]interface{} { "min": nil, "max": nil, }, "withdraw": map[string]interface{} { "min": nil, "max": nil, }, }, }) } ch <- result return nil }() return ch } /** * @method * @name hyperliquid#fetchMarkets * @description retrieves data on all markets for hyperliquid * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-perpetuals-asset-contexts-includes-mark-price-current-funding-open-interest-etc * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/spot#retrieve-spot-asset-contexts * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ func (this *hyperliquid) 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 var rawPromises interface{} = []interface{}{this.FetchSwapMarkets(params), this.FetchSpotMarkets(params)} promises:= (<-promiseAll(rawPromises)) PanicOnError(promises) var swapMarkets interface{} = GetValue(promises, 0) var spotMarkets interface{} = GetValue(promises, 1) ch <- this.ArrayConcat(swapMarkets, spotMarkets) return nil }() return ch } /** * @method * @name hyperliquid#fetchSwapMarkets * @description retrieves data on all swap markets for hyperliquid * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-perpetuals-asset-contexts-includes-mark-price-current-funding-open-interest-etc * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ func (this *hyperliquid) FetchSwapMarkets(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 request interface{} = map[string]interface{} { "type": "metaAndAssetCtxs", } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // [ // { // "universe": [ // { // "maxLeverage": 50, // "name": "SOL", // "onlyIsolated": false, // "szDecimals": 2 // } // ] // }, // [ // { // "dayNtlVlm": "9450588.2273", // "funding": "0.0000198", // "impactPxs": [ // "108.04", // "108.06" // ], // "markPx": "108.04", // "midPx": "108.05", // "openInterest": "10764.48", // "oraclePx": "107.99", // "premium": "0.00055561", // "prevDayPx": "111.81" // } // ] // ] // // var meta interface{} = this.SafeDict(response, 0, map[string]interface{} {}) var universe interface{} = this.SafeList(meta, "universe", []interface{}{}) var assetCtxs interface{} = this.SafeList(response, 1, []interface{}{}) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(universe)); i++ { var data interface{} = this.Extend(this.SafeDict(universe, i, map[string]interface{} {}), this.SafeDict(assetCtxs, i, map[string]interface{} {})) AddElementToObject(data, "baseId", i) AppendToArray(&result,data) } ch <- this.ParseMarkets(result) return nil }() return ch } /** * @method * @name hyperliquid#calculatePricePrecision * @description Helper function to calculate the Hyperliquid DECIMAL_PLACES price precision * @param {float} price the price to use in the calculation * @param {int} amountPrecision the amountPrecision to use in the calculation * @param {int} maxDecimals the maxDecimals to use in the calculation * @returns {int} The calculated price precision */ func (this *hyperliquid) CalculatePricePrecision(price interface{}, amountPrecision interface{}, maxDecimals interface{}) interface{} { var pricePrecision interface{} = 0 var priceStr interface{} = this.NumberToString(price) if IsTrue(IsEqual(priceStr, nil)) { return 0 } var priceSplitted interface{} = Split(priceStr, ".") if IsTrue(Precise.StringEq(priceStr, "0")) { // Significant digits is always 5 in this case var significantDigits interface{} = 5 // Integer digits is always 0 in this case (0 doesn't count) var integerDigits interface{} = 0 // Calculate the price precision pricePrecision = mathMin(Subtract(maxDecimals, amountPrecision), Subtract(significantDigits, integerDigits)) } else if IsTrue(IsTrue(Precise.StringGt(priceStr, "0")) && IsTrue(Precise.StringLt(priceStr, "1"))) { // Significant digits, always 5 in this case var significantDigits interface{} = 5 // Get the part after the decimal separator var decimalPart interface{} = this.SafeString(priceSplitted, 1, "") // Count the number of leading zeros in the decimal part var leadingZeros interface{} = 0 for IsTrue((IsLessThanOrEqual(leadingZeros, GetLength(decimalPart)))) && IsTrue((IsEqual(GetValue(decimalPart, leadingZeros), "0"))) { leadingZeros = Add(leadingZeros, 1) } // Calculate price precision based on leading zeros and significant digits pricePrecision = Add(leadingZeros, significantDigits) // Calculate the price precision based on maxDecimals - szDecimals and the calculated price precision from the previous step pricePrecision = mathMin(Subtract(maxDecimals, amountPrecision), pricePrecision) } else { // Count the numbers before the decimal separator var integerPart interface{} = this.SafeString(priceSplitted, 0, "") // Get significant digits, take the max() of 5 and the integer digits count var significantDigits interface{} = mathMax(5, GetLength(integerPart)) // Calculate price precision based on maxDecimals - szDecimals and significantDigits - integerPart.length pricePrecision = mathMin(Subtract(maxDecimals, amountPrecision), Subtract(significantDigits, GetLength(integerPart))) } return this.ParseToInt(pricePrecision) } /** * @method * @name hyperliquid#fetchSpotMarkets * @description retrieves data on all spot markets for hyperliquid * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/spot#retrieve-spot-asset-contexts * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ func (this *hyperliquid) FetchSpotMarkets(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 request interface{} = map[string]interface{} { "type": "spotMetaAndAssetCtxs", } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // [ // { // "tokens": [ // { // "name": "USDC", // "szDecimals": 8, // "weiDecimals" 8, // "index": 0, // "tokenId": "0x6d1e7cde53ba9467b783cb7c530ce054", // "isCanonical": true, // "evmContract":null, // "fullName":null // }, // { // "name": "PURR", // "szDecimals": 0, // "weiDecimals": 5, // "index": 1, // "tokenId": "0xc1fb593aeffbeb02f85e0308e9956a90", // "isCanonical": true, // "evmContract":null, // "fullName":null // } // ], // "universe": [ // { // "name": "PURR/USDC", // "tokens": [1, 0], // "index": 0, // "isCanonical": true // } // ] // }, // [ // { // "dayNtlVlm":"8906.0", // "markPx":"0.14", // "midPx":"0.209265", // "prevDayPx":"0.20432" // } // ] // ] // var first interface{} = this.SafeDict(response, 0, map[string]interface{} {}) var second interface{} = this.SafeList(response, 1, []interface{}{}) var meta interface{} = this.SafeList(first, "universe", []interface{}{}) var tokens interface{} = this.SafeList(first, "tokens", []interface{}{}) var markets interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(meta)); i++ { var market interface{} = this.SafeDict(meta, i, map[string]interface{} {}) var index interface{} = this.SafeInteger(market, "index") var extraData interface{} = this.SafeDict(second, index, map[string]interface{} {}) var marketName interface{} = this.SafeString(market, "name") // if (marketName.indexOf ('/') < 0) { // // there are some weird spot markets in testnet, eg @2 // continue; // } // const marketParts = marketName.split ('/'); // const baseName = this.safeString (marketParts, 0); // const quoteId = this.safeString (marketParts, 1); var fees interface{} = this.SafeDict(this.Fees, "spot", map[string]interface{} {}) var taker interface{} = this.SafeNumber(fees, "taker") var maker interface{} = this.SafeNumber(fees, "maker") var tokensPos interface{} = this.SafeList(market, "tokens", []interface{}{}) var baseTokenPos interface{} = this.SafeInteger(tokensPos, 0) var quoteTokenPos interface{} = this.SafeInteger(tokensPos, 1) var baseTokenInfo interface{} = this.SafeDict(tokens, baseTokenPos, map[string]interface{} {}) var quoteTokenInfo interface{} = this.SafeDict(tokens, quoteTokenPos, map[string]interface{} {}) var baseName interface{} = this.SafeString(baseTokenInfo, "name") var quoteId interface{} = this.SafeString(quoteTokenInfo, "name") var base interface{} = this.SafeCurrencyCode(baseName) var quote interface{} = this.SafeCurrencyCode(quoteId) var symbol interface{} = Add(Add(base, "/"), quote) var innerBaseTokenInfo interface{} = this.SafeDict(baseTokenInfo, "spec", baseTokenInfo) // const innerQuoteTokenInfo = this.safeDict (quoteTokenInfo, 'spec', quoteTokenInfo); var amountPrecisionStr interface{} = this.SafeString(innerBaseTokenInfo, "szDecimals") var amountPrecision interface{} = ParseInt(amountPrecisionStr) var price interface{} = this.SafeNumber(extraData, "midPx") var pricePrecision interface{} = 0 if IsTrue(!IsEqual(price, nil)) { pricePrecision = this.CalculatePricePrecision(price, amountPrecision, 8) } var pricePrecisionStr interface{} = this.NumberToString(pricePrecision) // const quotePrecision = this.parseNumber (this.parsePrecision (this.safeString (innerQuoteTokenInfo, 'szDecimals'))); var baseId interface{} = this.NumberToString(Add(index, 10000)) AppendToArray(&markets,this.SafeMarketStructure(map[string]interface{} { "id": marketName, "symbol": symbol, "base": base, "quote": quote, "settle": nil, "baseId": baseId, "quoteId": quoteId, "settleId": nil, "type": "spot", "spot": true, "subType": nil, "margin": nil, "swap": false, "future": false, "option": false, "active": true, "contract": false, "linear": nil, "inverse": nil, "taker": taker, "maker": maker, "contractSize": nil, "expiry": nil, "expiryDatetime": nil, "strike": nil, "optionType": nil, "precision": map[string]interface{} { "amount": this.ParseNumber(this.ParsePrecision(amountPrecisionStr)), "price": this.ParseNumber(this.ParsePrecision(pricePrecisionStr)), }, "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.ParseNumber("10"), "max": nil, }, }, "created": nil, "info": this.Extend(extraData, market), })) } ch <- markets return nil }() return ch } func (this *hyperliquid) ParseMarket(market interface{}) interface{} { // // { // "maxLeverage": "50", // "name": "ETH", // "onlyIsolated": false, // "szDecimals": "4", // "dayNtlVlm": "1709813.11535", // "funding": "0.00004807", // "impactPxs": [ // "2369.3", // "2369.6" // ], // "markPx": "2369.6", // "midPx": "2369.45", // "openInterest": "1815.4712", // "oraclePx": "2367.3", // "premium": "0.00090821", // "prevDayPx": "2381.5" // } // var quoteId interface{} = "USDC" var base interface{} = this.SafeString(market, "name") var quote interface{} = this.SafeCurrencyCode(quoteId) var baseId interface{} = this.SafeString(market, "baseId") var settleId interface{} = "USDC" var settle interface{} = this.SafeCurrencyCode(settleId) var symbol interface{} = Add(Add(base, "/"), quote) var contract interface{} = true var swap interface{} = true if IsTrue(contract) { if IsTrue(swap) { symbol = Add(Add(symbol, ":"), settle) } } var fees interface{} = this.SafeDict(this.Fees, "swap", map[string]interface{} {}) var taker interface{} = this.SafeNumber(fees, "taker") var maker interface{} = this.SafeNumber(fees, "maker") var amountPrecisionStr interface{} = this.SafeString(market, "szDecimals") var amountPrecision interface{} = ParseInt(amountPrecisionStr) var price interface{} = this.SafeNumber(market, "markPx", 0) var pricePrecision interface{} = 0 if IsTrue(!IsEqual(price, nil)) { pricePrecision = this.CalculatePricePrecision(price, amountPrecision, 6) } var pricePrecisionStr interface{} = this.NumberToString(pricePrecision) var isDelisted interface{} = this.SafeBool(market, "isDelisted") var active interface{} = true if IsTrue(!IsEqual(isDelisted, nil)) { active = !IsTrue(isDelisted) } return this.SafeMarketStructure(map[string]interface{} { "id": baseId, "symbol": symbol, "base": base, "quote": quote, "settle": settle, "baseId": baseId, "quoteId": quoteId, "settleId": settleId, "type": "swap", "spot": false, "margin": nil, "swap": swap, "future": false, "option": false, "active": active, "contract": contract, "linear": true, "inverse": false, "taker": taker, "maker": maker, "contractSize": this.ParseNumber("1"), "expiry": nil, "expiryDatetime": nil, "strike": nil, "optionType": nil, "precision": map[string]interface{} { "amount": this.ParseNumber(this.ParsePrecision(amountPrecisionStr)), "price": this.ParseNumber(this.ParsePrecision(pricePrecisionStr)), }, "limits": map[string]interface{} { "leverage": map[string]interface{} { "min": nil, "max": this.SafeInteger(market, "maxLeverage"), }, "amount": map[string]interface{} { "min": nil, "max": nil, }, "price": map[string]interface{} { "min": nil, "max": nil, }, "cost": map[string]interface{} { "min": this.ParseNumber("10"), "max": nil, }, }, "created": nil, "info": market, }) } /** * @method * @name hyperliquid#fetchBalance * @description query for balance and get the amount of funds available for trading or funds locked in orders * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/spot#retrieve-a-users-token-balances * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-users-perpetuals-account-summary * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.user] user address, will default to this.walletAddress if not provided * @param {string} [params.type] wallet type, ['spot', 'swap'], defaults to swap * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure} */ func (this *hyperliquid) 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 var userAddress interface{} = nil userAddressparamsVariable := this.HandlePublicAddress("fetchBalance", params); userAddress = GetValue(userAddressparamsVariable,0); params = GetValue(userAddressparamsVariable,1) var typeVar interface{} = nil typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchBalance", nil, params); typeVar = GetValue(typeVarparamsVariable,0); params = GetValue(typeVarparamsVariable,1) var isSpot interface{} = (IsEqual(typeVar, "spot")) var reqType interface{} = Ternary(IsTrue((isSpot)), "spotClearinghouseState", "clearinghouseState") var request interface{} = map[string]interface{} { "type": reqType, "user": userAddress, } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // { // "assetPositions": [], // "crossMaintenanceMarginUsed": "0.0", // "crossMarginSummary": { // "accountValue": "100.0", // "totalMarginUsed": "0.0", // "totalNtlPos": "0.0", // "totalRawUsd": "100.0" // }, // "marginSummary": { // "accountValue": "100.0", // "totalMarginUsed": "0.0", // "totalNtlPos": "0.0", // "totalRawUsd": "100.0" // }, // "time": "1704261007014", // "withdrawable": "100.0" // } // spot // // { // "balances":[ // { // "coin":"USDC", // "hold":"0.0", // "total":"1481.844" // }, // { // "coin":"PURR", // "hold":"0.0", // "total":"999.65004" // } // } // var balances interface{} = this.SafeList(response, "balances") if IsTrue(!IsEqual(balances, nil)) { var spotBalances interface{} = map[string]interface{} { "info": response, } for i := 0; IsLessThan(i, GetArrayLength(balances)); i++ { var balance interface{} = GetValue(balances, i) var code interface{} = this.SafeCurrencyCode(this.SafeString(balance, "coin")) var account interface{} = this.Account() var total interface{} = this.SafeString(balance, "total") var used interface{} = this.SafeString(balance, "hold") AddElementToObject(account, "total", total) AddElementToObject(account, "used", used) AddElementToObject(spotBalances, code, account) } ch <- this.SafeBalance(spotBalances) return nil } var data interface{} = this.SafeDict(response, "marginSummary", map[string]interface{} {}) var result interface{} = map[string]interface{} { "info": response, "USDC": map[string]interface{} { "total": this.SafeNumber(data, "accountValue"), "free": this.SafeNumber(response, "withdrawable"), }, } var timestamp interface{} = this.SafeInteger(response, "time") AddElementToObject(result, "timestamp", timestamp) AddElementToObject(result, "datetime", this.Iso8601(timestamp)) ch <- this.SafeBalance(result) return nil }() return ch } /** * @method * @name hyperliquid#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#l2-book-snapshot * @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 * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols */ func (this *hyperliquid) 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 retRes8748 := (<-this.LoadMarkets()) PanicOnError(retRes8748) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "type": "l2Book", "coin": Ternary(IsTrue(GetValue(market, "swap")), GetValue(market, "base"), GetValue(market, "id")), } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // { // "coin": "ETH", // "levels": [ // [ // { // "n": "2", // "px": "2216.2", // "sz": "74.0637" // } // ], // [ // { // "n": "2", // "px": "2216.5", // "sz": "70.5893" // } // ] // ], // "time": "1704290104840" // } // var data interface{} = this.SafeList(response, "levels", []interface{}{}) var result interface{} = map[string]interface{} { "bids": this.SafeList(data, 0, []interface{}{}), "asks": this.SafeList(data, 1, []interface{}{}), } var timestamp interface{} = this.SafeInteger(response, "time") ch <- this.ParseOrderBook(result, GetValue(market, "symbol"), timestamp, "bids", "asks", "px", "sz") return nil }() return ch } /** * @method * @name hyperliquid#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-perpetuals-asset-contexts-includes-mark-price-current-funding-open-interest-etc * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/spot#retrieve-spot-asset-contexts * @param {string[]} [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 {string} [params.type] 'spot' or 'swap', by default fetches both * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ func (this *hyperliquid) 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 retRes9248 := (<-this.LoadMarkets()) PanicOnError(retRes9248) symbols = this.MarketSymbols(symbols) // at this stage, to get tickers data, we use fetchMarkets endpoints var response interface{} = []interface{}{} var typeVar interface{} = this.SafeString(params, "type") params = this.Omit(params, "type") if IsTrue(IsEqual(typeVar, "spot")) { response = (<-this.FetchSpotMarkets(params)) PanicOnError(response) } else if IsTrue(IsEqual(typeVar, "swap")) { response = (<-this.FetchSwapMarkets(params)) PanicOnError(response) } else { response = (<-this.FetchMarkets(params)) PanicOnError(response) } // same response as under "fetchMarkets" var result interface{} = map[string]interface{} {} for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { var market interface{} = GetValue(response, i) var info interface{} = GetValue(market, "info") var ticker interface{} = this.ParseTicker(info, market) var symbol interface{} = this.SafeString(ticker, "symbol") AddElementToObject(result, symbol, ticker) } ch <- this.FilterByArrayTickers(result, "symbol", symbols) return nil }() return ch } /** * @method * @name hyperliquid#fetchFundingRates * @description retrieves data on all swap markets for hyperliquid * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-perpetuals-asset-contexts-includes-mark-price-current-funding-open-interest-etc * @param {string[]} [symbols] list of unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ func (this *hyperliquid) FetchFundingRates(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 request interface{} = map[string]interface{} { "type": "metaAndAssetCtxs", } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // [ // { // "universe": [ // { // "maxLeverage": 50, // "name": "SOL", // "onlyIsolated": false, // "szDecimals": 2 // } // ] // }, // [ // { // "dayNtlVlm": "9450588.2273", // "funding": "0.0000198", // "impactPxs": [ // "108.04", // "108.06" // ], // "markPx": "108.04", // "midPx": "108.05", // "openInterest": "10764.48", // "oraclePx": "107.99", // "premium": "0.00055561", // "prevDayPx": "111.81" // } // ] // ] // // var meta interface{} = this.SafeDict(response, 0, map[string]interface{} {}) var universe interface{} = this.SafeList(meta, "universe", []interface{}{}) var assetCtxs interface{} = this.SafeList(response, 1, []interface{}{}) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(universe)); i++ { var data interface{} = this.Extend(this.SafeDict(universe, i, map[string]interface{} {}), this.SafeDict(assetCtxs, i, map[string]interface{} {})) AppendToArray(&result,data) } ch <- this.ParseFundingRates(result, symbols) return nil }() return ch } func (this *hyperliquid) ParseFundingRate(info interface{}, optionalArgs ...interface{}) interface{} { // // { // "maxLeverage": "50", // "name": "ETH", // "onlyIsolated": false, // "szDecimals": "4", // "dayNtlVlm": "1709813.11535", // "funding": "0.00004807", // "impactPxs": [ // "2369.3", // "2369.6" // ], // "markPx": "2369.6", // "midPx": "2369.45", // "openInterest": "1815.4712", // "oraclePx": "2367.3", // "premium": "0.00090821", // "prevDayPx": "2381.5" // } // market := GetArg(optionalArgs, 0, nil) _ = market var base interface{} = this.SafeString(info, "name") var marketId interface{} = this.CoinToMarketId(base) var symbol interface{} = this.SafeSymbol(marketId, market) var funding interface{} = this.SafeNumber(info, "funding") var markPx interface{} = this.SafeNumber(info, "markPx") var oraclePx interface{} = this.SafeNumber(info, "oraclePx") var fundingTimestamp interface{} = Multiply(Multiply(Multiply((Add(MathFloor(Divide(Divide(Divide(this.Milliseconds(), 60), 60), 1000)), 1)), 60), 60), 1000) return map[string]interface{} { "info": info, "symbol": symbol, "markPrice": markPx, "indexPrice": oraclePx, "interestRate": nil, "estimatedSettlePrice": nil, "timestamp": nil, "datetime": nil, "fundingRate": funding, "fundingTimestamp": fundingTimestamp, "fundingDatetime": this.Iso8601(fundingTimestamp), "nextFundingRate": nil, "nextFundingTimestamp": nil, "nextFundingDatetime": nil, "previousFundingRate": nil, "previousFundingTimestamp": nil, "previousFundingDatetime": nil, "interval": "1h", } } func (this *hyperliquid) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} { // // { // "prevDayPx": "3400.5", // "dayNtlVlm": "511297257.47936022", // "markPx": "3464.7", // "midPx": "3465.05", // "oraclePx": "3460.1", // only in swap // "openInterest": "64638.1108", // only in swap // "premium": "0.00141614", // only in swap // "funding": "0.00008727", // only in swap // "impactPxs": [ "3465.0", "3465.1" ], // only in swap // "coin": "PURR", // only in spot // "circulatingSupply": "998949190.03400207", // only in spot // }, // market := GetArg(optionalArgs, 0, nil) _ = market var bidAsk interface{} = this.SafeList(ticker, "impactPxs") return this.SafeTicker(map[string]interface{} { "symbol": GetValue(market, "symbol"), "timestamp": nil, "datetime": nil, "previousClose": this.SafeNumber(ticker, "prevDayPx"), "close": this.SafeNumber(ticker, "midPx"), "bid": this.SafeNumber(bidAsk, 0), "ask": this.SafeNumber(bidAsk, 1), "quoteVolume": this.SafeNumber(ticker, "dayNtlVlm"), "info": ticker, }, market) } /** * @method * @name hyperliquid#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#candle-snapshot * @param {string} symbol unified symbol of the market to fetch OHLCV data for * @param {string} timeframe the length of time each candle represents, support '1m', '15m', '1h', '1d' * @param {int} [since] timestamp in ms of the earliest candle to fetch * @param {int} [limit] the maximum amount of candles to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] timestamp in ms of the latest candle to fetch * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ func (this *hyperliquid) 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 retRes11028 := (<-this.LoadMarkets()) PanicOnError(retRes11028) var market interface{} = this.Market(symbol) var until interface{} = this.SafeInteger(params, "until", this.Milliseconds()) var useTail interface{} = IsEqual(since, nil) var originalSince interface{} = since if IsTrue(IsEqual(since, nil)) { if IsTrue(!IsEqual(limit, nil)) { // optimization if limit is provided var timeframeInMilliseconds interface{} = Multiply(this.ParseTimeframe(timeframe), 1000) since = this.Sum(until, Multiply(Multiply(timeframeInMilliseconds, limit), OpNeg(1))) useTail = false } else { since = 0 } } params = this.Omit(params, []interface{}{"until"}) var request interface{} = map[string]interface{} { "type": "candleSnapshot", "req": map[string]interface{} { "coin": Ternary(IsTrue(GetValue(market, "swap")), GetValue(market, "base"), GetValue(market, "id")), "interval": this.SafeString(this.Timeframes, timeframe, timeframe), "startTime": since, "endTime": until, }, } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // [ // { // "T": 1704287699999, // "c": "2226.4", // "h": "2247.9", // "i": "15m", // "l": "2224.6", // "n": 46, // "o": "2247.9", // "s": "ETH", // "t": 1704286800000, // "v": "591.6427" // } // ] // ch <- this.ParseOHLCVs(response, market, timeframe, originalSince, limit, useTail) return nil }() return ch } func (this *hyperliquid) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} { // // { // "T": 1704287699999, // "c": "2226.4", // "h": "2247.9", // "i": "15m", // "l": "2224.6", // "n": 46, // "o": "2247.9", // "s": "ETH", // "t": 1704286800000, // "v": "591.6427" // } // market := GetArg(optionalArgs, 0, nil) _ = market return []interface{}{this.SafeInteger(ohlcv, "t"), this.SafeNumber(ohlcv, "o"), this.SafeNumber(ohlcv, "h"), this.SafeNumber(ohlcv, "l"), this.SafeNumber(ohlcv, "c"), this.SafeNumber(ohlcv, "v")} } /** * @method * @name hyperliquid#fetchTrades * @description get the list of most recent trades for a particular symbol * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-a-users-fills * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-a-users-fills-by-time * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch trades for * @param {int} [limit] the maximum number of trades structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] timestamp in ms of the latest trade * @param {string} [params.address] wallet address that made trades * @param {string} [params.user] wallet address that made trades * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ func (this *hyperliquid) 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 var userAddress interface{} = nil userAddressparamsVariable := this.HandlePublicAddress("fetchTrades", params); userAddress = GetValue(userAddressparamsVariable,0); params = GetValue(userAddressparamsVariable,1) retRes11908 := (<-this.LoadMarkets()) PanicOnError(retRes11908) var market interface{} = this.SafeMarket(symbol) var request interface{} = map[string]interface{} { "user": userAddress, } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "type", "userFillsByTime") AddElementToObject(request, "startTime", since) } else { AddElementToObject(request, "type", "userFills") } var until interface{} = this.SafeInteger(params, "until") params = this.Omit(params, "until") if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "endTime", until) } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // [ // { // "closedPnl": "0.19343", // "coin": "ETH", // "crossed": true, // "dir": "Close Long", // "fee": "0.050062", // "hash": "0x09d77c96791e98b5775a04092584ab010d009445119c71e4005c0d634ea322bc", // "liquidationMarkPx": null, // "oid": 3929354691, // "px": "2381.1", // "side": "A", // "startPosition": "0.0841", // "sz": "0.0841", // "tid": 128423918764978, // "time": 1704262888911 // } // ] // ch <- this.ParseTrades(response, market, since, limit) return nil }() return ch } func (this *hyperliquid) AmountToPrecision(symbol interface{}, amount interface{}) interface{} { var market interface{} = this.Market(symbol) return this.DecimalToPrecision(amount, ROUND, GetValue(GetValue(market, "precision"), "amount"), this.PrecisionMode, this.PaddingMode) } func (this *hyperliquid) PriceToPrecision(symbol interface{}, price interface{}) interface{} { var market interface{} = this.Market(symbol) var priceStr interface{} = this.NumberToString(price) var integerPart interface{} = GetValue(Split(priceStr, "."), 0) var significantDigits interface{} = mathMax(5, GetLength(integerPart)) var result interface{} = this.DecimalToPrecision(price, ROUND, significantDigits, SIGNIFICANT_DIGITS, this.PaddingMode) var maxDecimals interface{} = Ternary(IsTrue(GetValue(market, "spot")), 8, 6) var subtractedValue interface{} = Subtract(maxDecimals, this.PrecisionFromString(this.SafeString(GetValue(market, "precision"), "amount"))) return this.DecimalToPrecision(result, ROUND, subtractedValue, DECIMAL_PLACES, this.PaddingMode) } func (this *hyperliquid) HashMessage(message interface{}) interface{} { return Add("0x", this.Hash(message, keccak, "hex")) } func (this *hyperliquid) SignHash(hash interface{}, privateKey interface{}) interface{} { var signature interface{} = Ecdsa(Slice(hash, OpNeg(64), nil), Slice(privateKey, OpNeg(64), nil), secp256k1, nil) return map[string]interface{} { "r": Add("0x", GetValue(signature, "r")), "s": Add("0x", GetValue(signature, "s")), "v": this.Sum(27, GetValue(signature, "v")), } } func (this *hyperliquid) SignMessage(message interface{}, privateKey interface{}) interface{} { return this.SignHash(this.HashMessage(message), Slice(privateKey, OpNeg(64), nil)) } func (this *hyperliquid) ConstructPhantomAgent(hash interface{}, optionalArgs ...interface{}) interface{} { isTestnet := GetArg(optionalArgs, 0, true) _ = isTestnet var source interface{} = Ternary(IsTrue((isTestnet)), "b", "a") return map[string]interface{} { "source": source, "connectionId": hash, } } func (this *hyperliquid) ActionHash(action interface{}, vaultAddress interface{}, nonce interface{}) interface{} { var dataBinary interface{} = this.Packb(action) var dataHex interface{} = this.BinaryToBase16(dataBinary) var data interface{} = dataHex data = Add(data, Add("00000", this.IntToBase16(nonce))) if IsTrue(IsEqual(vaultAddress, nil)) { data = Add(data, "00") } else { data = Add(data, "01") data = Add(data, vaultAddress) } return this.Hash(this.Base16ToBinary(data), keccak, "binary") } func (this *hyperliquid) SignL1Action(action interface{}, nonce interface{}, optionalArgs ...interface{}) interface{} { vaultAdress := GetArg(optionalArgs, 0, nil) _ = vaultAdress var hash interface{} = this.ActionHash(action, vaultAdress, nonce) var isTestnet interface{} = this.SafeBool(this.Options, "sandboxMode", false) var phantomAgent interface{} = this.ConstructPhantomAgent(hash, isTestnet) // const data: Dict = { // 'domain': { // 'chainId': 1337, // 'name': 'Exchange', // 'verifyingContract': '0x0000000000000000000000000000000000000000', // 'version': '1', // }, // 'types': { // 'Agent': [ // { 'name': 'source', 'type': 'string' }, // { 'name': 'connectionId', 'type': 'bytes32' }, // ], // 'EIP712Domain': [ // { 'name': 'name', 'type': 'string' }, // { 'name': 'version', 'type': 'string' }, // { 'name': 'chainId', 'type': 'uint256' }, // { 'name': 'verifyingContract', 'type': 'address' }, // ], // }, // 'primaryType': 'Agent', // 'message': phantomAgent, // }; var zeroAddress interface{} = this.SafeString(this.Options, "zeroAddress") var chainId interface{} = 1337 // check this out var domain interface{} = map[string]interface{} { "chainId": chainId, "name": "Exchange", "verifyingContract": zeroAddress, "version": "1", } var messageTypes interface{} = map[string]interface{} { "Agent": []interface{}{map[string]interface{} { "name": "source", "type": "string", }, map[string]interface{} { "name": "connectionId", "type": "bytes32", }}, } var msg interface{} = this.EthEncodeStructuredData(domain, messageTypes, phantomAgent) var signature interface{} = this.SignMessage(msg, this.PrivateKey) return signature } func (this *hyperliquid) SignUserSignedAction(messageTypes interface{}, message interface{}) interface{} { var zeroAddress interface{} = this.SafeString(this.Options, "zeroAddress") var chainId interface{} = 421614 // check this out var domain interface{} = map[string]interface{} { "chainId": chainId, "name": "HyperliquidSignTransaction", "verifyingContract": zeroAddress, "version": "1", } var msg interface{} = this.EthEncodeStructuredData(domain, messageTypes, message) var signature interface{} = this.SignMessage(msg, this.PrivateKey) return signature } func (this *hyperliquid) BuildUsdSendSig(message interface{}) interface{} { var messageTypes interface{} = map[string]interface{} { "HyperliquidTransaction:UsdSend": []interface{}{map[string]interface{} { "name": "hyperliquidChain", "type": "string", }, map[string]interface{} { "name": "destination", "type": "string", }, map[string]interface{} { "name": "amount", "type": "string", }, map[string]interface{} { "name": "time", "type": "uint64", }}, } return this.SignUserSignedAction(messageTypes, message) } func (this *hyperliquid) BuildUsdClassSendSig(message interface{}) interface{} { var messageTypes interface{} = map[string]interface{} { "HyperliquidTransaction:UsdClassTransfer": []interface{}{map[string]interface{} { "name": "hyperliquidChain", "type": "string", }, map[string]interface{} { "name": "amount", "type": "string", }, map[string]interface{} { "name": "toPerp", "type": "bool", }, map[string]interface{} { "name": "nonce", "type": "uint64", }}, } return this.SignUserSignedAction(messageTypes, message) } func (this *hyperliquid) BuildWithdrawSig(message interface{}) interface{} { var messageTypes interface{} = map[string]interface{} { "HyperliquidTransaction:Withdraw": []interface{}{map[string]interface{} { "name": "hyperliquidChain", "type": "string", }, map[string]interface{} { "name": "destination", "type": "string", }, map[string]interface{} { "name": "amount", "type": "string", }, map[string]interface{} { "name": "time", "type": "uint64", }}, } return this.SignUserSignedAction(messageTypes, message) } /** * @method * @name hyperliquid#createOrder * @description create a trade order * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-an-order * @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 {string} [params.timeInForce] 'Gtc', 'Ioc', 'Alo' * @param {bool} [params.postOnly] true or false whether the order is post-only * @param {bool} [params.reduceOnly] true or false whether the order is reduce-only * @param {float} [params.triggerPrice] The price at which a trigger order is triggered at * @param {string} [params.clientOrderId] client order id, (optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef) * @param {string} [params.slippage] the slippage for market order * @param {string} [params.vaultAddress] the vault address for order * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *hyperliquid) 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 retRes14018 := (<-this.LoadMarkets()) PanicOnError(retRes14018) orderglobalParamsVariable := this.ParseCreateOrderArgs(symbol, typeVar, side, amount, price, params); order := GetValue(orderglobalParamsVariable,0); globalParams := GetValue(orderglobalParamsVariable,1) orders:= (<-this.CreateOrders([]interface{}{order}, globalParams)) PanicOnError(orders) ch <- GetValue(orders, 0) return nil }() return ch } /** * @method * @name hyperliquid#createOrders * @description create a list of trade orders * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-an-order * @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params * @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 *hyperliquid) CreateOrders(orders 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 retRes14178 := (<-this.LoadMarkets()) PanicOnError(retRes14178) var request interface{} = this.CreateOrdersRequest(orders, params) response:= (<-this.PrivatePostExchange(request)) PanicOnError(response) // // { // "status": "ok", // "response": { // "type": "order", // "data": { // "statuses": [ // { // "resting": { // "oid": 5063830287 // } // } // ] // } // } // } // var responseObj interface{} = this.SafeDict(response, "response", map[string]interface{} {}) var data interface{} = this.SafeDict(responseObj, "data", map[string]interface{} {}) var statuses interface{} = this.SafeList(data, "statuses", []interface{}{}) ch <- this.ParseOrders(statuses, nil) return nil }() return ch } func (this *hyperliquid) CreateOrdersRequest(orders interface{}, optionalArgs ...interface{}) interface{} { /** * @method * @name hyperliquid#createOrdersRequest * @description create a list of trade orders * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-an-order * @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params this.CheckRequiredCredentials() var defaultSlippage interface{} = this.SafeString(this.Options, "defaultSlippage") defaultSlippage = this.SafeString(params, "slippage", defaultSlippage) var hasClientOrderId interface{} = false for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ { var rawOrder interface{} = GetValue(orders, i) var orderParams interface{} = this.SafeDict(rawOrder, "params", map[string]interface{} {}) var clientOrderId interface{} = this.SafeString2(orderParams, "clientOrderId", "client_id") if IsTrue(!IsEqual(clientOrderId, nil)) { hasClientOrderId = true } } if IsTrue(hasClientOrderId) { for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ { var rawOrder interface{} = GetValue(orders, i) var orderParams interface{} = this.SafeDict(rawOrder, "params", map[string]interface{} {}) var clientOrderId interface{} = this.SafeString2(orderParams, "clientOrderId", "client_id") if IsTrue(IsEqual(clientOrderId, nil)) { panic(ArgumentsRequired(Add(this.Id, " createOrders() all orders must have clientOrderId if at least one has a clientOrderId"))) } } } params = this.Omit(params, []interface{}{"slippage", "clientOrderId", "client_id", "slippage", "triggerPrice", "stopPrice", "stopLossPrice", "takeProfitPrice", "timeInForce"}) var nonce interface{} = this.Milliseconds() var orderReq interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ { var rawOrder interface{} = GetValue(orders, i) var marketId interface{} = this.SafeString(rawOrder, "symbol") var market interface{} = this.Market(marketId) var symbol interface{} = GetValue(market, "symbol") var typeVar interface{} = this.SafeStringUpper(rawOrder, "type") var isMarket interface{} = (IsEqual(typeVar, "MARKET")) var side interface{} = this.SafeStringUpper(rawOrder, "side") var isBuy interface{} = (IsEqual(side, "BUY")) var amount interface{} = this.SafeString(rawOrder, "amount") var price interface{} = this.SafeString(rawOrder, "price") var orderParams interface{} = this.SafeDict(rawOrder, "params", map[string]interface{} {}) var clientOrderId interface{} = this.SafeString2(orderParams, "clientOrderId", "client_id") var slippage interface{} = this.SafeString(orderParams, "slippage", defaultSlippage) var defaultTimeInForce interface{} = Ternary(IsTrue((isMarket)), "ioc", "gtc") var postOnly interface{} = this.SafeBool(orderParams, "postOnly", false) if IsTrue(postOnly) { defaultTimeInForce = "alo" } var timeInForce interface{} = this.SafeStringLower(orderParams, "timeInForce", defaultTimeInForce) timeInForce = this.Capitalize(timeInForce) var triggerPrice interface{} = this.SafeString2(orderParams, "triggerPrice", "stopPrice") var stopLossPrice interface{} = this.SafeString(orderParams, "stopLossPrice", triggerPrice) var takeProfitPrice interface{} = this.SafeString(orderParams, "takeProfitPrice") var isTrigger interface{} = (IsTrue(stopLossPrice) || IsTrue(takeProfitPrice)) var px interface{} = nil if IsTrue(isMarket) { if IsTrue(IsEqual(price, nil)) { panic(ArgumentsRequired(Add(this.Id, " market orders require price to calculate the max slippage price. Default slippage can be set in options (default is 5%)."))) } px = Ternary(IsTrue((isBuy)), Precise.StringMul(price, Precise.StringAdd("1", slippage)), Precise.StringMul(price, Precise.StringSub("1", slippage))) px = this.PriceToPrecision(symbol, px) // round after adding slippage } else { px = this.PriceToPrecision(symbol, price) } var sz interface{} = this.AmountToPrecision(symbol, amount) var reduceOnly interface{} = this.SafeBool(orderParams, "reduceOnly", false) var orderType interface{} = map[string]interface{} {} if IsTrue(isTrigger) { var isTp interface{} = false if IsTrue(!IsEqual(takeProfitPrice, nil)) { triggerPrice = this.PriceToPrecision(symbol, takeProfitPrice) isTp = true } else { triggerPrice = this.PriceToPrecision(symbol, stopLossPrice) } AddElementToObject(orderType, "trigger", map[string]interface{} { "isMarket": isMarket, "triggerPx": triggerPrice, "tpsl": Ternary(IsTrue((isTp)), "tp", "sl"), }) } else { AddElementToObject(orderType, "limit", map[string]interface{} { "tif": timeInForce, }) } orderParams = this.Omit(orderParams, []interface{}{"clientOrderId", "slippage", "triggerPrice", "stopPrice", "stopLossPrice", "takeProfitPrice", "timeInForce", "client_id", "reduceOnly", "postOnly"}) var orderObj interface{} = map[string]interface{} { "a": this.ParseToInt(GetValue(market, "baseId")), "b": isBuy, "p": px, "s": sz, "r": reduceOnly, "t": orderType, } if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(orderObj, "c", clientOrderId) } AppendToArray(&orderReq,orderObj) } var vaultAddress interface{} = this.FormatVaultAddress(this.SafeString(params, "vaultAddress")) var orderAction interface{} = map[string]interface{} { "type": "order", "orders": orderReq, "grouping": "na", } if IsTrue(IsEqual(vaultAddress, nil)) { AddElementToObject(orderAction, "brokerCode", 1) } var signature interface{} = this.SignL1Action(orderAction, nonce, vaultAddress) var request interface{} = map[string]interface{} { "action": orderAction, "nonce": nonce, "signature": signature, } if IsTrue(!IsEqual(vaultAddress, nil)) { params = this.Omit(params, "vaultAddress") AddElementToObject(request, "vaultAddress", vaultAddress) } return request } /** * @method * @name hyperliquid#cancelOrder * @description cancels an open order * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid * @param {string} id order id * @param {string} symbol unified symbol of the market the order was made in * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.clientOrderId] client order id, (optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef) * @param {string} [params.vaultAddress] the vault address for order * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *hyperliquid) 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 orders:= (<-this.CancelOrders([]interface{}{id}, symbol, params)) PanicOnError(orders) ch <- this.SafeDict(orders, 0) return nil }() return ch } /** * @method * @name hyperliquid#cancelOrders * @description cancel multiple orders * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid * @param {string[]} ids order ids * @param {string} [symbol] unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string|string[]} [params.clientOrderId] client order ids, (optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef) * @param {string} [params.vaultAddress] the vault address * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *hyperliquid) 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 this.CheckRequiredCredentials() if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " cancelOrders() requires a symbol argument"))) } retRes16088 := (<-this.LoadMarkets()) PanicOnError(retRes16088) var market interface{} = this.Market(symbol) var clientOrderId interface{} = this.SafeValue2(params, "clientOrderId", "client_id") params = this.Omit(params, []interface{}{"clientOrderId", "client_id"}) var nonce interface{} = this.Milliseconds() var request interface{} = map[string]interface{} { "nonce": nonce, } var cancelReq interface{} = []interface{}{} var cancelAction interface{} = map[string]interface{} { "type": "", "cancels": []interface{}{}, } var baseId interface{} = this.ParseToNumeric(GetValue(market, "baseId")) if IsTrue(!IsEqual(clientOrderId, nil)) { if !IsTrue(IsArray(clientOrderId)) { clientOrderId = []interface{}{clientOrderId} } AddElementToObject(cancelAction, "type", "cancelByCloid") for i := 0; IsLessThan(i, GetArrayLength(clientOrderId)); i++ { AppendToArray(&cancelReq,map[string]interface{} { "asset": baseId, "cloid": GetValue(clientOrderId, i), }) } } else { AddElementToObject(cancelAction, "type", "cancel") for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ { AppendToArray(&cancelReq,map[string]interface{} { "a": baseId, "o": this.ParseToNumeric(GetValue(ids, i)), }) } } AddElementToObject(cancelAction, "cancels", cancelReq) var vaultAddress interface{} = this.FormatVaultAddress(this.SafeString(params, "vaultAddress")) var signature interface{} = this.SignL1Action(cancelAction, nonce, vaultAddress) AddElementToObject(request, "action", cancelAction) AddElementToObject(request, "signature", signature) if IsTrue(!IsEqual(vaultAddress, nil)) { params = this.Omit(params, "vaultAddress") AddElementToObject(request, "vaultAddress", vaultAddress) } response:= (<-this.PrivatePostExchange(request)) PanicOnError(response) // // { // "status":"ok", // "response":{ // "type":"cancel", // "data":{ // "statuses":[ // "success" // ] // } // } // } // var innerResponse interface{} = this.SafeDict(response, "response") var data interface{} = this.SafeDict(innerResponse, "data") var statuses interface{} = this.SafeList(data, "statuses") var orders interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(statuses)); i++ { var status interface{} = GetValue(statuses, i) AppendToArray(&orders,this.SafeOrder(map[string]interface{} { "info": status, "status": status, })) } ch <- orders return nil }() return ch } /** * @method * @name hyperliquid#cancelOrdersForSymbols * @description cancel multiple orders for multiple symbols * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid * @param {CancellationRequest[]} orders each order should contain the parameters required by cancelOrder namely id and symbol, example [{"id": "a", "symbol": "BTC/USDT"}, {"id": "b", "symbol": "ETH/USDT"}] * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.vaultAddress] the vault address * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *hyperliquid) CancelOrdersForSymbols(orders 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 this.CheckRequiredCredentials() retRes16938 := (<-this.LoadMarkets()) PanicOnError(retRes16938) var nonce interface{} = this.Milliseconds() var request interface{} = map[string]interface{} { "nonce": nonce, } var cancelReq interface{} = []interface{}{} var cancelAction interface{} = map[string]interface{} { "type": "", "cancels": []interface{}{}, } var cancelByCloid interface{} = false for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ { var order interface{} = GetValue(orders, i) var clientOrderId interface{} = this.SafeString(order, "clientOrderId") if IsTrue(!IsEqual(clientOrderId, nil)) { cancelByCloid = true } var id interface{} = this.SafeString(order, "id") var symbol interface{} = this.SafeString(order, "symbol") if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " cancelOrdersForSymbols() requires a symbol argument in each order"))) } if IsTrue(IsTrue(!IsEqual(id, nil)) && IsTrue(cancelByCloid)) { panic(BadRequest(Add(this.Id, " cancelOrdersForSymbols() all orders must have either id or clientOrderId"))) } var assetKey interface{} = Ternary(IsTrue(cancelByCloid), "asset", "a") var idKey interface{} = Ternary(IsTrue(cancelByCloid), "cloid", "o") var market interface{} = this.Market(symbol) var cancelObj interface{} = map[string]interface{} {} AddElementToObject(cancelObj, assetKey, this.ParseToNumeric(GetValue(market, "baseId"))) AddElementToObject(cancelObj, idKey, Ternary(IsTrue(cancelByCloid), clientOrderId, this.ParseToNumeric(id))) AppendToArray(&cancelReq,cancelObj) } AddElementToObject(cancelAction, "type", Ternary(IsTrue(cancelByCloid), "cancelByCloid", "cancel")) AddElementToObject(cancelAction, "cancels", cancelReq) var vaultAddress interface{} = this.FormatVaultAddress(this.SafeString(params, "vaultAddress")) var signature interface{} = this.SignL1Action(cancelAction, nonce, vaultAddress) AddElementToObject(request, "action", cancelAction) AddElementToObject(request, "signature", signature) if IsTrue(!IsEqual(vaultAddress, nil)) { params = this.Omit(params, "vaultAddress") AddElementToObject(request, "vaultAddress", vaultAddress) } response:= (<-this.PrivatePostExchange(request)) PanicOnError(response) // // { // "status":"ok", // "response":{ // "type":"cancel", // "data":{ // "statuses":[ // "success" // ] // } // } // } // ch <- response return nil }() return ch } /** * @method * @name hyperliquid#cancelAllOrdersAfter * @description dead man's switch, cancel all orders after the given timeout * @param {number} timeout time in milliseconds, 0 represents cancel the timer * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.vaultAddress] the vault address * @returns {object} the api result */ func (this *hyperliquid) CancelAllOrdersAfter(timeout 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 this.CheckRequiredCredentials() retRes17658 := (<-this.LoadMarkets()) PanicOnError(retRes17658) params = this.Omit(params, []interface{}{"clientOrderId", "client_id"}) var nonce interface{} = this.Milliseconds() var request interface{} = map[string]interface{} { "nonce": nonce, } var cancelAction interface{} = map[string]interface{} { "type": "scheduleCancel", "time": Add(nonce, timeout), } var vaultAddress interface{} = this.FormatVaultAddress(this.SafeString(params, "vaultAddress")) var signature interface{} = this.SignL1Action(cancelAction, nonce, vaultAddress) AddElementToObject(request, "action", cancelAction) AddElementToObject(request, "signature", signature) if IsTrue(!IsEqual(vaultAddress, nil)) { params = this.Omit(params, "vaultAddress") AddElementToObject(request, "vaultAddress", vaultAddress) } response:= (<-this.PrivatePostExchange(request)) PanicOnError(response) // // { // "status":"err", // "response":"Cannot set scheduled cancel time until enough volume traded. Required: $1000000. Traded: $373.47205." // } // ch <- response return nil }() return ch } func (this *hyperliquid) EditOrderRequest(id interface{}, symbol interface{}, typeVar interface{}, side interface{}, optionalArgs ...interface{}) interface{} { amount := GetArg(optionalArgs, 0, nil) _ = amount price := GetArg(optionalArgs, 1, nil) _ = price params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params this.CheckRequiredCredentials() if IsTrue(IsEqual(id, nil)) { panic(ArgumentsRequired(Add(this.Id, " editOrder() requires an id argument"))) } var market interface{} = this.Market(symbol) typeVar = ToUpper(typeVar) var isMarket interface{} = (IsEqual(typeVar, "MARKET")) side = ToUpper(side) var isBuy interface{} = (IsEqual(side, "BUY")) var defaultSlippage interface{} = this.SafeString(this.Options, "defaultSlippage") var slippage interface{} = this.SafeString(params, "slippage", defaultSlippage) var defaultTimeInForce interface{} = Ternary(IsTrue((isMarket)), "ioc", "gtc") var postOnly interface{} = this.SafeBool(params, "postOnly", false) if IsTrue(postOnly) { defaultTimeInForce = "alo" } var timeInForce interface{} = this.SafeStringLower(params, "timeInForce", defaultTimeInForce) timeInForce = this.Capitalize(timeInForce) var clientOrderId interface{} = this.SafeString2(params, "clientOrderId", "client_id") var triggerPrice interface{} = this.SafeString2(params, "triggerPrice", "stopPrice") var stopLossPrice interface{} = this.SafeString(params, "stopLossPrice", triggerPrice) var takeProfitPrice interface{} = this.SafeString(params, "takeProfitPrice") var isTrigger interface{} = (IsTrue(stopLossPrice) || IsTrue(takeProfitPrice)) params = this.Omit(params, []interface{}{"slippage", "timeInForce", "triggerPrice", "stopLossPrice", "takeProfitPrice", "clientOrderId", "client_id"}) var px interface{} = ToString(price) if IsTrue(isMarket) { px = Ternary(IsTrue((isBuy)), Precise.StringMul(ToString(price), Precise.StringAdd("1", slippage)), Precise.StringMul(ToString(price), Precise.StringSub("1", slippage))) } else { px = this.PriceToPrecision(symbol, ToString(price)) } var sz interface{} = this.AmountToPrecision(symbol, amount) var reduceOnly interface{} = this.SafeBool(params, "reduceOnly", false) var orderType interface{} = map[string]interface{} {} if IsTrue(isTrigger) { var isTp interface{} = false if IsTrue(!IsEqual(takeProfitPrice, nil)) { triggerPrice = this.PriceToPrecision(symbol, takeProfitPrice) isTp = true } else { triggerPrice = this.PriceToPrecision(symbol, stopLossPrice) } AddElementToObject(orderType, "trigger", map[string]interface{} { "isMarket": isMarket, "triggerPx": triggerPrice, "tpsl": Ternary(IsTrue((isTp)), "tp", "sl"), }) } else { AddElementToObject(orderType, "limit", map[string]interface{} { "tif": timeInForce, }) } if IsTrue(IsEqual(triggerPrice, nil)) { triggerPrice = "0" } var nonce interface{} = this.Milliseconds() var orderReq interface{} = map[string]interface{} { "a": this.ParseToInt(GetValue(market, "baseId")), "b": isBuy, "p": px, "s": sz, "r": reduceOnly, "t": orderType, } if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(orderReq, "c", clientOrderId) } var modifyReq interface{} = map[string]interface{} { "oid": this.ParseToInt(id), "order": orderReq, } var modifyAction interface{} = map[string]interface{} { "type": "batchModify", "modifies": []interface{}{modifyReq}, } var vaultAddress interface{} = this.FormatVaultAddress(this.SafeString(params, "vaultAddress")) var signature interface{} = this.SignL1Action(modifyAction, nonce, vaultAddress) var request interface{} = map[string]interface{} { "action": modifyAction, "nonce": nonce, "signature": signature, } if IsTrue(!IsEqual(vaultAddress, nil)) { params = this.Omit(params, "vaultAddress") AddElementToObject(request, "vaultAddress", vaultAddress) } return request } /** * @method * @name hyperliquid#editOrder * @description edit a trade order * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-an-order * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-multiple-orders * @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 {string} [params.timeInForce] 'Gtc', 'Ioc', 'Alo' * @param {bool} [params.postOnly] true or false whether the order is post-only * @param {bool} [params.reduceOnly] true or false whether the order is reduce-only * @param {float} [params.triggerPrice] The price at which a trigger order is triggered at * @param {string} [params.clientOrderId] client order id, (optional 128 bit hex string e.g. 0x1234567890abcdef1234567890abcdef) * @param {string} [params.vaultAddress] the vault address for order * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *hyperliquid) 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 retRes19078 := (<-this.LoadMarkets()) PanicOnError(retRes19078) var market interface{} = this.Market(symbol) var request interface{} = this.EditOrderRequest(id, symbol, typeVar, side, amount, price, params) response:= (<-this.PrivatePostExchange(request)) PanicOnError(response) // // { // "status": "ok", // "response": { // "type": "order", // "data": { // "statuses": [ // { // "resting": { // "oid": 5063830287 // } // } // ] // } // } // } // when the order is filled immediately // { // "status":"ok", // "response":{ // "type":"order", // "data":{ // "statuses":[ // { // "filled":{ // "totalSz":"0.1", // "avgPx":"100.84", // "oid":6195281425 // } // } // ] // } // } // } // var responseObject interface{} = this.SafeDict(response, "response", map[string]interface{} {}) var dataObject interface{} = this.SafeDict(responseObject, "data", map[string]interface{} {}) var statuses interface{} = this.SafeList(dataObject, "statuses", []interface{}{}) var first interface{} = this.SafeDict(statuses, 0, map[string]interface{} {}) ch <- this.ParseOrder(first, market) return nil }() return ch } /** * @method * @name hyperliquid#fetchFundingRateHistory * @description fetches historical funding rate prices * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-historical-funding-rates * @param {string} symbol unified symbol of the market to fetch the funding rate history for * @param {int} [since] timestamp in ms of the earliest funding rate to fetch * @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] timestamp in ms of the latest funding rate * @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} */ func (this *hyperliquid) FetchFundingRateHistory(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 retRes19668 := (<-this.LoadMarkets()) PanicOnError(retRes19668) if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchFundingRateHistory() requires a symbol argument"))) } var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "type": "fundingHistory", "coin": GetValue(market, "base"), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTime", since) } else { var maxLimit interface{} = Ternary(IsTrue((IsEqual(limit, nil))), 500, limit) AddElementToObject(request, "startTime", Subtract(this.Milliseconds(), Multiply(Multiply(Multiply(maxLimit, 60), 60), 1000))) } var until interface{} = this.SafeInteger(params, "until") params = this.Omit(params, "until") if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "endTime", until) } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // [ // { // "coin": "ETH", // "fundingRate": "0.0000125", // "premium": "0.00057962", // "time": 1704290400031 // } // ] // var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { var entry interface{} = GetValue(response, i) var timestamp interface{} = this.SafeInteger(entry, "time") AppendToArray(&result,map[string]interface{} { "info": entry, "symbol": this.SafeSymbol(nil, market), "fundingRate": this.SafeNumber(entry, "fundingRate"), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), }) } var sorted interface{} = this.SortBy(result, "timestamp") ch <- this.FilterBySymbolSinceLimit(sorted, symbol, since, limit) return nil }() return ch } /** * @method * @name hyperliquid#fetchOpenOrders * @description fetch all unfilled currently open orders * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-a-users-open-orders * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch open orders for * @param {int} [limit] the maximum number of open orders structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.user] user address, will default to this.walletAddress if not provided * @param {string} [params.method] 'openOrders' or 'frontendOpenOrders' default is 'frontendOpenOrders' * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *hyperliquid) 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 var userAddress interface{} = nil userAddressparamsVariable := this.HandlePublicAddress("fetchOpenOrders", params); userAddress = GetValue(userAddressparamsVariable,0); params = GetValue(userAddressparamsVariable,1) var method interface{} = nil methodparamsVariable := this.HandleOptionAndParams(params, "fetchOpenOrders", "method", "frontendOpenOrders"); method = GetValue(methodparamsVariable,0); params = GetValue(methodparamsVariable,1) retRes20318 := (<-this.LoadMarkets()) PanicOnError(retRes20318) var market interface{} = this.SafeMarket(symbol) var request interface{} = map[string]interface{} { "type": method, "user": userAddress, } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // [ // { // "coin": "ETH", // "limitPx": "2000.0", // "oid": 3991946565, // "origSz": "0.1", // "side": "B", // "sz": "0.1", // "timestamp": 1704346468838 // } // ] // var orderWithStatus interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { var order interface{} = GetValue(response, i) var extendOrder interface{} = map[string]interface{} {} if IsTrue(IsEqual(this.SafeString(order, "status"), nil)) { AddElementToObject(extendOrder, "ccxtStatus", "open") } AppendToArray(&orderWithStatus,this.Extend(order, extendOrder)) } ch <- this.ParseOrders(orderWithStatus, market, since, limit) return nil }() return ch } /** * @method * @name hyperliquid#fetchClosedOrders * @description fetch all unfilled currently closed orders * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch open orders for * @param {int} [limit] the maximum number of open orders structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.user] user address, will default to this.walletAddress if not provided * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *hyperliquid) 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 retRes20758 := (<-this.LoadMarkets()) PanicOnError(retRes20758) orders:= (<-this.FetchOrders(symbol, nil, nil, params)) PanicOnError(orders) // don't filter here because we don't want to catch open orders var closedOrders interface{} = this.FilterByArray(orders, "status", []interface{}{"closed"}, false) ch <- this.FilterBySymbolSinceLimit(closedOrders, symbol, since, limit) return nil }() return ch } /** * @method * @name hyperliquid#fetchCanceledOrders * @description fetch all canceled orders * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch open orders for * @param {int} [limit] the maximum number of open orders structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.user] user address, will default to this.walletAddress if not provided * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *hyperliquid) 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 retRes20938 := (<-this.LoadMarkets()) PanicOnError(retRes20938) orders:= (<-this.FetchOrders(symbol, nil, nil, params)) PanicOnError(orders) // don't filter here because we don't want to catch open orders var closedOrders interface{} = this.FilterByArray(orders, "status", []interface{}{"canceled"}, false) ch <- this.FilterBySymbolSinceLimit(closedOrders, symbol, since, limit) return nil }() return ch } /** * @method * @name hyperliquid#fetchCanceledAndClosedOrders * @description fetch all closed and canceled orders * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch open orders for * @param {int} [limit] the maximum number of open orders structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.user] user address, will default to this.walletAddress if not provided * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *hyperliquid) FetchCanceledAndClosedOrders(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 retRes21118 := (<-this.LoadMarkets()) PanicOnError(retRes21118) orders:= (<-this.FetchOrders(symbol, nil, nil, params)) PanicOnError(orders) // don't filter here because we don't want to catch open orders var closedOrders interface{} = this.FilterByArray(orders, "status", []interface{}{"canceled", "closed", "rejected"}, false) ch <- this.FilterBySymbolSinceLimit(closedOrders, symbol, since, limit) return nil }() return ch } /** * @method * @name hyperliquid#fetchOrders * @description fetch all orders * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch open orders for * @param {int} [limit] the maximum number of open orders structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.user] user address, will default to this.walletAddress if not provided * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *hyperliquid) 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, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params var userAddress interface{} = nil userAddressparamsVariable := this.HandlePublicAddress("fetchOrders", params); userAddress = GetValue(userAddressparamsVariable,0); params = GetValue(userAddressparamsVariable,1) retRes21318 := (<-this.LoadMarkets()) PanicOnError(retRes21318) var market interface{} = this.SafeMarket(symbol) var request interface{} = map[string]interface{} { "type": "historicalOrders", "user": userAddress, } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // [ // { // "coin": "ETH", // "limitPx": "2000.0", // "oid": 3991946565, // "origSz": "0.1", // "side": "B", // "sz": "0.1", // "timestamp": 1704346468838 // } // ] // ch <- this.ParseOrders(response, market, since, limit) return nil }() return ch } /** * @method * @name hyperliquid#fetchOrder * @description fetches information on an order made by the user * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#query-order-status-by-oid-or-cloid * @param {string} id order id * @param {string} symbol unified symbol of the market the order was made in * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.user] user address, will default to this.walletAddress if not provided * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *hyperliquid) 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 var userAddress interface{} = nil userAddressparamsVariable := this.HandlePublicAddress("fetchOrder", params); userAddress = GetValue(userAddressparamsVariable,0); params = GetValue(userAddressparamsVariable,1) retRes21688 := (<-this.LoadMarkets()) PanicOnError(retRes21688) var market interface{} = this.SafeMarket(symbol) var isClientOrderId interface{} = IsGreaterThanOrEqual(GetLength(id), 34) var request interface{} = map[string]interface{} { "type": "orderStatus", "oid": Ternary(IsTrue(isClientOrderId), id, this.ParseToNumeric(id)), "user": userAddress, } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // { // "order": { // "order": { // "children": [], // "cloid": null, // "coin": "ETH", // "isPositionTpsl": false, // "isTrigger": false, // "limitPx": "2000.0", // "oid": "3991946565", // "orderType": "Limit", // "origSz": "0.1", // "reduceOnly": false, // "side": "B", // "sz": "0.1", // "tif": "Gtc", // "timestamp": "1704346468838", // "triggerCondition": "N/A", // "triggerPx": "0.0" // }, // "status": "open", // "statusTimestamp": "1704346468838" // }, // "status": "order" // } // var data interface{} = this.SafeDict(response, "order") ch <- this.ParseOrder(data, market) return nil }() return ch } func (this *hyperliquid) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} { // // fetchOpenOrders // // { // "coin": "ETH", // "limitPx": "2000.0", // "oid": 3991946565, // "origSz": "0.1", // "side": "B", // "sz": "0.1", // "timestamp": 1704346468838 // } // fetchClosedorders // { // "cloid": null, // "closedPnl": "0.0", // "coin": "SOL", // "crossed": true, // "dir": "Open Long", // "fee": "0.003879", // "hash": "0x4a2647998682b7f07bc5040ab531e1011400f9a51bfa0346a0b41ebe510e8875", // "liquidationMarkPx": null, // "oid": "6463280784", // "px": "110.83", // "side": "B", // "startPosition": "1.64", // "sz": "0.1", // "tid": "232174667018988", // "time": "1709142268394" // } // // fetchOrder // // { // "order": { // "children": [], // "cloid": null, // "coin": "ETH", // "isPositionTpsl": false, // "isTrigger": false, // "limitPx": "2000.0", // "oid": "3991946565", // "orderType": "Limit", // "origSz": "0.1", // "reduceOnly": false, // "side": "B", // "sz": "0.1", // "tif": "Gtc", // "timestamp": "1704346468838", // "triggerCondition": "N/A", // "triggerPx": "0.0" // }, // "status": "open", // "statusTimestamp": "1704346468838" // } // // createOrder // // { // "resting": { // "oid": 5063830287 // } // } // // { // "filled":{ // "totalSz":"0.1", // "avgPx":"100.84", // "oid":6195281425 // } // } // frontendOrder // { // "children": [], // "cloid": null, // "coin": "BLUR", // "isPositionTpsl": false, // "isTrigger": true, // "limitPx": "0.5", // "oid": 8670487141, // "orderType": "Stop Limit", // "origSz": "20.0", // "reduceOnly": false, // "side": "B", // "sz": "20.0", // "tif": null, // "timestamp": 1715523663687, // "triggerCondition": "Price above 0.6", // "triggerPx": "0.6" // } // market := GetArg(optionalArgs, 0, nil) _ = market var entry interface{} = this.SafeDictN(order, []interface{}{"order", "resting", "filled"}) if IsTrue(IsEqual(entry, nil)) { entry = order } var coin interface{} = this.SafeString(entry, "coin") var marketId interface{} = nil if IsTrue(!IsEqual(coin, nil)) { marketId = this.CoinToMarketId(coin) } if IsTrue(IsEqual(this.SafeString(entry, "id"), nil)) { market = this.SafeMarket(marketId, nil) } else { market = this.SafeMarket(marketId, market) } var symbol interface{} = GetValue(market, "symbol") var timestamp interface{} = this.SafeInteger(entry, "timestamp") var status interface{} = this.SafeString2(order, "status", "ccxtStatus") order = this.Omit(order, []interface{}{"ccxtStatus"}) var side interface{} = this.SafeString(entry, "side") if IsTrue(!IsEqual(side, nil)) { side = Ternary(IsTrue((IsEqual(side, "A"))), "sell", "buy") } var totalAmount interface{} = this.SafeString2(entry, "origSz", "totalSz") var remaining interface{} = this.SafeString(entry, "sz") return this.SafeOrder(map[string]interface{} { "info": order, "id": this.SafeString(entry, "oid"), "clientOrderId": this.SafeString(entry, "cloid"), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "lastTradeTimestamp": nil, "lastUpdateTimestamp": this.SafeInteger(order, "statusTimestamp"), "symbol": symbol, "type": this.ParseOrderType(this.SafeStringLower(entry, "orderType")), "timeInForce": this.SafeStringUpper(entry, "tif"), "postOnly": nil, "reduceOnly": this.SafeBool(entry, "reduceOnly"), "side": side, "price": this.SafeString(entry, "limitPx"), "triggerPrice": Ternary(IsTrue(this.SafeBool(entry, "isTrigger")), this.SafeNumber(entry, "triggerPx"), nil), "amount": totalAmount, "cost": nil, "average": this.SafeString(entry, "avgPx"), "filled": Precise.StringSub(totalAmount, remaining), "remaining": remaining, "status": this.ParseOrderStatus(status), "fee": nil, "trades": nil, }, market) } func (this *hyperliquid) ParseOrderStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "triggered": "open", "filled": "closed", "open": "open", "canceled": "canceled", "rejected": "rejected", "marginCanceled": "canceled", } return this.SafeString(statuses, status, status) } func (this *hyperliquid) ParseOrderType(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "stop limit": "limit", "stop market": "market", } return this.SafeString(statuses, status, status) } /** * @method * @name hyperliquid#fetchMyTrades * @description fetch all trades made by the user * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-a-users-fills * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-a-users-fills-by-time * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch trades for * @param {int} [limit] the maximum number of trades structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] timestamp in ms of the latest trade * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ func (this *hyperliquid) 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 var userAddress interface{} = nil userAddressparamsVariable := this.HandlePublicAddress("fetchMyTrades", params); userAddress = GetValue(userAddressparamsVariable,0); params = GetValue(userAddressparamsVariable,1) retRes23878 := (<-this.LoadMarkets()) PanicOnError(retRes23878) var market interface{} = this.SafeMarket(symbol) var request interface{} = map[string]interface{} { "user": userAddress, } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "type", "userFillsByTime") AddElementToObject(request, "startTime", since) } else { AddElementToObject(request, "type", "userFills") } var until interface{} = this.SafeInteger(params, "until") params = this.Omit(params, "until") if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "endTime", until) } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // [ // { // "closedPnl": "0.19343", // "coin": "ETH", // "crossed": true, // "dir": "Close Long", // "fee": "0.050062", // "feeToken": "USDC", // "hash": "0x09d77c96791e98b5775a04092584ab010d009445119c71e4005c0d634ea322bc", // "liquidationMarkPx": null, // "oid": 3929354691, // "px": "2381.1", // "side": "A", // "startPosition": "0.0841", // "sz": "0.0841", // "tid": 128423918764978, // "time": 1704262888911 // } // ] // ch <- this.ParseTrades(response, market, since, limit) return nil }() return ch } func (this *hyperliquid) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} { // // { // "closedPnl": "0.19343", // "coin": "ETH", // "crossed": true, // "dir": "Close Long", // "fee": "0.050062", // "hash": "0x09d77c96791e98b5775a04092584ab010d009445119c71e4005c0d634ea322bc", // "liquidationMarkPx": null, // "oid": 3929354691, // "px": "2381.1", // "side": "A", // "startPosition": "0.0841", // "sz": "0.0841", // "tid": 128423918764978, // "time": 1704262888911 // } // market := GetArg(optionalArgs, 0, nil) _ = market var timestamp interface{} = this.SafeInteger(trade, "time") var price interface{} = this.SafeString(trade, "px") var amount interface{} = this.SafeString(trade, "sz") var coin interface{} = this.SafeString(trade, "coin") var marketId interface{} = this.CoinToMarketId(coin) market = this.SafeMarket(marketId, nil) var symbol interface{} = GetValue(market, "symbol") var id interface{} = this.SafeString(trade, "tid") var side interface{} = this.SafeString(trade, "side") if IsTrue(!IsEqual(side, nil)) { side = Ternary(IsTrue((IsEqual(side, "A"))), "sell", "buy") } var fee interface{} = this.SafeString(trade, "fee") return this.SafeTrade(map[string]interface{} { "info": trade, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "symbol": symbol, "id": id, "order": this.SafeString(trade, "oid"), "type": nil, "side": side, "takerOrMaker": nil, "price": price, "amount": amount, "cost": nil, "fee": map[string]interface{} { "cost": fee, "currency": this.SafeString(trade, "feeToken"), "rate": nil, }, }, market) } /** * @method * @name hyperliquid#fetchPosition * @description fetch data on an open position * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-users-perpetuals-account-summary * @param {string} symbol unified market symbol of the market the position is held in * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.user] user address, will default to this.walletAddress if not provided * @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *hyperliquid) 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 positions:= (<-this.FetchPositions([]interface{}{symbol}, params)) PanicOnError(positions) ch <- this.SafeDict(positions, 0, map[string]interface{} {}) return nil }() return ch } /** * @method * @name hyperliquid#fetchPositions * @description fetch all open positions * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-users-perpetuals-account-summary * @param {string[]} [symbols] list of unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.user] user address, will default to this.walletAddress if not provided * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *hyperliquid) 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 retRes25078 := (<-this.LoadMarkets()) PanicOnError(retRes25078) var userAddress interface{} = nil userAddressparamsVariable := this.HandlePublicAddress("fetchPositions", params); userAddress = GetValue(userAddressparamsVariable,0); params = GetValue(userAddressparamsVariable,1) symbols = this.MarketSymbols(symbols) var request interface{} = map[string]interface{} { "type": "clearinghouseState", "user": userAddress, } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // { // "assetPositions": [ // { // "position": { // "coin": "ETH", // "cumFunding": { // "allTime": "0.0", // "sinceChange": "0.0", // "sinceOpen": "0.0" // }, // "entryPx": "2213.9", // "leverage": { // "rawUsd": "-475.23904", // "type": "isolated", // "value": "20" // }, // "liquidationPx": "2125.00856238", // "marginUsed": "24.88097", // "maxLeverage": "50", // "positionValue": "500.12001", // "returnOnEquity": "0.0", // "szi": "0.2259", // "unrealizedPnl": "0.0" // }, // "type": "oneWay" // } // ], // "crossMaintenanceMarginUsed": "0.0", // "crossMarginSummary": { // "accountValue": "100.0", // "totalMarginUsed": "0.0", // "totalNtlPos": "0.0", // "totalRawUsd": "100.0" // }, // "marginSummary": { // "accountValue": "100.0", // "totalMarginUsed": "0.0", // "totalNtlPos": "0.0", // "totalRawUsd": "100.0" // }, // "time": "1704261007014", // "withdrawable": "100.0" // } // var data interface{} = this.SafeList(response, "assetPositions", []interface{}{}) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { AppendToArray(&result,this.ParsePosition(GetValue(data, i), nil)) } ch <- this.FilterByArrayPositions(result, "symbol", symbols, false) return nil }() return ch } func (this *hyperliquid) ParsePosition(position interface{}, optionalArgs ...interface{}) interface{} { // // { // "position": { // "coin": "ETH", // "cumFunding": { // "allTime": "0.0", // "sinceChange": "0.0", // "sinceOpen": "0.0" // }, // "entryPx": "2213.9", // "leverage": { // "rawUsd": "-475.23904", // "type": "isolated", // "value": "20" // }, // "liquidationPx": "2125.00856238", // "marginUsed": "24.88097", // "maxLeverage": "50", // "positionValue": "500.12001", // "returnOnEquity": "0.0", // "szi": "0.2259", // "unrealizedPnl": "0.0" // }, // "type": "oneWay" // } // market := GetArg(optionalArgs, 0, nil) _ = market var entry interface{} = this.SafeDict(position, "position", map[string]interface{} {}) var coin interface{} = this.SafeString(entry, "coin") var marketId interface{} = this.CoinToMarketId(coin) market = this.SafeMarket(marketId, nil) var symbol interface{} = GetValue(market, "symbol") var leverage interface{} = this.SafeDict(entry, "leverage", map[string]interface{} {}) var marginMode interface{} = this.SafeString(leverage, "type") var isIsolated interface{} = (IsEqual(marginMode, "isolated")) var rawSize interface{} = this.SafeString(entry, "szi") var size interface{} = rawSize var side interface{} = nil if IsTrue(!IsEqual(size, nil)) { side = Ternary(IsTrue(Precise.StringGt(rawSize, "0")), "long", "short") size = Precise.StringAbs(size) } var rawUnrealizedPnl interface{} = this.SafeString(entry, "unrealizedPnl") var absRawUnrealizedPnl interface{} = Precise.StringAbs(rawUnrealizedPnl) var initialMargin interface{} = this.SafeString(entry, "marginUsed") var percentage interface{} = Precise.StringMul(Precise.StringDiv(absRawUnrealizedPnl, initialMargin), "100") return this.SafePosition(map[string]interface{} { "info": position, "id": nil, "symbol": symbol, "timestamp": nil, "datetime": nil, "isolated": isIsolated, "hedged": nil, "side": side, "contracts": this.ParseNumber(size), "contractSize": nil, "entryPrice": this.SafeNumber(entry, "entryPx"), "markPrice": nil, "notional": this.SafeNumber(entry, "positionValue"), "leverage": this.SafeNumber(leverage, "value"), "collateral": this.SafeNumber(entry, "marginUsed"), "initialMargin": this.ParseNumber(initialMargin), "maintenanceMargin": nil, "initialMarginPercentage": nil, "maintenanceMarginPercentage": nil, "unrealizedPnl": this.ParseNumber(rawUnrealizedPnl), "liquidationPrice": this.SafeNumber(entry, "liquidationPx"), "marginMode": marginMode, "percentage": this.ParseNumber(percentage), }) } /** * @method * @name hyperliquid#setMarginMode * @description set margin mode (symbol) * @param {string} marginMode margin mode must be either [isolated, cross] * @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.leverage] the rate of leverage, is required if setting trade mode (symbol) * @returns {object} response from the exchange */ func (this *hyperliquid) SetMarginMode(marginMode 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 if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " setMarginMode() requires a symbol argument"))) } retRes26568 := (<-this.LoadMarkets()) PanicOnError(retRes26568) var market interface{} = this.Market(symbol) var leverage interface{} = this.SafeInteger(params, "leverage") if IsTrue(IsEqual(leverage, nil)) { panic(ArgumentsRequired(Add(this.Id, " setMarginMode() requires a leverage parameter"))) } var asset interface{} = this.ParseToInt(GetValue(market, "baseId")) var isCross interface{} = (IsEqual(marginMode, "cross")) var nonce interface{} = this.Milliseconds() params = this.Omit(params, []interface{}{"leverage"}) var updateAction interface{} = map[string]interface{} { "type": "updateLeverage", "asset": asset, "isCross": isCross, "leverage": leverage, } var vaultAddress interface{} = this.SafeString(params, "vaultAddress") if IsTrue(!IsEqual(vaultAddress, nil)) { params = this.Omit(params, "vaultAddress") if IsTrue(StartsWith(vaultAddress, "0x")) { vaultAddress = Replace(vaultAddress, "0x", "") } } var signature interface{} = this.SignL1Action(updateAction, nonce, vaultAddress) var request interface{} = map[string]interface{} { "action": updateAction, "nonce": nonce, "signature": signature, } if IsTrue(!IsEqual(vaultAddress, nil)) { AddElementToObject(request, "vaultAddress", vaultAddress) } response:= (<-this.PrivatePostExchange(request)) PanicOnError(response) // // { // 'response': { // 'type': 'default' // }, // 'status': 'ok' // } // ch <- response return nil }() return ch } /** * @method * @name hyperliquid#setLeverage * @description set the level of leverage for a market * @param {float} leverage the rate of leverage * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.marginMode] margin mode must be either [isolated, cross], default is cross * @returns {object} response from the exchange */ func (this *hyperliquid) SetLeverage(leverage 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 if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " setLeverage() requires a symbol argument"))) } retRes27158 := (<-this.LoadMarkets()) PanicOnError(retRes27158) var market interface{} = this.Market(symbol) var marginMode interface{} = this.SafeString(params, "marginMode", "cross") var isCross interface{} = (IsEqual(marginMode, "cross")) var asset interface{} = this.ParseToInt(GetValue(market, "baseId")) var nonce interface{} = this.Milliseconds() params = this.Omit(params, "marginMode") var updateAction interface{} = map[string]interface{} { "type": "updateLeverage", "asset": asset, "isCross": isCross, "leverage": leverage, } var vaultAddress interface{} = this.FormatVaultAddress(this.SafeString(params, "vaultAddress")) var signature interface{} = this.SignL1Action(updateAction, nonce, vaultAddress) var request interface{} = map[string]interface{} { "action": updateAction, "nonce": nonce, "signature": signature, } if IsTrue(!IsEqual(vaultAddress, nil)) { params = this.Omit(params, "vaultAddress") AddElementToObject(request, "vaultAddress", vaultAddress) } response:= (<-this.PrivatePostExchange(request)) PanicOnError(response) // // { // 'response': { // 'type': 'default' // }, // 'status': 'ok' // } // ch <- response return nil }() return ch } /** * @method * @name hyperliquid#addMargin * @description add margin * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-isolated-margin * @param {string} symbol unified market symbol * @param {float} amount amount of margin to add * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [margin structure]{@link https://docs.ccxt.com/#/?id=add-margin-structure} */ func (this *hyperliquid) AddMargin(symbol interface{}, amount 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 retRes276315 := (<-this.ModifyMarginHelper(symbol, amount, "add", params)) PanicOnError(retRes276315) ch <- retRes276315 return nil }() return ch } /** * @method * @name hyperliquid#reduceMargin * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-isolated-margin * @description remove margin from a position * @param {string} symbol unified market symbol * @param {float} amount the amount of margin to remove * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [margin structure]{@link https://docs.ccxt.com/#/?id=reduce-margin-structure} */ func (this *hyperliquid) ReduceMargin(symbol interface{}, amount 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 retRes277715 := (<-this.ModifyMarginHelper(symbol, amount, "reduce", params)) PanicOnError(retRes277715) ch <- retRes277715 return nil }() return ch } func (this *hyperliquid) ModifyMarginHelper(symbol interface{}, amount interface{}, typeVar 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 retRes27818 := (<-this.LoadMarkets()) PanicOnError(retRes27818) var market interface{} = this.Market(symbol) var asset interface{} = this.ParseToInt(GetValue(market, "baseId")) var sz interface{} = this.ParseToInt(Precise.StringMul(this.AmountToPrecision(symbol, amount), "1000000")) if IsTrue(IsEqual(typeVar, "reduce")) { sz = OpNeg(sz) } var nonce interface{} = this.Milliseconds() var updateAction interface{} = map[string]interface{} { "type": "updateIsolatedMargin", "asset": asset, "isBuy": true, "ntli": sz, } var vaultAddress interface{} = this.FormatVaultAddress(this.SafeString(params, "vaultAddress")) var signature interface{} = this.SignL1Action(updateAction, nonce, vaultAddress) var request interface{} = map[string]interface{} { "action": updateAction, "nonce": nonce, "signature": signature, } if IsTrue(!IsEqual(vaultAddress, nil)) { params = this.Omit(params, "vaultAddress") AddElementToObject(request, "vaultAddress", vaultAddress) } response:= (<-this.PrivatePostExchange(request)) PanicOnError(response) // // { // 'response': { // 'type': 'default' // }, // 'status': 'ok' // } // ch <- this.Extend(this.ParseMarginModification(response, market), map[string]interface{} { "code": this.SafeString(response, "status"), }) return nil }() return ch } func (this *hyperliquid) ParseMarginModification(data interface{}, optionalArgs ...interface{}) interface{} { // // { // 'type': 'default' // } // market := GetArg(optionalArgs, 0, nil) _ = market return map[string]interface{} { "info": data, "symbol": this.SafeSymbol(nil, market), "type": nil, "marginMode": "isolated", "amount": nil, "total": nil, "code": this.SafeString(market, "settle"), "status": nil, "timestamp": nil, "datetime": nil, } } /** * @method * @name hyperliquid#transfer * @description transfer currency internally between wallets on the same account * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#l1-usdc-transfer * @param {string} code unified currency code * @param {float} amount amount to transfer * @param {string} fromAccount account to transfer from *spot, swap* * @param {string} toAccount account to transfer to *swap, spot or address* * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.vaultAddress] the vault address for order * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure} */ func (this *hyperliquid) Transfer(code interface{}, amount interface{}, fromAccount interface{}, toAccount 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 this.CheckRequiredCredentials() retRes28568 := (<-this.LoadMarkets()) PanicOnError(retRes28568) var isSandboxMode interface{} = this.SafeBool(this.Options, "sandboxMode") var nonce interface{} = this.Milliseconds() if IsTrue(this.InArray(fromAccount, []interface{}{"spot", "swap", "perp"})) { // handle swap <> spot account transfer if !IsTrue(this.InArray(toAccount, []interface{}{"spot", "swap", "perp"})) { panic(NotSupported(Add(this.Id, " transfer() only support spot <> swap transfer"))) } var strAmount interface{} = this.NumberToString(amount) var vaultAddress interface{} = this.FormatVaultAddress(this.SafeString(params, "vaultAddress")) params = this.Omit(params, "vaultAddress") if IsTrue(!IsEqual(vaultAddress, nil)) { strAmount = Add(Add(strAmount, " subaccount:"), vaultAddress) } var toPerp interface{} = IsTrue((IsEqual(toAccount, "perp"))) || IsTrue((IsEqual(toAccount, "swap"))) var transferPayload interface{} = map[string]interface{} { "hyperliquidChain": Ternary(IsTrue(isSandboxMode), "Testnet", "Mainnet"), "amount": strAmount, "toPerp": toPerp, "nonce": nonce, } var transferSig interface{} = this.BuildUsdClassSendSig(transferPayload) var transferRequest interface{} = map[string]interface{} { "action": map[string]interface{} { "hyperliquidChain": GetValue(transferPayload, "hyperliquidChain"), "signatureChainId": "0x66eee", "type": "usdClassTransfer", "amount": strAmount, "toPerp": toPerp, "nonce": nonce, }, "nonce": nonce, "signature": transferSig, } if IsTrue(!IsEqual(vaultAddress, nil)) { AddElementToObject(transferRequest, "vaultAddress", vaultAddress) } transferResponse:= (<-this.PrivatePostExchange(transferRequest)) PanicOnError(transferResponse) ch <- transferResponse return nil } // handle sub-account/different account transfer this.CheckAddress(toAccount) if IsTrue(!IsEqual(code, nil)) { code = ToUpper(code) if IsTrue(!IsEqual(code, "USDC")) { panic(NotSupported(Add(this.Id, " transfer() only support USDC"))) } } var payload interface{} = map[string]interface{} { "hyperliquidChain": Ternary(IsTrue(isSandboxMode), "Testnet", "Mainnet"), "destination": toAccount, "amount": this.NumberToString(amount), "time": nonce, } var sig interface{} = this.BuildUsdSendSig(payload) var request interface{} = map[string]interface{} { "action": map[string]interface{} { "hyperliquidChain": GetValue(payload, "hyperliquidChain"), "signatureChainId": "0x66eee", "destination": toAccount, "amount": ToString(amount), "time": nonce, "type": "usdSend", }, "nonce": nonce, "signature": sig, } response:= (<-this.PrivatePostExchange(request)) PanicOnError(response) // // {'response': {'type': 'default'}, 'status': 'ok'} // ch <- this.ParseTransfer(response) return nil }() return ch } func (this *hyperliquid) ParseTransfer(transfer interface{}, optionalArgs ...interface{}) interface{} { // // {'response': {'type': 'default'}, 'status': 'ok'} // currency := GetArg(optionalArgs, 0, nil) _ = currency return map[string]interface{} { "info": transfer, "id": nil, "timestamp": nil, "datetime": nil, "currency": nil, "amount": nil, "fromAccount": nil, "toAccount": nil, "status": "ok", } } /** * @method * @name hyperliquid#withdraw * @description make a withdrawal (only support USDC) * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#initiate-a-withdrawal-request * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#deposit-or-withdraw-from-a-vault * @param {string} code unified currency code * @param {float} amount the amount to withdraw * @param {string} address the address to withdraw to * @param {string} tag * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.vaultAddress] vault address withdraw from * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *hyperliquid) 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 this.CheckRequiredCredentials() retRes29638 := (<-this.LoadMarkets()) PanicOnError(retRes29638) this.CheckAddress(address) if IsTrue(!IsEqual(code, nil)) { code = ToUpper(code) if IsTrue(!IsEqual(code, "USDC")) { panic(NotSupported(Add(this.Id, " withdraw() only support USDC"))) } } var vaultAddress interface{} = this.FormatVaultAddress(this.SafeString(params, "vaultAddress")) params = this.Omit(params, "vaultAddress") var nonce interface{} = this.Milliseconds() var action interface{} = map[string]interface{} {} var sig interface{} = nil if IsTrue(!IsEqual(vaultAddress, nil)) { action = map[string]interface{} { "type": "vaultTransfer", "vaultAddress": Add("0x", vaultAddress), "isDeposit": false, "usd": amount, } sig = this.SignL1Action(action, nonce) } else { var isSandboxMode interface{} = this.SafeBool(this.Options, "sandboxMode", false) var payload interface{} = map[string]interface{} { "hyperliquidChain": Ternary(IsTrue(isSandboxMode), "Testnet", "Mainnet"), "destination": address, "amount": ToString(amount), "time": nonce, } sig = this.BuildWithdrawSig(payload) action = map[string]interface{} { "hyperliquidChain": GetValue(payload, "hyperliquidChain"), "signatureChainId": "0x66eee", "destination": address, "amount": ToString(amount), "time": nonce, "type": "withdraw3", } } var request interface{} = map[string]interface{} { "action": action, "nonce": nonce, "signature": sig, } response:= (<-this.PrivatePostExchange(request)) PanicOnError(response) ch <- this.ParseTransaction(response) return nil }() return ch } func (this *hyperliquid) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} { // // { status: 'ok', response: { type: 'default' } } // // fetchDeposits / fetchWithdrawals // { // "time":1724762307531, // "hash":"0x620a234a7e0eb7930575040f59482a01050058b0802163b4767bfd9033e77781", // "delta":{ // "type":"accountClassTransfer", // "usdc":"50.0", // "toPerp":false // } // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var timestamp interface{} = this.SafeInteger(transaction, "time") var delta interface{} = this.SafeDict(transaction, "delta", map[string]interface{} {}) var fee interface{} = nil var feeCost interface{} = this.SafeInteger(delta, "fee") if IsTrue(!IsEqual(feeCost, nil)) { fee = map[string]interface{} { "currency": "USDC", "cost": feeCost, } } var internal interface{} = nil var typeVar interface{} = this.SafeString(delta, "type") if IsTrue(!IsEqual(typeVar, nil)) { internal = (IsEqual(typeVar, "internalTransfer")) } return map[string]interface{} { "info": transaction, "id": nil, "txid": this.SafeString(transaction, "hash"), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "network": nil, "address": nil, "addressTo": this.SafeString(delta, "destination"), "addressFrom": this.SafeString(delta, "user"), "tag": nil, "tagTo": nil, "tagFrom": nil, "type": nil, "amount": this.SafeInteger(delta, "usdc"), "currency": nil, "status": this.SafeString(transaction, "status"), "updated": nil, "comment": nil, "internal": internal, "fee": fee, } } /** * @method * @name hyperliquid#fetchTradingFee * @description fetch the trading fees for a market * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.user] user address, will default to this.walletAddress if not provided * @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure} */ func (this *hyperliquid) FetchTradingFee(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 retRes30758 := (<-this.LoadMarkets()) PanicOnError(retRes30758) var userAddress interface{} = nil userAddressparamsVariable := this.HandlePublicAddress("fetchTradingFee", params); userAddress = GetValue(userAddressparamsVariable,0); params = GetValue(userAddressparamsVariable,1) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "type": "userFees", "user": userAddress, } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // { // "dailyUserVlm": [ // { // "date": "2024-07-08", // "userCross": "0.0", // "userAdd": "0.0", // "exchange": "90597185.23639999" // } // ], // "feeSchedule": { // "cross": "0.00035", // "add": "0.0001", // "tiers": { // "vip": [ // { // "ntlCutoff": "5000000.0", // "cross": "0.0003", // "add": "0.00005" // } // ], // "mm": [ // { // "makerFractionCutoff": "0.005", // "add": "-0.00001" // } // ] // }, // "referralDiscount": "0.04" // }, // "userCrossRate": "0.00035", // "userAddRate": "0.0001", // "activeReferralDiscount": "0.0" // } // var data interface{} = map[string]interface{} { "userCrossRate": this.SafeString(response, "userCrossRate"), "userAddRate": this.SafeString(response, "userAddRate"), } ch <- this.ParseTradingFee(data, market) return nil }() return ch } func (this *hyperliquid) ParseTradingFee(fee interface{}, optionalArgs ...interface{}) interface{} { // // { // "dailyUserVlm": [ // { // "date": "2024-07-08", // "userCross": "0.0", // "userAdd": "0.0", // "exchange": "90597185.23639999" // } // ], // "feeSchedule": { // "cross": "0.00035", // "add": "0.0001", // "tiers": { // "vip": [ // { // "ntlCutoff": "5000000.0", // "cross": "0.0003", // "add": "0.00005" // } // ], // "mm": [ // { // "makerFractionCutoff": "0.005", // "add": "-0.00001" // } // ] // }, // "referralDiscount": "0.04" // }, // "userCrossRate": "0.00035", // "userAddRate": "0.0001", // "activeReferralDiscount": "0.0" // } // market := GetArg(optionalArgs, 0, nil) _ = market var symbol interface{} = this.SafeSymbol(nil, market) return map[string]interface{} { "info": fee, "symbol": symbol, "maker": this.SafeNumber(fee, "userAddRate"), "taker": this.SafeNumber(fee, "userCrossRate"), "percentage": nil, "tierBased": nil, } } /** * @method * @name hyperliquid#fetchLedger * @description fetch the history of changes, actions done by the user or operations that altered the balance of the user * @param {string} [code] unified currency code * @param {int} [since] timestamp in ms of the earliest ledger entry * @param {int} [limit] max number of ledger entries to return * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] timestamp in ms of the latest ledger entry * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger} */ func (this *hyperliquid) 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 retRes31858 := (<-this.LoadMarkets()) PanicOnError(retRes31858) var userAddress interface{} = nil userAddressparamsVariable := this.HandlePublicAddress("fetchLedger", params); userAddress = GetValue(userAddressparamsVariable,0); params = GetValue(userAddressparamsVariable,1) var request interface{} = map[string]interface{} { "type": "userNonFundingLedgerUpdates", "user": userAddress, } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTime", since) } var until interface{} = this.SafeInteger(params, "until") if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "endTime", until) params = this.Omit(params, []interface{}{"until"}) } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // [ // { // "time":1724762307531, // "hash":"0x620a234a7e0eb7930575040f59482a01050058b0802163b4767bfd9033e77781", // "delta":{ // "type":"accountClassTransfer", // "usdc":"50.0", // "toPerp":false // } // } // ] // ch <- this.ParseLedger(response, nil, since, limit) return nil }() return ch } func (this *hyperliquid) ParseLedgerEntry(item interface{}, optionalArgs ...interface{}) interface{} { // // { // "time":1724762307531, // "hash":"0x620a234a7e0eb7930575040f59482a01050058b0802163b4767bfd9033e77781", // "delta":{ // "type":"accountClassTransfer", // "usdc":"50.0", // "toPerp":false // } // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var timestamp interface{} = this.SafeInteger(item, "time") var delta interface{} = this.SafeDict(item, "delta", map[string]interface{} {}) var fee interface{} = nil var feeCost interface{} = this.SafeInteger(delta, "fee") if IsTrue(!IsEqual(feeCost, nil)) { fee = map[string]interface{} { "currency": "USDC", "cost": feeCost, } } var typeVar interface{} = this.SafeString(delta, "type") var amount interface{} = this.SafeString(delta, "usdc") return this.SafeLedgerEntry(map[string]interface{} { "info": item, "id": this.SafeString(item, "hash"), "direction": nil, "account": nil, "referenceAccount": this.SafeString(delta, "user"), "referenceId": this.SafeString(item, "hash"), "type": this.ParseLedgerEntryType(typeVar), "currency": nil, "amount": this.ParseNumber(amount), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "before": nil, "after": nil, "status": nil, "fee": fee, }, currency) } func (this *hyperliquid) ParseLedgerEntryType(typeVar interface{}) interface{} { var ledgerType interface{} = map[string]interface{} { "internalTransfer": "transfer", "accountClassTransfer": "transfer", } return this.SafeString(ledgerType, typeVar, typeVar) } /** * @method * @name hyperliquid#fetchDeposits * @description fetch all deposits made to an account * @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 {int} [params.until] the latest time in ms to fetch withdrawals for * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *hyperliquid) 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 retRes32808 := (<-this.LoadMarkets()) PanicOnError(retRes32808) var userAddress interface{} = nil userAddressparamsVariable := this.HandlePublicAddress("fetchDepositsWithdrawals", params); userAddress = GetValue(userAddressparamsVariable,0); params = GetValue(userAddressparamsVariable,1) var request interface{} = map[string]interface{} { "type": "userNonFundingLedgerUpdates", "user": userAddress, } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTime", since) } var until interface{} = this.SafeInteger(params, "until") if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "endTime", until) params = this.Omit(params, []interface{}{"until"}) } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // [ // { // "time":1724762307531, // "hash":"0x620a234a7e0eb7930575040f59482a01050058b0802163b4767bfd9033e77781", // "delta":{ // "type":"accountClassTransfer", // "usdc":"50.0", // "toPerp":false // } // } // ] // var records interface{} = this.ExtractTypeFromDelta(response) var deposits interface{} = this.FilterByArray(records, "type", []interface{}{"deposit"}, false) ch <- this.ParseTransactions(deposits, nil, since, limit) return nil }() return ch } /** * @method * @name hyperliquid#fetchWithdrawals * @description fetch all withdrawals made from an account * @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 {int} [params.until] the latest time in ms to fetch withdrawals for * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *hyperliquid) 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 retRes33268 := (<-this.LoadMarkets()) PanicOnError(retRes33268) var userAddress interface{} = nil userAddressparamsVariable := this.HandlePublicAddress("fetchDepositsWithdrawals", params); userAddress = GetValue(userAddressparamsVariable,0); params = GetValue(userAddressparamsVariable,1) var request interface{} = map[string]interface{} { "type": "userNonFundingLedgerUpdates", "user": userAddress, } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTime", since) } var until interface{} = this.SafeInteger(params, "until") if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "endTime", until) params = this.Omit(params, []interface{}{"until"}) } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // [ // { // "time":1724762307531, // "hash":"0x620a234a7e0eb7930575040f59482a01050058b0802163b4767bfd9033e77781", // "delta":{ // "type":"accountClassTransfer", // "usdc":"50.0", // "toPerp":false // } // } // ] // var records interface{} = this.ExtractTypeFromDelta(response) var withdrawals interface{} = this.FilterByArray(records, "type", []interface{}{"withdraw"}, false) ch <- this.ParseTransactions(withdrawals, nil, since, limit) return nil }() return ch } /** * @method * @name hyperliquid#fetchOpenInterests * @description Retrieves the open interest for a list of symbols * @param {string[]} [symbols] Unified CCXT market symbol * @param {object} [params] exchange specific parameters * @returns {object} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure} */ func (this *hyperliquid) FetchOpenInterests(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 retRes33698 := (<-this.LoadMarkets()) PanicOnError(retRes33698) symbols = this.MarketSymbols(symbols) swapMarkets:= (<-this.FetchSwapMarkets()) PanicOnError(swapMarkets) ch <- this.ParseOpenInterests(swapMarkets, symbols) return nil }() return ch } /** * @method * @name hyperliquid#fetchOpenInterest * @description retrieves the open interest of a contract trading pair * @param {string} symbol unified CCXT market symbol * @param {object} [params] exchange specific parameters * @returns {object} an [open interest structure]{@link https://docs.ccxt.com/#/?id=open-interest-structure} */ func (this *hyperliquid) FetchOpenInterest(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 symbol = this.Symbol(symbol) retRes33858 := (<-this.LoadMarkets()) PanicOnError(retRes33858) ois:= (<-this.FetchOpenInterests([]interface{}{symbol}, params)) PanicOnError(ois) ch <- GetValue(ois, symbol) return nil }() return ch } func (this *hyperliquid) ParseOpenInterest(interest interface{}, optionalArgs ...interface{}) interface{} { // // { // szDecimals: '2', // name: 'HYPE', // maxLeverage: '3', // funding: '0.00014735', // openInterest: '14677900.74', // prevDayPx: '26.145', // dayNtlVlm: '299643445.12560016', // premium: '0.00081613', // oraclePx: '27.569', // markPx: '27.63', // midPx: '27.599', // impactPxs: [ '27.5915', '27.6319' ], // dayBaseVlm: '10790652.83', // baseId: 159 // } // market := GetArg(optionalArgs, 0, nil) _ = market interest = this.SafeDict(interest, "info", map[string]interface{} {}) var coin interface{} = this.SafeString(interest, "name") var marketId interface{} = nil if IsTrue(!IsEqual(coin, nil)) { marketId = this.CoinToMarketId(coin) } return this.SafeOpenInterest(map[string]interface{} { "symbol": this.SafeSymbol(marketId), "openInterestAmount": this.SafeNumber(interest, "openInterest"), "openInterestValue": nil, "timestamp": nil, "datetime": nil, "info": interest, }, market) } /** * @method * @name hyperliquid#fetchFundingHistory * @description fetch the history of funding payments paid and received on this account * @param {string} [symbol] unified market symbol * @param {int} [since] the earliest time in ms to fetch funding history for * @param {int} [limit] the maximum number of funding history structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [funding history structure]{@link https://docs.ccxt.com/#/?id=funding-history-structure} */ func (this *hyperliquid) FetchFundingHistory(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 retRes34368 := (<-this.LoadMarkets()) PanicOnError(retRes34368) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var userAddress interface{} = nil userAddressparamsVariable := this.HandlePublicAddress("fetchFundingHistory", params); userAddress = GetValue(userAddressparamsVariable,0); params = GetValue(userAddressparamsVariable,1) var request interface{} = map[string]interface{} { "user": userAddress, "type": "userFunding", } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTime", since) } var until interface{} = this.SafeInteger(params, "until") params = this.Omit(params, "until") if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "endTime", until) } response:= (<-this.PublicPostInfo(this.Extend(request, params))) PanicOnError(response) // // [ // { // "time": 1734026400057, // "hash": "0x0000000000000000000000000000000000000000000000000000000000000000", // "delta": { // "type": "funding", // "coin": "SOL", // "usdc": "75.635093", // "szi": "-7375.9", // "fundingRate": "0.00004381", // "nSamples": null // } // } // ] // ch <- this.ParseIncomes(response, market, since, limit) return nil }() return ch } func (this *hyperliquid) ParseIncome(income interface{}, optionalArgs ...interface{}) interface{} { // // { // "time": 1734026400057, // "hash": "0x0000000000000000000000000000000000000000000000000000000000000000", // "delta": { // "type": "funding", // "coin": "SOL", // "usdc": "75.635093", // "szi": "-7375.9", // "fundingRate": "0.00004381", // "nSamples": null // } // } // market := GetArg(optionalArgs, 0, nil) _ = market var id interface{} = this.SafeString(income, "hash") var timestamp interface{} = this.SafeInteger(income, "time") var delta interface{} = this.SafeDict(income, "delta") var baseId interface{} = this.SafeString(delta, "coin") var marketSymbol interface{} = Add(baseId, "/USDC:USDC") market = this.SafeMarket(marketSymbol) var symbol interface{} = GetValue(market, "symbol") var amount interface{} = this.SafeString(delta, "usdc") var code interface{} = this.SafeCurrencyCode("USDC") var rate interface{} = this.SafeNumber(delta, "fundingRate") return map[string]interface{} { "info": income, "symbol": symbol, "code": code, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "id": id, "amount": this.ParseNumber(amount), "rate": rate, } } func (this *hyperliquid) ExtractTypeFromDelta(optionalArgs ...interface{}) interface{} { data := GetArg(optionalArgs, 0, []interface{}{}) _ = data var records interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var record interface{} = GetValue(data, i) AddElementToObject(record, "type", GetValue(GetValue(record, "delta"), "type")) AppendToArray(&records,record) } return records } func (this *hyperliquid) FormatVaultAddress(optionalArgs ...interface{}) interface{} { address := GetArg(optionalArgs, 0, nil) _ = address if IsTrue(IsEqual(address, nil)) { return nil } if IsTrue(StartsWith(address, "0x")) { return Replace(address, "0x", "") } return address } func (this *hyperliquid) HandlePublicAddress(methodName interface{}, params interface{}) interface{} { var userAux interface{} = nil userAuxparamsVariable := this.HandleOptionAndParams(params, methodName, "user"); userAux = GetValue(userAuxparamsVariable,0); params = GetValue(userAuxparamsVariable,1) var user interface{} = userAux userparamsVariable := this.HandleOptionAndParams(params, methodName, "address", userAux); user = GetValue(userparamsVariable,0); params = GetValue(userparamsVariable,1) if IsTrue(IsTrue((!IsEqual(user, nil))) && IsTrue((!IsEqual(user, "")))) { return []interface{}{user, params} } if IsTrue(IsTrue((!IsEqual(this.WalletAddress, nil))) && IsTrue((!IsEqual(this.WalletAddress, "")))) { return []interface{}{this.WalletAddress, params} } panic(ArgumentsRequired(Add(Add(Add(this.Id, " "), methodName), "() requires a user parameter inside \\'params\\' or the wallet address set"))) } func (this *hyperliquid) CoinToMarketId(coin interface{}) interface{} { if IsTrue(IsTrue(IsGreaterThan(GetIndexOf(coin, "/"), OpNeg(1))) || IsTrue(IsGreaterThan(GetIndexOf(coin, "@"), OpNeg(1)))) { return coin // spot } return Add(coin, "/USDC:USDC") } func (this *hyperliquid) HandleErrors(code interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} { if !IsTrue(response) { return nil // fallback to default error handler } // {"status":"err","response":"User or API Wallet 0xb8a6f8b26223de27c31938d56e470a5b832703a5 does not exist."} // // { // status: 'ok', // response: { type: 'order', data: { statuses: [ { error: 'Insufficient margin to place order. asset=4' } ] } } // } // {"status":"ok","response":{"type":"order","data":{"statuses":[{"error":"Insufficient margin to place order. asset=84"}]}}} // var status interface{} = this.SafeString(response, "status", "") var message interface{} = nil if IsTrue(IsEqual(status, "err")) { message = this.SafeString(response, "response") } else { var responsePayload interface{} = this.SafeDict(response, "response", map[string]interface{} {}) var data interface{} = this.SafeDict(responsePayload, "data", map[string]interface{} {}) var statuses interface{} = this.SafeList(data, "statuses", []interface{}{}) var firstStatus interface{} = this.SafeDict(statuses, 0) message = this.SafeString(firstStatus, "error") } var feedback interface{} = Add(Add(this.Id, " "), body) var nonEmptyMessage interface{} = (IsTrue((!IsEqual(message, nil))) && IsTrue((!IsEqual(message, "")))) if IsTrue(nonEmptyMessage) { this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), message, feedback) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), message, feedback) } if IsTrue(nonEmptyMessage) { panic(ExchangeError(feedback)) } return nil } func (this *hyperliquid) Sign(path interface{}, optionalArgs ...interface{}) interface{} { api := GetArg(optionalArgs, 0, "public") _ = 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 url interface{} = Add(Add(this.ImplodeHostname(GetValue(GetValue(this.Urls, "api"), api)), "/"), path) if IsTrue(IsEqual(method, "POST")) { headers = map[string]interface{} { "Content-Type": "application/json", } body = this.Json(params) } return map[string]interface{} { "url": url, "method": method, "body": body, "headers": headers, } } func (this *hyperliquid) CalculateRateLimiterCost(api interface{}, method interface{}, path interface{}, params interface{}, optionalArgs ...interface{}) interface{} { config := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = config if IsTrue(IsTrue((InOp(config, "byType"))) && IsTrue((InOp(params, "type")))) { var typeVar interface{} = GetValue(params, "type") var byType interface{} = GetValue(config, "byType") if IsTrue(InOp(byType, typeVar)) { return GetValue(byType, typeVar) } } return this.SafeValue(config, "cost", 1) } func (this *hyperliquid) ParseCreateOrderArgs(symbol interface{}, typeVar interface{}, side interface{}, amount interface{}, optionalArgs ...interface{}) interface{} { price := GetArg(optionalArgs, 0, nil) _ = price params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params var market interface{} = this.Market(symbol) var vaultAddress interface{} = this.SafeString(params, "vaultAddress") params = this.Omit(params, "vaultAddress") symbol = GetValue(market, "symbol") var order interface{} = map[string]interface{} { "symbol": symbol, "type": typeVar, "side": side, "amount": amount, "price": price, "params": params, } var globalParams interface{} = map[string]interface{} {} if IsTrue(!IsEqual(vaultAddress, nil)) { AddElementToObject(globalParams, "vaultAddress", vaultAddress) } return []interface{}{order, globalParams} } func (this *hyperliquid) Init(userConfig map[string]interface{}) { this.Exchange = Exchange{} this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this) this.Exchange.DerivedExchange = this }