3028 lines
144 KiB
Go
3028 lines
144 KiB
Go
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 wavesexchange struct {
|
|
Exchange
|
|
|
|
}
|
|
|
|
func NewWavesexchangeCore() wavesexchange {
|
|
p := wavesexchange{}
|
|
setDefaults(&p)
|
|
return p
|
|
}
|
|
|
|
func (this *wavesexchange) Describe() interface{} {
|
|
return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} {
|
|
"id": "wavesexchange",
|
|
"name": "Waves.Exchange",
|
|
"countries": []interface{}{"CH"},
|
|
"certified": false,
|
|
"pro": false,
|
|
"dex": true,
|
|
"has": map[string]interface{} {
|
|
"CORS": nil,
|
|
"spot": true,
|
|
"margin": false,
|
|
"swap": false,
|
|
"future": false,
|
|
"option": false,
|
|
"addMargin": false,
|
|
"cancelOrder": true,
|
|
"closeAllPositions": false,
|
|
"closePosition": false,
|
|
"createMarketOrder": true,
|
|
"createOrder": true,
|
|
"createReduceOnlyOrder": false,
|
|
"createStopLimitOrder": false,
|
|
"createStopMarketOrder": false,
|
|
"createStopOrder": false,
|
|
"fetchBalance": true,
|
|
"fetchBorrowRateHistories": false,
|
|
"fetchBorrowRateHistory": false,
|
|
"fetchClosedOrders": true,
|
|
"fetchCrossBorrowRate": false,
|
|
"fetchCrossBorrowRates": false,
|
|
"fetchDepositAddress": true,
|
|
"fetchDepositAddresses": nil,
|
|
"fetchDepositAddressesByNetwork": nil,
|
|
"fetchDepositWithdrawFee": "emulated",
|
|
"fetchDepositWithdrawFees": true,
|
|
"fetchFundingHistory": false,
|
|
"fetchFundingRate": false,
|
|
"fetchFundingRateHistory": false,
|
|
"fetchFundingRates": false,
|
|
"fetchIndexOHLCV": false,
|
|
"fetchIsolatedBorrowRate": false,
|
|
"fetchIsolatedBorrowRates": false,
|
|
"fetchLeverage": false,
|
|
"fetchLeverageTiers": false,
|
|
"fetchMarginMode": false,
|
|
"fetchMarkets": true,
|
|
"fetchMarkOHLCV": false,
|
|
"fetchMyTrades": true,
|
|
"fetchOHLCV": true,
|
|
"fetchOpenInterestHistory": false,
|
|
"fetchOpenOrders": true,
|
|
"fetchOrder": true,
|
|
"fetchOrderBook": true,
|
|
"fetchOrders": true,
|
|
"fetchPosition": false,
|
|
"fetchPositionHistory": false,
|
|
"fetchPositionMode": false,
|
|
"fetchPositions": false,
|
|
"fetchPositionsForSymbol": false,
|
|
"fetchPositionsHistory": false,
|
|
"fetchPositionsRisk": false,
|
|
"fetchPremiumIndexOHLCV": false,
|
|
"fetchTicker": true,
|
|
"fetchTickers": true,
|
|
"fetchTrades": true,
|
|
"fetchTransfer": false,
|
|
"fetchTransfers": false,
|
|
"reduceMargin": false,
|
|
"sandbox": true,
|
|
"setLeverage": false,
|
|
"setMarginMode": false,
|
|
"setPositionMode": false,
|
|
"signIn": true,
|
|
"transfer": false,
|
|
"withdraw": true,
|
|
"ws": false,
|
|
},
|
|
"timeframes": map[string]interface{} {
|
|
"1m": "1m",
|
|
"5m": "5m",
|
|
"15m": "15m",
|
|
"30m": "30m",
|
|
"1h": "1h",
|
|
"2h": "2h",
|
|
"3h": "3h",
|
|
"4h": "4h",
|
|
"6h": "6h",
|
|
"12h": "12h",
|
|
"1d": "1d",
|
|
"1w": "1w",
|
|
"1M": "1M",
|
|
},
|
|
"urls": map[string]interface{} {
|
|
"logo": "https://user-images.githubusercontent.com/1294454/84547058-5fb27d80-ad0b-11ea-8711-78ac8b3c7f31.jpg",
|
|
"test": map[string]interface{} {
|
|
"matcher": "https://matcher-testnet.wx.network",
|
|
"node": "https://nodes-testnet.wavesnodes.com",
|
|
"public": "https://api-testnet.wavesplatform.com/v0",
|
|
"private": "https://api-testnet.wx.network/v1",
|
|
"forward": "https://testnet.wx.network/api/v1/forward/matcher",
|
|
"market": "https://testnet.wx.network/api/v1/forward/marketdata/api/v1",
|
|
},
|
|
"api": map[string]interface{} {
|
|
"matcher": "https://matcher.wx.network",
|
|
"node": "https://nodes.wx.network",
|
|
"public": "https://api.wavesplatform.com/v0",
|
|
"private": "https://api.wx.network/v1",
|
|
"forward": "https://wx.network/api/v1/forward/matcher",
|
|
"market": "https://wx.network/api/v1/forward/marketdata/api/v1",
|
|
},
|
|
"doc": []interface{}{"https://docs.wx.network", "https://docs.waves.tech", "https://api.wavesplatform.com/v0/docs/", "https://nodes.wavesnodes.com/api-docs/index.html", "https://matcher.waves.exchange/api-docs/index.html"},
|
|
"www": "https://wx.network",
|
|
},
|
|
"api": map[string]interface{} {
|
|
"matcher": map[string]interface{} {
|
|
"get": []interface{}{"matcher", "matcher/settings", "matcher/settings/rates", "matcher/balance/reserved/{publicKey}", "matcher/debug/allSnashotOffsets", "matcher/debug/currentOffset", "matcher/debug/lastOffset", "matcher/debug/oldestSnapshotOffset", "matcher/debug/config", "matcher/debug/address/{address}", "matcher/debug/status", "matcher/debug/address/{address}/check", "matcher/orderbook", "matcher/orderbook/{baseId}/{quoteId}", "matcher/orderbook/{baseId}/{quoteId}/publicKey/{publicKey}", "matcher/orderbook/{baseId}/{quoteId}/{orderId}", "matcher/orderbook/{baseId}/{quoteId}/info", "matcher/orderbook/{baseId}/{quoteId}/status", "matcher/orderbook/{baseId}/{quoteId}/tradableBalance/{address}", "matcher/orderbook/{publicKey}", "matcher/orderbook/{publicKey}/{orderId}", "matcher/orders/{address}", "matcher/orders/{address}/{orderId}", "matcher/transactions/{orderId}", "api/v1/orderbook/{baseId}/{quoteId}"},
|
|
"post": []interface{}{"matcher/orderbook", "matcher/orderbook/market", "matcher/orderbook/cancel", "matcher/orderbook/{baseId}/{quoteId}/cancel", "matcher/orderbook/{baseId}/{quoteId}/calculateFee", "matcher/orderbook/{baseId}/{quoteId}/delete", "matcher/orderbook/{baseId}/{quoteId}/cancelAll", "matcher/debug/saveSnapshots", "matcher/orders/{address}/cancel", "matcher/orders/cancel/{orderId}", "matcher/orders/serialize"},
|
|
"delete": []interface{}{"matcher/orderbook/{baseId}/{quoteId}", "matcher/settings/rates/{assetId}"},
|
|
"put": []interface{}{"matcher/settings/rates/{assetId}"},
|
|
},
|
|
"node": map[string]interface{} {
|
|
"get": []interface{}{"addresses", "addresses/balance/{address}", "addresses/balance/{address}/{confirmations}", "addresses/balance/details/{address}", "addresses/data/{address}", "addresses/data/{address}/{key}", "addresses/effectiveBalance/{address}", "addresses/effectiveBalance/{address}/{confirmations}", "addresses/publicKey/{publicKey}", "addresses/scriptInfo/{address}", "addresses/scriptInfo/{address}/meta", "addresses/seed/{address}", "addresses/seq/{from}/{to}", "addresses/validate/{address}", "alias/by-address/{address}", "alias/by-alias/{alias}", "assets/{assetId}/distribution/{height}/{limit}", "assets/balance/{address}", "assets/balance/{address}/{assetId}", "assets/details/{assetId}", "assets/nft/{address}/limit/{limit}", "blockchain/rewards", "blockchain/rewards/height", "blocks/address/{address}/{from}/{to}/", "blocks/at/{height}", "blocks/delay/{signature}/{blockNum}", "blocks/first", "blocks/headers/last", "blocks/headers/seq/{from}/{to}", "blocks/height", "blocks/height/{signature}", "blocks/last", "blocks/seq/{from}/{to}", "blocks/signature/{signature}", "consensus/algo", "consensus/basetarget", "consensus/basetarget/{blockId}", "consensus/{generatingbalance}/address", "consensus/generationsignature", "consensus/generationsignature/{blockId}", "debug/balances/history/{address}", "debug/blocks/{howMany}", "debug/configInfo", "debug/historyInfo", "debug/info", "debug/minerInfo", "debug/portfolios/{address}", "debug/state", "debug/stateChanges/address/{address}", "debug/stateChanges/info/{id}", "debug/stateWaves/{height}", "leasing/active/{address}", "node/state", "node/version", "peers/all", "peers/blacklisted", "peers/connected", "peers/suspended", "transactions/address/{address}/limit/{limit}", "transactions/info/{id}", "transactions/status", "transactions/unconfirmed", "transactions/unconfirmed/info/{id}", "transactions/unconfirmed/size", "utils/seed", "utils/seed/{length}", "utils/time", "wallet/seed"},
|
|
"post": []interface{}{"addresses", "addresses/data/{address}", "addresses/sign/{address}", "addresses/signText/{address}", "addresses/verify/{address}", "addresses/verifyText/{address}", "debug/blacklist", "debug/print", "debug/rollback", "debug/validate", "node/stop", "peers/clearblacklist", "peers/connect", "transactions/broadcast", "transactions/calculateFee", "tranasctions/sign", "transactions/sign/{signerAddress}", "tranasctions/status", "utils/hash/fast", "utils/hash/secure", "utils/script/compileCode", "utils/script/compileWithImports", "utils/script/decompile", "utils/script/estimate", "utils/sign/{privateKey}", "utils/transactionsSerialize"},
|
|
"delete": []interface{}{"addresses/{address}", "debug/rollback-to/{signature}"},
|
|
},
|
|
"public": map[string]interface{} {
|
|
"get": []interface{}{"assets", "pairs", "candles/{baseId}/{quoteId}", "transactions/exchange"},
|
|
},
|
|
"private": map[string]interface{} {
|
|
"get": []interface{}{"deposit/addresses/{currency}", "deposit/addresses/{currency}/{platform}", "platforms", "deposit/currencies", "withdraw/currencies", "withdraw/addresses/{currency}/{address}"},
|
|
"post": []interface{}{"oauth2/token"},
|
|
},
|
|
"forward": map[string]interface{} {
|
|
"get": []interface{}{"matcher/orders/{address}", "matcher/orders/{address}/{orderId}"},
|
|
"post": []interface{}{"matcher/orders/{wavesAddress}/cancel"},
|
|
},
|
|
"market": map[string]interface{} {
|
|
"get": []interface{}{"tickers"},
|
|
},
|
|
},
|
|
"currencies": map[string]interface{} {
|
|
"WX": this.SafeCurrencyStructure(map[string]interface{} {
|
|
"id": "EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc",
|
|
"numericId": nil,
|
|
"code": "WX",
|
|
"precision": this.ParseNumber("1e-8"),
|
|
}),
|
|
},
|
|
"precisionMode": TICK_SIZE,
|
|
"options": map[string]interface{} {
|
|
"allowedCandles": 1440,
|
|
"accessToken": nil,
|
|
"createMarketBuyOrderRequiresPrice": true,
|
|
"matcherPublicKey": nil,
|
|
"quotes": nil,
|
|
"createOrderDefaultExpiry": 2419200000,
|
|
"wavesAddress": nil,
|
|
"withdrawFeeUSDN": 7420,
|
|
"withdrawFeeWAVES": 100000,
|
|
"wavesPrecision": 1e-8,
|
|
"messagePrefix": "W",
|
|
"networks": map[string]interface{} {
|
|
"ERC20": "ETH",
|
|
"BEP20": "BSC",
|
|
},
|
|
},
|
|
"features": map[string]interface{} {
|
|
"spot": map[string]interface{} {
|
|
"sandbox": true,
|
|
"createOrder": map[string]interface{} {
|
|
"marginMode": false,
|
|
"triggerPrice": true,
|
|
"triggerDirection": false,
|
|
"triggerPriceType": nil,
|
|
"stopLossPrice": false,
|
|
"takeProfitPrice": false,
|
|
"attachedStopLossTakeProfit": nil,
|
|
"timeInForce": map[string]interface{} {
|
|
"IOC": false,
|
|
"FOK": false,
|
|
"PO": false,
|
|
"GTD": true,
|
|
},
|
|
"hedged": false,
|
|
"trailing": false,
|
|
"leverage": false,
|
|
"marketBuyByCost": false,
|
|
"marketBuyRequiresPrice": true,
|
|
"selfTradePrevention": false,
|
|
"iceberg": false,
|
|
},
|
|
"createOrders": nil,
|
|
"fetchMyTrades": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": 100,
|
|
"daysBack": 100000,
|
|
"untilDays": 100000,
|
|
"symbolRequired": false,
|
|
},
|
|
"fetchOrder": map[string]interface{} {
|
|
"marginMode": false,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": false,
|
|
},
|
|
"fetchOpenOrders": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": 100,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": false,
|
|
},
|
|
"fetchOrders": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": 100,
|
|
"daysBack": nil,
|
|
"untilDays": nil,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": true,
|
|
},
|
|
"fetchClosedOrders": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": 100,
|
|
"daysBack": 100000,
|
|
"daysBackCanceled": 1,
|
|
"untilDays": 100000,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": false,
|
|
},
|
|
"fetchOHLCV": map[string]interface{} {
|
|
"limit": nil,
|
|
},
|
|
},
|
|
"swap": map[string]interface{} {
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
},
|
|
"future": map[string]interface{} {
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
},
|
|
},
|
|
"commonCurrencies": map[string]interface{} {
|
|
"EGG": "Waves Ducks",
|
|
},
|
|
"requiresEddsa": true,
|
|
"exceptions": map[string]interface{} {
|
|
"3147270": InsufficientFunds,
|
|
"112": InsufficientFunds,
|
|
"4": ExchangeError,
|
|
"13": ExchangeNotAvailable,
|
|
"14": ExchangeNotAvailable,
|
|
"3145733": AccountSuspended,
|
|
"3148040": DuplicateOrderId,
|
|
"3148801": AuthenticationError,
|
|
"9440512": AuthenticationError,
|
|
"9440771": BadSymbol,
|
|
"9441026": InvalidOrder,
|
|
"9441282": InvalidOrder,
|
|
"9441286": InvalidOrder,
|
|
"9441295": InvalidOrder,
|
|
"9441540": InvalidOrder,
|
|
"9441542": InvalidOrder,
|
|
"106954752": AuthenticationError,
|
|
"106954769": AuthenticationError,
|
|
"106957828": AuthenticationError,
|
|
"106960131": AuthenticationError,
|
|
"106981137": AuthenticationError,
|
|
"9437184": BadRequest,
|
|
"9437193": OrderNotFound,
|
|
"1048577": BadRequest,
|
|
"1051904": AuthenticationError,
|
|
},
|
|
})
|
|
}
|
|
func (this *wavesexchange) SetSandboxMode(enabled interface{}) {
|
|
AddElementToObject(this.Options, "messagePrefix", Ternary(IsTrue(enabled), "T", "W"))
|
|
AddElementToObject(this.Options, "sandboxMode", enabled)
|
|
this.Exchange.SetSandboxMode(enabled)
|
|
}
|
|
func (this *wavesexchange) GetFeesForAsset(symbol interface{}, side interface{}, amount interface{}, price 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
|
|
|
|
retRes4678 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes4678)
|
|
var market interface{} = this.Market(symbol)
|
|
amount = this.ToRealSymbolAmount(symbol, amount)
|
|
price = this.ToRealSymbolPrice(symbol, price)
|
|
var request interface{} = this.Extend(map[string]interface{} {
|
|
"baseId": GetValue(market, "baseId"),
|
|
"quoteId": GetValue(market, "quoteId"),
|
|
"orderType": side,
|
|
"amount": amount,
|
|
"price": price,
|
|
}, params)
|
|
|
|
retRes47815 := (<-this.MatcherPostMatcherOrderbookBaseIdQuoteIdCalculateFee(request))
|
|
PanicOnError(retRes47815)
|
|
ch <- retRes47815
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *wavesexchange) CustomCalculateFee(symbol interface{}, typeVar interface{}, side interface{}, amount interface{}, price interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
takerOrMaker := GetArg(optionalArgs, 0, "taker")
|
|
_ = takerOrMaker
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
response:= (<-this.GetFeesForAsset(symbol, side, amount, price))
|
|
PanicOnError(response)
|
|
// {
|
|
// "base":{
|
|
// "feeAssetId":"WAVES",
|
|
// "matcherFee":"1000000"
|
|
// },
|
|
// "discount":{
|
|
// "feeAssetId":"EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc",
|
|
// "matcherFee":"4077612"
|
|
// }
|
|
// }
|
|
var isDiscountFee interface{} = this.SafeBool(params, "isDiscountFee", false)
|
|
var mode interface{} = nil
|
|
if IsTrue(isDiscountFee) {
|
|
mode = this.SafeValue(response, "discount")
|
|
} else {
|
|
mode = this.SafeValue(response, "base")
|
|
}
|
|
var matcherFee interface{} = this.SafeString(mode, "matcherFee")
|
|
var feeAssetId interface{} = this.SafeString(mode, "feeAssetId")
|
|
var feeAsset interface{} = this.SafeCurrencyCode(feeAssetId)
|
|
var adjustedMatcherFee interface{} = this.FromRealCurrencyAmount(feeAsset, matcherFee)
|
|
var amountAsString interface{} = this.NumberToString(amount)
|
|
var priceAsString interface{} = this.NumberToString(price)
|
|
var feeCost interface{} = this.FeeToPrecision(symbol, this.ParseNumber(adjustedMatcherFee))
|
|
var feeRate interface{} = Precise.StringDiv(adjustedMatcherFee, Precise.StringMul(amountAsString, priceAsString))
|
|
|
|
ch <- map[string]interface{} {
|
|
"type": takerOrMaker,
|
|
"currency": feeAsset,
|
|
"rate": this.ParseNumber(feeRate),
|
|
"cost": this.ParseNumber(feeCost),
|
|
}
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *wavesexchange) GetQuotes() <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
var quotes interface{} = this.SafeValue(this.Options, "quotes")
|
|
if IsTrue(quotes) {
|
|
|
|
ch <- quotes
|
|
return nil
|
|
} else {
|
|
// currencies can have any name because you can create you own token
|
|
// as a result someone can create a fake token called BTC
|
|
// we use this mapping to determine the real tokens
|
|
// https://docs.wx.network/en/waves-matcher/matcher-api#asset-pair
|
|
|
|
response:= (<-this.MatcherGetMatcherSettings())
|
|
PanicOnError(response)
|
|
// {
|
|
// "orderVersions": [
|
|
// 1,
|
|
// 2,
|
|
// 3
|
|
// ],
|
|
// "success": true,
|
|
// "matcherPublicKey": "9cpfKN9suPNvfeUNphzxXMjcnn974eme8ZhWUjaktzU5",
|
|
// "orderFee": {
|
|
// "dynamic": {
|
|
// "baseFee": 300000,
|
|
// "rates": {
|
|
// "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ": 1.22639597,
|
|
// "62LyMjcr2DtiyF5yVXFhoQ2q414VPPJXjsNYp72SuDCH": 0.00989643,
|
|
// "HZk1mbfuJpmxU1Fs4AX5MWLVYtctsNcg6e2C6VKqK8zk": 0.0395674,
|
|
// "8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS": 0.00018814,
|
|
// "4LHHvYGNKJUg5hj65aGD5vgScvCBmLpdRFtjokvCjSL8": 26.19721262,
|
|
// "474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu": 0.00752978,
|
|
// "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p": 1.84575,
|
|
// "B3uGHFRpSUuGEDWjqB9LWWxafQj8VTvpMucEyoxzws5H": 0.02330273,
|
|
// "zMFqXuoyrn5w17PFurTqxB7GsS71fp9dfk6XFwxbPCy": 0.00721412,
|
|
// "5WvPKSJXzVE2orvbkJ8wsQmmQKqTv9sGBPksV4adViw3": 0.02659103,
|
|
// "WAVES": 1,
|
|
// "BrjUWjndUanm5VsJkbUip8VRYy6LWJePtxya3FNv4TQa": 0.03433583
|
|
// }
|
|
// }
|
|
// },
|
|
// "networkByte": 87,
|
|
// "matcherVersion": "2.1.3.5",
|
|
// "status": "SimpleResponse",
|
|
// "priceAssets": [
|
|
// "Ft8X1v1LTa1ABafufpaCWyVj8KkaxUWE6xBhW6sNFJck",
|
|
// "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p",
|
|
// "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ",
|
|
// "Gtb1WRznfchDnTh37ezoDTJ4wcoKaRsKqKjJjy7nm2zU",
|
|
// "2mX5DzVKWrAJw8iwdJnV2qtoeVG9h5nTDpTqC1wb1WEN",
|
|
// "8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS",
|
|
// "WAVES",
|
|
// "474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu",
|
|
// "zMFqXuoyrn5w17PFurTqxB7GsS71fp9dfk6XFwxbPCy",
|
|
// "62LyMjcr2DtiyF5yVXFhoQ2q414VPPJXjsNYp72SuDCH",
|
|
// "HZk1mbfuJpmxU1Fs4AX5MWLVYtctsNcg6e2C6VKqK8zk",
|
|
// "B3uGHFRpSUuGEDWjqB9LWWxafQj8VTvpMucEyoxzws5H",
|
|
// "5WvPKSJXzVE2orvbkJ8wsQmmQKqTv9sGBPksV4adViw3",
|
|
// "BrjUWjndUanm5VsJkbUip8VRYy6LWJePtxya3FNv4TQa",
|
|
// "4LHHvYGNKJUg5hj65aGD5vgScvCBmLpdRFtjokvCjSL8"
|
|
// ]
|
|
// }
|
|
quotes = map[string]interface{} {}
|
|
var priceAssets interface{} = this.SafeValue(response, "priceAssets")
|
|
for i := 0; IsLessThan(i, GetArrayLength(priceAssets)); i++ {
|
|
AddElementToObject(quotes, GetValue(priceAssets, i), true)
|
|
}
|
|
AddElementToObject(this.Options, "quotes", quotes)
|
|
|
|
ch <- quotes
|
|
return nil
|
|
}
|
|
return nil
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#fetchMarkets
|
|
* @description retrieves data on all markets for wavesexchange
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object[]} an array of objects representing market data
|
|
*/
|
|
func (this *wavesexchange) 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
|
|
|
|
response:= (<-this.MarketGetTickers())
|
|
PanicOnError(response)
|
|
//
|
|
// [
|
|
// {
|
|
// "symbol": "WAVES/BTC",
|
|
// "amountAssetID": "WAVES",
|
|
// "amountAssetName": "Waves",
|
|
// "amountAssetDecimals": 8,
|
|
// "amountAssetTotalSupply": "106908766.00000000",
|
|
// "amountAssetMaxSupply": "106908766.00000000",
|
|
// "amountAssetCirculatingSupply": "106908766.00000000",
|
|
// "priceAssetID": "8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS",
|
|
// "priceAssetName": "WBTC",
|
|
// "priceAssetDecimals": 8,
|
|
// "priceAssetTotalSupply": "20999999.96007507",
|
|
// "priceAssetMaxSupply": "20999999.96007507",
|
|
// "priceAssetCirculatingSupply": "20999999.66019601",
|
|
// "24h_open": "0.00032688",
|
|
// "24h_high": "0.00033508",
|
|
// "24h_low": "0.00032443",
|
|
// "24h_close": "0.00032806",
|
|
// "24h_vwap": "0.00032988",
|
|
// "24h_volume": "42349.69440104",
|
|
// "24h_priceVolume": "13.97037207",
|
|
// "timestamp":1640232379124
|
|
// }
|
|
// ...
|
|
// ]
|
|
//
|
|
var result interface{} = []interface{}{}
|
|
for i := 0; IsLessThan(i, GetArrayLength(response)); i++ {
|
|
var entry interface{} = GetValue(response, i)
|
|
var baseId interface{} = this.SafeString(entry, "amountAssetID")
|
|
var quoteId interface{} = this.SafeString(entry, "priceAssetID")
|
|
var id interface{} = Add(Add(baseId, "/"), quoteId)
|
|
var marketId interface{} = this.SafeString(entry, "symbol")
|
|
basequoteVariable := Split(marketId, "/");
|
|
base := GetValue(basequoteVariable,0);
|
|
quote := GetValue(basequoteVariable,1)
|
|
base = this.SafeCurrencyCode(base)
|
|
quote = this.SafeCurrencyCode(quote)
|
|
var symbol interface{} = Add(Add(base, "/"), quote)
|
|
AppendToArray(&result,map[string]interface{} {
|
|
"id": id,
|
|
"symbol": symbol,
|
|
"base": base,
|
|
"quote": quote,
|
|
"settle": nil,
|
|
"baseId": baseId,
|
|
"quoteId": quoteId,
|
|
"settleId": nil,
|
|
"type": "spot",
|
|
"spot": true,
|
|
"margin": false,
|
|
"swap": false,
|
|
"future": false,
|
|
"option": false,
|
|
"active": nil,
|
|
"contract": false,
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
"contractSize": nil,
|
|
"expiry": nil,
|
|
"expiryDatetime": nil,
|
|
"strike": nil,
|
|
"optionType": nil,
|
|
"precision": map[string]interface{} {
|
|
"amount": this.ParseNumber(this.ParsePrecision(this.SafeString(entry, "amountAssetDecimals"))),
|
|
"price": this.ParseNumber(this.ParsePrecision(this.SafeString(entry, "priceAssetDecimals"))),
|
|
},
|
|
"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": nil,
|
|
"max": nil,
|
|
},
|
|
},
|
|
"created": nil,
|
|
"info": entry,
|
|
})
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#fetchOrderBook
|
|
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
* @see https://matcher.waves.exchange/api-docs/index.html#/markets/getOrderBook
|
|
* @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 *wavesexchange) 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
|
|
|
|
retRes6968 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes6968)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = this.Extend(map[string]interface{} {
|
|
"baseId": GetValue(market, "baseId"),
|
|
"quoteId": GetValue(market, "quoteId"),
|
|
}, params)
|
|
|
|
response:= (<-this.MatcherGetMatcherOrderbookBaseIdQuoteId(request))
|
|
PanicOnError(response)
|
|
var timestamp interface{} = this.SafeInteger(response, "timestamp")
|
|
var bids interface{} = this.ParseOrderBookSide(this.SafeValue(response, "bids"), market, limit)
|
|
var asks interface{} = this.ParseOrderBookSide(this.SafeValue(response, "asks"), market, limit)
|
|
|
|
ch <- map[string]interface{} {
|
|
"symbol": symbol,
|
|
"bids": bids,
|
|
"asks": asks,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"nonce": nil,
|
|
}
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *wavesexchange) ParseOrderBookSide(bookSide interface{}, optionalArgs ...interface{}) interface{} {
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
limit := GetArg(optionalArgs, 1, nil)
|
|
_ = limit
|
|
var precision interface{} = GetValue(market, "precision")
|
|
var wavesPrecision interface{} = this.SafeString(this.Options, "wavesPrecision", "1e-8")
|
|
var amountPrecisionString interface{} = this.SafeString(precision, "amount")
|
|
var pricePrecisionString interface{} = this.SafeString(precision, "price")
|
|
var difference interface{} = Precise.StringDiv(amountPrecisionString, pricePrecisionString)
|
|
var pricePrecision interface{} = Precise.StringDiv(wavesPrecision, difference)
|
|
var result interface{} = []interface{}{}
|
|
for i := 0; IsLessThan(i, GetArrayLength(bookSide)); i++ {
|
|
var entry interface{} = GetValue(bookSide, i)
|
|
var entryPrice interface{} = this.SafeString(entry, "price", "0")
|
|
var entryAmount interface{} = this.SafeString(entry, "amount", "0")
|
|
var price interface{} = nil
|
|
var amount interface{} = nil
|
|
if IsTrue(IsTrue((!IsEqual(pricePrecision, nil))) && IsTrue((!IsEqual(entryPrice, nil)))) {
|
|
price = Precise.StringMul(entryPrice, pricePrecision)
|
|
}
|
|
if IsTrue(IsTrue((!IsEqual(amountPrecisionString, nil))) && IsTrue((!IsEqual(entryAmount, nil)))) {
|
|
amount = Precise.StringMul(entryAmount, amountPrecisionString)
|
|
}
|
|
if IsTrue(IsTrue((!IsEqual(limit, nil))) && IsTrue((IsGreaterThan(i, limit)))) {
|
|
break
|
|
}
|
|
AppendToArray(&result,[]interface{}{this.ParseNumber(price), this.ParseNumber(amount)})
|
|
}
|
|
return result
|
|
}
|
|
func (this *wavesexchange) CheckRequiredKeys() interface{} {
|
|
if IsTrue(IsEqual(this.ApiKey, nil)) {
|
|
panic(AuthenticationError(Add(this.Id, " requires apiKey credential")))
|
|
}
|
|
if IsTrue(IsEqual(this.Secret, nil)) {
|
|
panic(AuthenticationError(Add(this.Id, " requires secret credential")))
|
|
}
|
|
var apiKeyBytes interface{} = nil
|
|
var secretKeyBytes interface{} = nil
|
|
|
|
{ ret__ := func(this *wavesexchange) (ret_ interface{}) {
|
|
defer func() {
|
|
if e := recover(); e != nil {
|
|
if e == "break" {
|
|
return
|
|
}
|
|
ret_ = func(this *wavesexchange) interface{} {
|
|
// catch block:
|
|
panic(AuthenticationError(Add(this.Id, " apiKey must be a base58 encoded public key")))
|
|
return nil
|
|
}(this)
|
|
}
|
|
}()
|
|
// try block:
|
|
apiKeyBytes = this.Base58ToBinary(this.ApiKey)
|
|
return nil
|
|
}(this)
|
|
if ret__ != nil {
|
|
return ret__
|
|
}
|
|
}
|
|
|
|
{ ret__ := func(this *wavesexchange) (ret_ interface{}) {
|
|
defer func() {
|
|
if e := recover(); e != nil {
|
|
if e == "break" {
|
|
return
|
|
}
|
|
ret_ = func(this *wavesexchange) interface{} {
|
|
// catch block:
|
|
panic(AuthenticationError(Add(this.Id, " secret must be a base58 encoded private key")))
|
|
return nil
|
|
}(this)
|
|
}
|
|
}()
|
|
// try block:
|
|
secretKeyBytes = this.Base58ToBinary(this.Secret)
|
|
return nil
|
|
}(this)
|
|
if ret__ != nil {
|
|
return ret__
|
|
}
|
|
}
|
|
var hexApiKeyBytes interface{} = this.BinaryToBase16(apiKeyBytes)
|
|
var hexSecretKeyBytes interface{} = this.BinaryToBase16(secretKeyBytes)
|
|
if IsTrue(!IsEqual(GetLength(hexApiKeyBytes), 64)) {
|
|
panic(AuthenticationError(Add(this.Id, " apiKey must be a base58 encoded public key")))
|
|
}
|
|
if IsTrue(!IsEqual(GetLength(hexSecretKeyBytes), 64)) {
|
|
panic(AuthenticationError(Add(this.Id, " secret must be a base58 encoded private key")))
|
|
}
|
|
return true
|
|
}
|
|
func (this *wavesexchange) 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 query interface{} = this.Omit(params, this.ExtractParams(path))
|
|
var isCancelOrder interface{} = IsEqual(path, "matcher/orders/{wavesAddress}/cancel")
|
|
path = this.ImplodeParams(path, params)
|
|
var url interface{} = Add(Add(GetValue(GetValue(this.Urls, "api"), api), "/"), path)
|
|
var queryString interface{} = this.UrlencodeWithArrayRepeat(query)
|
|
if IsTrue(IsTrue((IsEqual(api, "private"))) || IsTrue((IsEqual(api, "forward")))) {
|
|
headers = map[string]interface{} {
|
|
"Accept": "application/json",
|
|
}
|
|
var accessToken interface{} = this.SafeString(this.Options, "accessToken")
|
|
if IsTrue(accessToken) {
|
|
AddElementToObject(headers, "Authorization", Add("Bearer ", accessToken))
|
|
}
|
|
if IsTrue(IsEqual(method, "POST")) {
|
|
AddElementToObject(headers, "content-type", "application/json")
|
|
} else {
|
|
AddElementToObject(headers, "content-type", "application/x-www-form-urlencoded")
|
|
}
|
|
if IsTrue(isCancelOrder) {
|
|
body = this.Json([]interface{}{GetValue(query, "orderId")})
|
|
queryString = ""
|
|
}
|
|
if IsTrue(IsGreaterThan(GetArrayLength(queryString), 0)) {
|
|
url = Add(url, Add("?", queryString))
|
|
}
|
|
} else if IsTrue(IsEqual(api, "matcher")) {
|
|
if IsTrue(IsEqual(method, "POST")) {
|
|
headers = map[string]interface{} {
|
|
"Accept": "application/json",
|
|
"Content-Type": "application/json",
|
|
}
|
|
body = this.Json(query)
|
|
} else {
|
|
headers = query
|
|
}
|
|
} else {
|
|
if IsTrue(IsEqual(method, "POST")) {
|
|
headers = map[string]interface{} {
|
|
"content-type": "application/json",
|
|
}
|
|
body = this.Json(query)
|
|
} else {
|
|
headers = map[string]interface{} {
|
|
"content-type": "application/x-www-form-urlencoded",
|
|
}
|
|
if IsTrue(IsGreaterThan(GetArrayLength(queryString), 0)) {
|
|
url = Add(url, Add("?", queryString))
|
|
}
|
|
}
|
|
}
|
|
return map[string]interface{} {
|
|
"url": url,
|
|
"method": method,
|
|
"body": body,
|
|
"headers": headers,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#signIn
|
|
* @description sign in, must be called prior to using other authenticated methods
|
|
* @see https://docs.wx.network/en/api/auth/oauth2-token
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns response from exchange
|
|
*/
|
|
func (this *wavesexchange) SignIn(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
// W for production, T for testnet
|
|
// { access_token: "eyJhbGciOXJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzaWciOiJiaTZiMVhMQlo0M1Q4QmRTSlVSejJBZGlQdVlpaFZQYVhhVjc4ZGVIOEpTM3M3NUdSeEU1VkZVOE5LRUI0UXViNkFHaUhpVFpuZ3pzcnhXdExUclRvZTgiLCJhIjoiM1A4VnpMU2EyM0VXNUNWY2tIYlY3ZDVCb043NWZGMWhoRkgiLCJuYiI6IlciLCJ1c2VyX25hbWUiOiJBSFhuOG5CQTRTZkxRRjdoTFFpU24xNmt4eWVoaml6QkdXMVRkcm1TWjFnRiIsInNjb3BlIjpbImdlbmVyYWwiXSwibHQiOjYwNDc5OSwicGsiOiJBSFhuOG5CQTRTZkxRRjdoTFFpU24xNmt4eWVoaml6QkdXMVRkcm1TWjFnRiIsImV4cCI6MTU5MTk3NTA1NywiZXhwMCI6MTU5MTk3NTA1NywianRpIjoiN2JhOTUxMTMtOGI2MS00NjEzLTlkZmYtNTEwYTc0NjlkOWI5IiwiY2lkIjoid2F2ZXMuZXhjaGFuZ2UifQ.B-XwexBnUAzbWknVN68RKT0ZP5w6Qk1SKJ8usL3OIwDEzCUUX9PjW-5TQHmiCRcA4oft8lqXEiCwEoNfsblCo_jTpRo518a1vZkIbHQk0-13Dm1K5ewGxfxAwBk0g49odcbKdjl64TN1yM_PO1VtLVuiTeZP-XF-S42Uj-7fcO-r7AulyQLuTE0uo-Qdep8HDCk47rduZwtJOmhFbCCnSgnLYvKWy3CVTeldsR77qxUY-vy8q9McqeP7Id-_MWnsob8vWXpkeJxaEsw1Fke1dxApJaJam09VU8EB3ZJWpkT7V8PdafIrQGeexx3jhKKxo7rRb4hDV8kfpVoCgkvFan",
|
|
// "token_type": "bearer",
|
|
// "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzaWciOiJiaTZiMVhMQlo0M1Q4QmRTSlVSejJBZGlQdVlpaFZQYVhhVjc4ZGVIOEpTM3M3NUdSeEU1VkZVOE5LRUI0UXViNkFHaUhpVFpuZ3pzcnhXdExUclRvZTgiLCJhIjoiM1A4VnpMU2EyM0VXNUNWY2tIYlY3ZDVCb043NWZGMWhoRkgiLCJuYiI6IlciLCJ1c2VyX25hbWUiOiJBSFhuOG5CQTRTZkxRRjdoTFFpU24xNmt4eWVoaml6QkdXMVRkcm1TWjFnRiIsInNjb3BlIjpbImdlbmVyYWwiXSwiYXRpIjoiN2JhOTUxMTMtOGI2MS00NjEzLTlkZmYtNTEwYTc0NjlkXWI5IiwibHQiOjYwNDc5OSwicGsiOiJBSFhuOG5CQTRTZkxRRjdoTFFpU24xNmt4eWVoaml6QkdXMVRkcm1TWjFnRiIsImV4cCI6MTU5Mzk2MjI1OCwiZXhwMCI6MTU5MTk3NTA1NywianRpIjoiM2MzZWRlMTktNjI5My00MTNlLWJmMWUtZTRlZDZlYzUzZTgzIiwiY2lkIjoid2F2ZXMuZXhjaGFuZ2UifQ.gD1Qj0jfqayfZpBvNY0t3ccMyK5hdbT7dY-_5L6LxwV0Knan4ndEtvygxlTOczmJUKtnA4T1r5GBFgNMZTvtViKZIbqZNysEg2OY8UxwDaF4VPeGJLg_QXEnn8wBeBQdyMafh9UQdwD2ci7x-saM4tOAGmncAygfTDxy80201gwDhfAkAGerb9kL00oWzSJScldxu--pNLDBUEHZt52MSEel10HGrzvZkkvvSh67vcQo5TOGb5KG6nh65UdJCwr41AVz4fbQPP-N2Nkxqy0TE_bqVzZxExXgvcS8TS0Z82T3ijJa_ct7B9wblpylBnvmyj3VycUzufD6uy8MUGq32D",
|
|
// "expires_in": 604798,
|
|
// "scope": "general" }
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
if !IsTrue(this.SafeString(this.Options, "accessToken")) {
|
|
var prefix interface{} = "ffffff01"
|
|
var expiresDelta interface{} = Multiply(Multiply(Multiply(60, 60), 24), 7)
|
|
var seconds interface{} = this.Sum(this.Seconds(), expiresDelta)
|
|
seconds = ToString(seconds)
|
|
var clientId interface{} = "wx.network"
|
|
var defaultMessagePrefix interface{} = this.SafeString(this.Options, "messagePrefix", "W")
|
|
var message interface{} = Add(Add(Add(Add(defaultMessagePrefix, ":"), clientId), ":"), seconds)
|
|
var messageHex interface{} = this.BinaryToBase16(this.Encode(message))
|
|
var payload interface{} = Add(prefix, messageHex)
|
|
var hexKey interface{} = this.BinaryToBase16(this.Base58ToBinary(this.Secret))
|
|
var signature interface{} = this.Axolotl(payload, hexKey, ed25519)
|
|
var request interface{} = map[string]interface{} {
|
|
"grant_type": "password",
|
|
"scope": "general",
|
|
"username": this.ApiKey,
|
|
"password": Add(Add(seconds, ":"), signature),
|
|
"client_id": clientId,
|
|
}
|
|
|
|
response:= (<-this.PrivatePostOauth2Token(request))
|
|
PanicOnError(response)
|
|
AddElementToObject(this.Options, "accessToken", this.SafeString(response, "access_token"))
|
|
|
|
ch <- GetValue(this.Options, "accessToken")
|
|
return nil
|
|
}
|
|
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *wavesexchange) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "symbol": "WAVES/BTC",
|
|
// "amountAssetID": "WAVES",
|
|
// "amountAssetName": "Waves",
|
|
// "amountAssetDecimals": 8,
|
|
// "amountAssetTotalSupply": "106908766.00000000",
|
|
// "amountAssetMaxSupply": "106908766.00000000",
|
|
// "amountAssetCirculatingSupply": "106908766.00000000",
|
|
// "priceAssetID": "8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS",
|
|
// "priceAssetName": "WBTC",
|
|
// "priceAssetDecimals": 8,
|
|
// "priceAssetTotalSupply": "20999999.96007507",
|
|
// "priceAssetMaxSupply": "20999999.96007507",
|
|
// "priceAssetCirculatingSupply": "20999999.66019601",
|
|
// "24h_open": "0.00032688",
|
|
// "24h_high": "0.00033508",
|
|
// "24h_low": "0.00032443",
|
|
// "24h_close": "0.00032806",
|
|
// "24h_vwap": "0.00032988",
|
|
// "24h_volume": "42349.69440104",
|
|
// "24h_priceVolume": "13.97037207",
|
|
// "timestamp":1640232379124
|
|
// }
|
|
//
|
|
// fetch ticker
|
|
//
|
|
// {
|
|
// "firstPrice": "21749",
|
|
// "lastPrice": "22000",
|
|
// "volume": "0.73747149",
|
|
// "quoteVolume": "16409.44564928645471",
|
|
// "high": "23589.999941",
|
|
// "low": "21010.000845",
|
|
// "weightedAveragePrice": "22250.955964",
|
|
// "txsCount": "148",
|
|
// "volumeWaves": "0.0000000000680511203072"
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var timestamp interface{} = this.SafeInteger(ticker, "timestamp")
|
|
var marketId interface{} = this.SafeString(ticker, "symbol")
|
|
market = this.SafeMarket(marketId, market, "/")
|
|
var symbol interface{} = GetValue(market, "symbol")
|
|
var last interface{} = this.SafeString2(ticker, "24h_close", "lastPrice")
|
|
var low interface{} = this.SafeString2(ticker, "24h_low", "low")
|
|
var high interface{} = this.SafeString2(ticker, "24h_high", "high")
|
|
var vwap interface{} = this.SafeString2(ticker, "24h_vwap", "weightedAveragePrice")
|
|
var baseVolume interface{} = this.SafeString2(ticker, "24h_volume", "volume")
|
|
var quoteVolume interface{} = this.SafeString2(ticker, "24h_priceVolume", "quoteVolume")
|
|
var open interface{} = this.SafeString2(ticker, "24h_open", "firstPrice")
|
|
return this.SafeTicker(map[string]interface{} {
|
|
"symbol": symbol,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"high": high,
|
|
"low": low,
|
|
"bid": nil,
|
|
"bidVolume": nil,
|
|
"ask": nil,
|
|
"askVolume": nil,
|
|
"vwap": vwap,
|
|
"open": open,
|
|
"close": last,
|
|
"last": last,
|
|
"previousClose": nil,
|
|
"change": nil,
|
|
"percentage": nil,
|
|
"average": nil,
|
|
"baseVolume": baseVolume,
|
|
"quoteVolume": quoteVolume,
|
|
"info": ticker,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#fetchTicker
|
|
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
* @see https://api.wavesplatform.com/v0/docs/#/pairs/getPairsListAll
|
|
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
*/
|
|
func (this *wavesexchange) FetchTicker(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes9578 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes9578)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"pairs": GetValue(market, "id"),
|
|
}
|
|
|
|
response:= (<-this.PublicGetPairs(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "__type":"list",
|
|
// "data":[
|
|
// {
|
|
// "__type":"pair",
|
|
// "data":{
|
|
// "firstPrice":0.00012512,
|
|
// "lastPrice":0.00012441,
|
|
// "low":0.00012167,
|
|
// "high":0.00012768,
|
|
// "weightedAveragePrice":0.000124710697407246,
|
|
// "volume":209554.26356614,
|
|
// "quoteVolume":26.1336583539951,
|
|
// "volumeWaves":209554.26356614,
|
|
// "txsCount":6655
|
|
// },
|
|
// "amountAsset":"WAVES",
|
|
// "priceAsset":"8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS"
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeValue(response, "data", []interface{}{})
|
|
var ticker interface{} = this.SafeValue(data, 0, map[string]interface{} {})
|
|
var dataTicker interface{} = this.SafeDict(ticker, "data", map[string]interface{} {})
|
|
|
|
ch <- this.ParseTicker(dataTicker, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#fetchTickers
|
|
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
* @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
|
|
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
*/
|
|
func (this *wavesexchange) 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
|
|
|
|
retRes10018 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes10018)
|
|
|
|
response:= (<-this.MarketGetTickers(params))
|
|
PanicOnError(response)
|
|
|
|
//
|
|
// [
|
|
// {
|
|
// "symbol": "WAVES/BTC",
|
|
// "amountAssetID": "WAVES",
|
|
// "amountAssetName": "Waves",
|
|
// "amountAssetDecimals": 8,
|
|
// "amountAssetTotalSupply": "106908766.00000000",
|
|
// "amountAssetMaxSupply": "106908766.00000000",
|
|
// "amountAssetCirculatingSupply": "106908766.00000000",
|
|
// "priceAssetID": "8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS",
|
|
// "priceAssetName": "WBTC",
|
|
// "priceAssetDecimals": 8,
|
|
// "priceAssetTotalSupply": "20999999.96007507",
|
|
// "priceAssetMaxSupply": "20999999.96007507",
|
|
// "priceAssetCirculatingSupply": "20999999.66019601",
|
|
// "24h_open": "0.00032688",
|
|
// "24h_high": "0.00033508",
|
|
// "24h_low": "0.00032443",
|
|
// "24h_close": "0.00032806",
|
|
// "24h_vwap": "0.00032988",
|
|
// "24h_volume": "42349.69440104",
|
|
// "24h_priceVolume": "13.97037207",
|
|
// "timestamp":1640232379124
|
|
// }
|
|
// ...
|
|
// ]
|
|
//
|
|
ch <- this.ParseTickers(response, symbols)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#fetchOHLCV
|
|
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
* @see https://api.wavesplatform.com/v0/docs/#/candles/getCandles
|
|
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
* @param {string} timeframe the length of time each candle represents
|
|
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
* @param {int} [limit] the maximum amount of candles to fetch
|
|
* @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 *wavesexchange) 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
|
|
|
|
retRes10488 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes10488)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"baseId": GetValue(market, "baseId"),
|
|
"quoteId": GetValue(market, "quoteId"),
|
|
"interval": this.SafeString(this.Timeframes, timeframe, timeframe),
|
|
}
|
|
var allowedCandles interface{} = this.SafeInteger(this.Options, "allowedCandles", 1440)
|
|
var until interface{} = this.SafeInteger(params, "until")
|
|
var untilIsDefined interface{} = !IsEqual(until, nil)
|
|
if IsTrue(IsEqual(limit, nil)) {
|
|
limit = allowedCandles
|
|
}
|
|
limit = mathMin(allowedCandles, limit)
|
|
var duration interface{} = Multiply(this.ParseTimeframe(timeframe), 1000)
|
|
if IsTrue(IsEqual(since, nil)) {
|
|
var now interface{} = this.Milliseconds()
|
|
var timeEnd interface{} = Ternary(IsTrue(untilIsDefined), until, now)
|
|
var durationRoundedTimestamp interface{} = Multiply(this.ParseToInt(Divide(timeEnd, duration)), duration)
|
|
var delta interface{} = Multiply((Subtract(limit, 1)), duration)
|
|
var timeStart interface{} = Subtract(durationRoundedTimestamp, delta)
|
|
AddElementToObject(request, "timeStart", ToString(timeStart))
|
|
if IsTrue(untilIsDefined) {
|
|
AddElementToObject(request, "timeEnd", ToString(until))
|
|
}
|
|
} else {
|
|
AddElementToObject(request, "timeStart", ToString(since))
|
|
if IsTrue(untilIsDefined) {
|
|
AddElementToObject(request, "timeEnd", ToString(until))
|
|
} else {
|
|
var timeEnd interface{} = this.Sum(since, Multiply(duration, limit))
|
|
AddElementToObject(request, "timeEnd", ToString(timeEnd))
|
|
}
|
|
}
|
|
params = this.Omit(params, "until")
|
|
|
|
response:= (<-this.PublicGetCandlesBaseIdQuoteId(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "__type": "list",
|
|
// "data": [
|
|
// {
|
|
// "__type": "candle",
|
|
// "data": {
|
|
// "time": "2020-06-09T14:47:00.000Z",
|
|
// "open": 0.0250385,
|
|
// "close": 0.0250385,
|
|
// "high": 0.0250385,
|
|
// "low": 0.0250385,
|
|
// "volume": 0.01033012,
|
|
// "quoteVolume": 0.00025865,
|
|
// "weightedAveragePrice": 0.0250385,
|
|
// "maxHeight": 2099399,
|
|
// "txsCount": 5,
|
|
// "timeClose": "2020-06-09T14:47:59.999Z"
|
|
// }
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeValue(response, "data", []interface{}{})
|
|
var result interface{} = this.ParseOHLCVs(data, market, timeframe, since, limit)
|
|
result = this.FilterFutureCandles(result)
|
|
var lastClose interface{} = nil
|
|
var length interface{} = GetArrayLength(result)
|
|
for i := 0; IsLessThan(i, GetArrayLength(result)); i++ {
|
|
var j interface{} = Subtract(Subtract(length, i), 1)
|
|
var entry interface{} = GetValue(result, j)
|
|
var open interface{} = GetValue(entry, 1)
|
|
if IsTrue(IsEqual(open, nil)) {
|
|
AddElementToObject(entry, 1, lastClose)
|
|
AddElementToObject(entry, 2, lastClose)
|
|
AddElementToObject(entry, 3, lastClose)
|
|
AddElementToObject(entry, 4, lastClose)
|
|
AddElementToObject(result, j, entry)
|
|
}
|
|
lastClose = GetValue(entry, 4)
|
|
}
|
|
|
|
ch <- result
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *wavesexchange) FilterFutureCandles(ohlcvs interface{}) interface{} {
|
|
var result interface{} = []interface{}{}
|
|
var timestamp interface{} = this.Milliseconds()
|
|
for i := 0; IsLessThan(i, GetArrayLength(ohlcvs)); i++ {
|
|
if IsTrue(IsGreaterThan(GetValue(GetValue(ohlcvs, i), 0), timestamp)) {
|
|
// stop when getting data from the future
|
|
break
|
|
}
|
|
AppendToArray(&result,GetValue(ohlcvs, i))
|
|
}
|
|
return result
|
|
}
|
|
func (this *wavesexchange) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// {
|
|
// "__type": "candle",
|
|
// "data": {
|
|
// "time": "2020-06-05T20:46:00.000Z",
|
|
// "open": 240.573975,
|
|
// "close": 240.573975,
|
|
// "high": 240.573975,
|
|
// "low": 240.573975,
|
|
// "volume": 0.01278413,
|
|
// "quoteVolume": 3.075528,
|
|
// "weightedAveragePrice": 240.573975,
|
|
// "maxHeight": 2093895,
|
|
// "txsCount": 5,
|
|
// "timeClose": "2020-06-05T20:46:59.999Z"
|
|
// }
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var data interface{} = this.SafeValue(ohlcv, "data", map[string]interface{} {})
|
|
return []interface{}{this.Parse8601(this.SafeString(data, "time")), this.SafeNumber(data, "open"), this.SafeNumber(data, "high"), this.SafeNumber(data, "low"), this.SafeNumber(data, "close"), this.SafeNumber(data, "volume", 0)}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#fetchDepositAddress
|
|
* @description fetch the deposit address for a currency associated with this account
|
|
* @param {string} code unified currency code
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
*/
|
|
func (this *wavesexchange) FetchDepositAddress(code interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes11808 := (<-this.SignIn())
|
|
PanicOnError(retRes11808)
|
|
var networks interface{} = this.SafeValue(this.Options, "networks", map[string]interface{} {})
|
|
var rawNetwork interface{} = this.SafeStringUpper(params, "network")
|
|
var network interface{} = this.SafeString(networks, rawNetwork, rawNetwork)
|
|
params = this.Omit(params, []interface{}{"network"})
|
|
|
|
supportedCurrencies:= (<-this.PrivateGetPlatforms())
|
|
PanicOnError(supportedCurrencies)
|
|
//
|
|
// {
|
|
// "type": "list",
|
|
// "page_info": {
|
|
// "has_next_page": false,
|
|
// "last_cursor": null
|
|
// },
|
|
// "items": [
|
|
// {
|
|
// "type": "platform",
|
|
// "id": "ETH",
|
|
// "name": "Ethereum",
|
|
// "currencies": [
|
|
// "BAG",
|
|
// "BNT",
|
|
// "CRV",
|
|
// "EGG",
|
|
// "ETH",
|
|
// "EURN",
|
|
// "FL",
|
|
// "NSBT",
|
|
// "USDAP",
|
|
// "USDC",
|
|
// "USDFL",
|
|
// "USDN",
|
|
// "USDT",
|
|
// "WAVES"
|
|
// ]
|
|
// }
|
|
// ]
|
|
// }
|
|
//
|
|
var currencies interface{} = map[string]interface{} {}
|
|
var networksByCurrency interface{} = map[string]interface{} {}
|
|
var items interface{} = this.SafeValue(supportedCurrencies, "items", []interface{}{})
|
|
for i := 0; IsLessThan(i, GetArrayLength(items)); i++ {
|
|
var entry interface{} = GetValue(items, i)
|
|
var currencyId interface{} = this.SafeString(entry, "id")
|
|
var innerCurrencies interface{} = this.SafeValue(entry, "currencies", []interface{}{})
|
|
for j := 0; IsLessThan(j, GetArrayLength(innerCurrencies)); j++ {
|
|
var currencyCode interface{} = this.SafeString(innerCurrencies, j)
|
|
AddElementToObject(currencies, currencyCode, true)
|
|
if !IsTrue((InOp(networksByCurrency, currencyCode))) {
|
|
AddElementToObject(networksByCurrency, currencyCode, map[string]interface{} {})
|
|
}
|
|
AddElementToObject(GetValue(networksByCurrency, currencyCode), currencyId, true)
|
|
}
|
|
}
|
|
if !IsTrue((InOp(currencies, code))) {
|
|
var codes interface{} = ObjectKeys(currencies)
|
|
panic(ExchangeError(Add(Add(Add(Add(this.Id, " fetchDepositAddress() "), code), " not supported. Currency code must be one of "), Join(codes, ", "))))
|
|
}
|
|
var response interface{} = nil
|
|
if IsTrue(IsEqual(network, nil)) {
|
|
var request interface{} = map[string]interface{} {
|
|
"currency": code,
|
|
}
|
|
|
|
response = (<-this.PrivateGetDepositAddressesCurrency(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
var supportedNetworks interface{} = GetValue(networksByCurrency, code)
|
|
if !IsTrue((InOp(supportedNetworks, network))) {
|
|
var supportedNetworkKeys interface{} = ObjectKeys(supportedNetworks)
|
|
panic(ExchangeError(Add(Add(Add(Add(Add(Add(this.Id, " "), network), " network "), code), " deposit address not supported. Network must be one of "), Join(supportedNetworkKeys, ", "))))
|
|
}
|
|
if IsTrue(IsEqual(network, "WAVES")) {
|
|
var request interface{} = map[string]interface{} {
|
|
"publicKey": this.ApiKey,
|
|
}
|
|
|
|
responseInner:= (<-this.NodeGetAddressesPublicKeyPublicKey(this.Extend(request, request)))
|
|
PanicOnError(responseInner)
|
|
var addressInner interface{} = this.SafeString(response, "address")
|
|
|
|
ch <- map[string]interface{} {
|
|
"info": responseInner,
|
|
"currency": code,
|
|
"network": network,
|
|
"address": addressInner,
|
|
"tag": nil,
|
|
}
|
|
return nil
|
|
} else {
|
|
var request interface{} = map[string]interface{} {
|
|
"currency": code,
|
|
"platform": network,
|
|
}
|
|
|
|
response = (<-this.PrivateGetDepositAddressesCurrencyPlatform(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
}
|
|
//
|
|
// {
|
|
// "type": "deposit_addresses",
|
|
// "currency": {
|
|
// "type": "deposit_currency",
|
|
// "id": "ERGO",
|
|
// "waves_asset_id": "5dJj4Hn9t2Ve3tRpNGirUHy4yBK6qdJRAJYV21yPPuGz",
|
|
// "platform_id": "BSC",
|
|
// "decimals": 9,
|
|
// "status": "active",
|
|
// "allowed_amount": {
|
|
// "min": 0.001,
|
|
// "max": 100000
|
|
// },
|
|
// "fees": {
|
|
// "flat": 0,
|
|
// "rate": 0
|
|
// }
|
|
// },
|
|
// "deposit_addresses": [
|
|
// "9fRAAQjF8Yqg7qicQCL884zjimsRnuwsSavsM1rUdDaoG8mThku"
|
|
// ]
|
|
// }
|
|
var currency interface{} = this.SafeValue(response, "currency")
|
|
var networkId interface{} = this.SafeString(currency, "platform_id")
|
|
var networkByIds interface{} = this.SafeValue(this.Options, "networkByIds", map[string]interface{} {})
|
|
var unifiedNetwork interface{} = this.SafeString(networkByIds, networkId, networkId)
|
|
var addresses interface{} = this.SafeValue(response, "deposit_addresses")
|
|
var address interface{} = this.SafeString(addresses, 0)
|
|
|
|
ch <- map[string]interface{} {
|
|
"info": response,
|
|
"currency": code,
|
|
"network": unifiedNetwork,
|
|
"address": address,
|
|
"tag": nil,
|
|
}
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *wavesexchange) GetMatcherPublicKey() <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
// this method returns a single string
|
|
var matcherPublicKey interface{} = this.SafeString(this.Options, "matcherPublicKey")
|
|
if IsTrue(matcherPublicKey) {
|
|
|
|
ch <- matcherPublicKey
|
|
return nil
|
|
} else {
|
|
|
|
response:= (<-this.MatcherGetMatcher())
|
|
PanicOnError(response)
|
|
// remove trailing quotes from string response
|
|
AddElementToObject(this.Options, "matcherPublicKey", Slice(response, 1, Subtract(GetArrayLength(response), 1)))
|
|
|
|
ch <- GetValue(this.Options, "matcherPublicKey")
|
|
return nil
|
|
}
|
|
return nil
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *wavesexchange) GetAssetBytes(currencyId interface{}) interface{} {
|
|
if IsTrue(IsEqual(currencyId, "WAVES")) {
|
|
return this.NumberToBE(0, 1)
|
|
} else {
|
|
return this.BinaryConcat(this.NumberToBE(1, 1), this.Base58ToBinary(currencyId))
|
|
}
|
|
}
|
|
func (this *wavesexchange) GetAssetId(currencyId interface{}) interface{} {
|
|
if IsTrue(IsEqual(currencyId, "WAVES")) {
|
|
return ""
|
|
}
|
|
return currencyId
|
|
}
|
|
func (this *wavesexchange) ToRealCurrencyAmount(code interface{}, amount interface{}, optionalArgs ...interface{}) interface{} {
|
|
networkCode := GetArg(optionalArgs, 0, nil)
|
|
_ = networkCode
|
|
var currency interface{} = this.Currency(code)
|
|
var stringValue interface{} = Precise.StringDiv(this.NumberToString(amount), this.SafeString(currency, "precision"))
|
|
return ParseInt(stringValue)
|
|
}
|
|
func (this *wavesexchange) FromRealCurrencyAmount(code interface{}, amountString interface{}) interface{} {
|
|
if !IsTrue((InOp(this.Currencies, code))) {
|
|
return amountString
|
|
}
|
|
var currency interface{} = this.Currency(code)
|
|
var precisionAmount interface{} = this.SafeString(currency, "precision")
|
|
return Precise.StringMul(amountString, precisionAmount)
|
|
}
|
|
func (this *wavesexchange) ToRealSymbolPrice(symbol interface{}, price interface{}) interface{} {
|
|
var market interface{} = this.Market(symbol)
|
|
var stringValue interface{} = Precise.StringDiv(this.NumberToString(price), this.SafeString(GetValue(market, "precision"), "price"))
|
|
return ParseInt(stringValue)
|
|
}
|
|
func (this *wavesexchange) FromRealSymbolPrice(symbol interface{}, priceString interface{}) interface{} {
|
|
var market interface{} = GetValue(this.Markets, symbol)
|
|
return Precise.StringMul(priceString, this.SafeString(GetValue(market, "precision"), "price"))
|
|
}
|
|
func (this *wavesexchange) ToRealSymbolAmount(symbol interface{}, amount interface{}) interface{} {
|
|
var market interface{} = this.Market(symbol)
|
|
var stringValue interface{} = Precise.StringDiv(this.NumberToString(amount), this.SafeString(GetValue(market, "precision"), "amount"))
|
|
return ParseInt(stringValue)
|
|
}
|
|
func (this *wavesexchange) FromRealSymbolAmount(symbol interface{}, amountString interface{}) interface{} {
|
|
var market interface{} = GetValue(this.Markets, symbol)
|
|
return Precise.StringMul(amountString, GetValue(GetValue(market, "precision"), "amount"))
|
|
}
|
|
func (this *wavesexchange) SafeGetDynamic(settings interface{}) interface{} {
|
|
var orderFee interface{} = this.SafeValue(settings, "orderFee")
|
|
if IsTrue(InOp(orderFee, "dynamic")) {
|
|
return this.SafeValue(orderFee, "dynamic")
|
|
} else {
|
|
return this.SafeValue(GetValue(GetValue(orderFee, "composite"), "default"), "dynamic")
|
|
}
|
|
}
|
|
func (this *wavesexchange) SafeGetRates(dynamic interface{}) interface{} {
|
|
var rates interface{} = this.SafeValue(dynamic, "rates")
|
|
if IsTrue(IsEqual(rates, nil)) {
|
|
return map[string]interface{} {
|
|
"WAVES": 1,
|
|
}
|
|
}
|
|
return rates
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#createOrder
|
|
* @description create a trade order
|
|
* @see https://matcher.waves.exchange/api-docs/index.html#/serialize/serializeOrder
|
|
* @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 {float} [params.triggerPrice] The price at which a stop order is triggered at
|
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *wavesexchange) 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
|
|
this.CheckRequiredDependencies()
|
|
this.CheckRequiredKeys()
|
|
|
|
retRes14088 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes14088)
|
|
var market interface{} = this.Market(symbol)
|
|
|
|
matcherPublicKey:= (<-this.GetMatcherPublicKey())
|
|
PanicOnError(matcherPublicKey)
|
|
var amountAsset interface{} = this.GetAssetId(GetValue(market, "baseId"))
|
|
var priceAsset interface{} = this.GetAssetId(GetValue(market, "quoteId"))
|
|
var isMarketOrder interface{} = (IsEqual(typeVar, "market"))
|
|
var triggerPrice interface{} = this.SafeFloat2(params, "triggerPrice", "stopPrice")
|
|
var isStopOrder interface{} = (!IsEqual(triggerPrice, nil))
|
|
if IsTrue(IsTrue((isMarketOrder)) && IsTrue((IsEqual(price, nil)))) {
|
|
panic(InvalidOrder(Add(Add(Add(this.Id, " createOrder() requires a price argument for "), typeVar), " orders to determine the max price for buy and the min price for sell")))
|
|
}
|
|
var timestamp interface{} = this.Milliseconds()
|
|
var defaultExpiryDelta interface{} = nil
|
|
defaultExpiryDeltaparamsVariable := this.HandleOptionAndParams(params, "createOrder", "defaultExpiry", this.SafeInteger(this.Options, "createOrderDefaultExpiry", 2419200000));
|
|
defaultExpiryDelta = GetValue(defaultExpiryDeltaparamsVariable,0);
|
|
params = GetValue(defaultExpiryDeltaparamsVariable,1)
|
|
var expiration interface{} = this.Sum(timestamp, defaultExpiryDelta)
|
|
|
|
matcherFees:= (<-this.GetFeesForAsset(symbol, side, amount, price))
|
|
PanicOnError(matcherFees)
|
|
// {
|
|
// "base":{
|
|
// "feeAssetId":"WAVES", // varies depending on the trading pair
|
|
// "matcherFee":"1000000"
|
|
// },
|
|
// "discount":{
|
|
// "feeAssetId":"EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc",
|
|
// "matcherFee":"4077612"
|
|
// }
|
|
// }
|
|
var base interface{} = this.SafeValue2(matcherFees, "base", "discount")
|
|
var baseFeeAssetId interface{} = this.SafeString(base, "feeAssetId")
|
|
var baseFeeAsset interface{} = this.SafeCurrencyCode(baseFeeAssetId)
|
|
var baseMatcherFee interface{} = this.SafeString(base, "matcherFee")
|
|
var discount interface{} = this.SafeValue(matcherFees, "discount")
|
|
var discountFeeAssetId interface{} = this.SafeString(discount, "feeAssetId")
|
|
var discountFeeAsset interface{} = this.SafeCurrencyCode(discountFeeAssetId)
|
|
var discountMatcherFee interface{} = this.SafeString(discount, "matcherFee")
|
|
var matcherFeeAssetId interface{} = nil
|
|
var matcherFee interface{} = nil
|
|
// check first if user supplied asset fee is valid
|
|
if IsTrue(IsTrue((InOp(params, "feeAsset"))) || IsTrue((InOp(this.Options, "feeAsset")))) {
|
|
var feeAsset interface{} = this.SafeString(params, "feeAsset", this.SafeString(this.Options, "feeAsset"))
|
|
var feeCurrency interface{} = this.Currency(feeAsset)
|
|
matcherFeeAssetId = this.SafeString(feeCurrency, "id")
|
|
}
|
|
|
|
balances:= (<-this.FetchBalance())
|
|
PanicOnError(balances)
|
|
if IsTrue(!IsEqual(matcherFeeAssetId, nil)) {
|
|
if IsTrue(IsTrue(!IsEqual(baseFeeAssetId, matcherFeeAssetId)) && IsTrue(!IsEqual(discountFeeAssetId, matcherFeeAssetId))) {
|
|
panic(InvalidOrder(Add(Add(Add(Add(this.Id, " asset fee must be "), baseFeeAsset), " or "), discountFeeAsset)))
|
|
}
|
|
var matcherFeeAsset interface{} = this.SafeCurrencyCode(matcherFeeAssetId)
|
|
var rawMatcherFee interface{} = Ternary(IsTrue((IsEqual(matcherFeeAssetId, baseFeeAssetId))), baseMatcherFee, discountMatcherFee)
|
|
var floatMatcherFee interface{} = ParseFloat(this.FromRealCurrencyAmount(matcherFeeAsset, rawMatcherFee))
|
|
if IsTrue(IsTrue((InOp(balances, matcherFeeAsset))) && IsTrue((IsGreaterThanOrEqual(GetValue(GetValue(balances, matcherFeeAsset), "free"), floatMatcherFee)))) {
|
|
matcherFee = ParseInt(rawMatcherFee)
|
|
} else {
|
|
panic(InsufficientFunds(Add(this.Id, " not enough funds of the selected asset fee")))
|
|
}
|
|
}
|
|
var floatBaseMatcherFee interface{} = this.FromRealCurrencyAmount(baseFeeAsset, baseMatcherFee)
|
|
var floatDiscountMatcherFee interface{} = this.FromRealCurrencyAmount(discountFeeAsset, discountMatcherFee)
|
|
if IsTrue(IsEqual(matcherFeeAssetId, nil)) {
|
|
// try to the pay the fee using the base first then discount asset
|
|
if IsTrue(IsTrue((InOp(balances, baseFeeAsset))) && IsTrue((IsGreaterThanOrEqual(GetValue(GetValue(balances, baseFeeAsset), "free"), ParseFloat(floatBaseMatcherFee))))) {
|
|
matcherFeeAssetId = baseFeeAssetId
|
|
matcherFee = ParseInt(baseMatcherFee)
|
|
} else {
|
|
if IsTrue(IsTrue((InOp(balances, discountFeeAsset))) && IsTrue((IsGreaterThanOrEqual(GetValue(GetValue(balances, discountFeeAsset), "free"), ParseFloat(floatDiscountMatcherFee))))) {
|
|
matcherFeeAssetId = discountFeeAssetId
|
|
matcherFee = ParseInt(discountMatcherFee)
|
|
}
|
|
}
|
|
}
|
|
if IsTrue(IsEqual(matcherFeeAssetId, nil)) {
|
|
panic(InsufficientFunds(Add(Add(Add(Add(Add(Add(Add(Add(this.Id, " not enough funds on none of the eligible asset fees: "), baseFeeAsset), " "), floatBaseMatcherFee), " or "), discountFeeAsset), " "), floatDiscountMatcherFee)))
|
|
}
|
|
amount = this.ToRealSymbolAmount(symbol, amount)
|
|
price = this.ToRealSymbolPrice(symbol, price)
|
|
var assetPair interface{} = map[string]interface{} {
|
|
"amountAsset": amountAsset,
|
|
"priceAsset": priceAsset,
|
|
}
|
|
var sandboxMode interface{} = this.SafeBool(this.Options, "sandboxMode", false)
|
|
var chainId interface{} = Ternary(IsTrue((sandboxMode)), 84, 87)
|
|
var body interface{} = map[string]interface{} {
|
|
"senderPublicKey": this.ApiKey,
|
|
"matcherPublicKey": matcherPublicKey,
|
|
"assetPair": assetPair,
|
|
"orderType": side,
|
|
"price": price,
|
|
"amount": amount,
|
|
"timestamp": timestamp,
|
|
"expiration": expiration,
|
|
"matcherFee": ParseInt(matcherFee),
|
|
"priceMode": "assetDecimals",
|
|
"version": 4,
|
|
"chainId": chainId,
|
|
}
|
|
if IsTrue(isStopOrder) {
|
|
//
|
|
// {
|
|
// "v": 1, // version (int)
|
|
// "c": { // condition (object)
|
|
// "t": "sp", // condition type. for now only "stop-price" (string)
|
|
// "v": { // value (object)
|
|
// "p": "123", // price (long)
|
|
// },
|
|
// },
|
|
// }
|
|
//
|
|
var attachment interface{} = map[string]interface{} {
|
|
"v": 1,
|
|
"c": map[string]interface{} {
|
|
"t": "sp",
|
|
"v": map[string]interface{} {
|
|
"p": this.ToRealSymbolPrice(symbol, triggerPrice),
|
|
},
|
|
},
|
|
}
|
|
AddElementToObject(body, "attachment", this.BinaryToBase58(this.Encode(JsonStringify(attachment))))
|
|
}
|
|
if IsTrue(!IsEqual(matcherFeeAssetId, "WAVES")) {
|
|
AddElementToObject(body, "matcherFeeAssetId", matcherFeeAssetId)
|
|
}
|
|
|
|
serializedOrder:= (<-this.MatcherPostMatcherOrdersSerialize(body))
|
|
PanicOnError(serializedOrder)
|
|
if IsTrue(IsTrue((IsEqual(GetValue(serializedOrder, 0), "\""))) && IsTrue((IsEqual(GetValue(serializedOrder, (Subtract(GetArrayLength(serializedOrder), 1))), "\"")))) {
|
|
serializedOrder = Slice(serializedOrder, 1, Subtract(GetArrayLength(serializedOrder), 1))
|
|
}
|
|
var signature interface{} = this.Axolotl(this.BinaryToBase16(this.Base58ToBinary(serializedOrder)), this.BinaryToBase16(this.Base58ToBinary(this.Secret)), ed25519)
|
|
AddElementToObject(body, "signature", signature)
|
|
//
|
|
// {
|
|
// "success": true,
|
|
// "message": {
|
|
// "version": 4,
|
|
// "id": "8VR49dLZFaYcVwzx9TqVMTAZCSUoyB74kLUHrEPCSJgN",
|
|
// "sender": "3MpEdBXtsRHRj2TvZURSb8uLDxzneVbYczW",
|
|
// "senderPublicKey": "8aUTNqHGCBiubySBRhcS1N6NC5jLczhVcndRfMAuwtkY",
|
|
// "matcherPublicKey": "8QUAqtTckM5B8gvcuP7mMswat9SjKUuafJMusEoSn1Gy",
|
|
// "assetPair": {
|
|
// "amountAsset": "EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc",
|
|
// "priceAsset": "25FEqEjRkqK6yCkiT7Lz6SAYz7gUFCtxfCChnrVFD5AT"
|
|
// },
|
|
// "orderType": "sell",
|
|
// "amount": 100000,
|
|
// "price": 480000,
|
|
// "timestamp": 1690852043772,
|
|
// "expiration": 1693271243772,
|
|
// "matcherFee": 83327570,
|
|
// "signature": "3QYDWQVSP4kdqpTLodCuboh8bpWd6GW5s1pQyKdce1JBDwX6t4kH5Xtuq35pqo94gxjo3cfG6k6Xuic2JaYLubkK",
|
|
// "proofs": [
|
|
// "3QYDWQVSP4kdqpTLodCuboh8bpWd6GW5s1pQyKdce1JBDwX6t4kH5Xtuq35pqo94gxjo3cfG6k6Xuic2JaYLubkK"
|
|
// ],
|
|
// "matcherFeeAssetId": "EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc",
|
|
// "eip712Signature": null,
|
|
// "priceMode": "assetDecimals",
|
|
// "attachment": "2PQ4akZHnMSZrQissuu5uudoXbgsipeDnFcRtXtjVgkdm1gUWEgGzp"
|
|
// },
|
|
// "status": "OrderAccepted"
|
|
// }
|
|
//
|
|
if IsTrue(isMarketOrder) {
|
|
|
|
response:= (<-this.MatcherPostMatcherOrderbookMarket(this.Extend(body, params)))
|
|
PanicOnError(response)
|
|
var value interface{} = this.SafeDict(response, "message")
|
|
|
|
ch <- this.ParseOrder(value, market)
|
|
return nil
|
|
} else {
|
|
|
|
response:= (<-this.MatcherPostMatcherOrderbook(this.Extend(body, params)))
|
|
PanicOnError(response)
|
|
var value interface{} = this.SafeDict(response, "message")
|
|
|
|
ch <- this.ParseOrder(value, market)
|
|
return nil
|
|
}
|
|
return nil
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#cancelOrder
|
|
* @description cancels an open order
|
|
* @see https://matcher.waves.exchange/api-docs/index.html#/cancel/cancelOrdersByIdsWithKeyOrSignature
|
|
* @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
|
|
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *wavesexchange) 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
|
|
this.CheckRequiredDependencies()
|
|
this.CheckRequiredKeys()
|
|
|
|
retRes15908 := (<-this.SignIn())
|
|
PanicOnError(retRes15908)
|
|
|
|
wavesAddress:= (<-this.GetWavesAddress())
|
|
PanicOnError(wavesAddress)
|
|
|
|
response:= (<-this.ForwardPostMatcherOrdersWavesAddressCancel(map[string]interface{} {
|
|
"wavesAddress": wavesAddress,
|
|
"orderId": id,
|
|
}))
|
|
PanicOnError(response)
|
|
// {
|
|
// "success":true,
|
|
// "message":[[{"orderId":"EBpJeGM36KKFz5gTJAUKDBm89V8wqxKipSFBdU35AN3c","success":true,"status":"OrderCanceled"}]],
|
|
// "status":"BatchCancelCompleted"
|
|
// }
|
|
var message interface{} = this.SafeValue(response, "message")
|
|
var firstMessage interface{} = this.SafeValue(message, 0)
|
|
var firstOrder interface{} = this.SafeValue(firstMessage, 0)
|
|
var returnedId interface{} = this.SafeString(firstOrder, "orderId")
|
|
|
|
ch <- this.SafeOrder(map[string]interface{} {
|
|
"info": response,
|
|
"id": returnedId,
|
|
"clientOrderId": nil,
|
|
"timestamp": nil,
|
|
"datetime": nil,
|
|
"lastTradeTimestamp": nil,
|
|
"symbol": symbol,
|
|
"type": nil,
|
|
"side": nil,
|
|
"price": nil,
|
|
"amount": nil,
|
|
"cost": nil,
|
|
"average": nil,
|
|
"filled": nil,
|
|
"remaining": nil,
|
|
"status": nil,
|
|
"fee": nil,
|
|
"trades": nil,
|
|
})
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#fetchOrder
|
|
* @description fetches information on an order made by the user
|
|
* @see https://matcher.waves.exchange/api-docs/index.html#/status/getOrderStatusByPKAndIdWithSig
|
|
* @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
|
|
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *wavesexchange) 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
|
|
this.CheckRequiredDependencies()
|
|
this.CheckRequiredKeys()
|
|
|
|
retRes16408 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes16408)
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
}
|
|
var timestamp interface{} = this.Milliseconds()
|
|
var byteArray interface{} = []interface{}{this.Base58ToBinary(this.ApiKey), this.NumberToBE(timestamp, 8)}
|
|
var binary interface{} = this.BinaryConcatArray(byteArray)
|
|
var hexSecret interface{} = this.BinaryToBase16(this.Base58ToBinary(this.Secret))
|
|
var signature interface{} = this.Axolotl(this.BinaryToBase16(binary), hexSecret, ed25519)
|
|
var request interface{} = map[string]interface{} {
|
|
"Timestamp": ToString(timestamp),
|
|
"Signature": signature,
|
|
"publicKey": this.ApiKey,
|
|
"orderId": id,
|
|
}
|
|
|
|
response:= (<-this.MatcherGetMatcherOrderbookPublicKeyOrderId(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
ch <- this.ParseOrder(response, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#fetchOrders
|
|
* @description fetches information on multiple orders made by the user
|
|
* @param {string} symbol unified market symbol of the market orders were made in
|
|
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *wavesexchange) 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
|
|
this.CheckRequiredDependencies()
|
|
this.CheckRequiredKeys()
|
|
if IsTrue(IsEqual(symbol, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchOrders() requires a symbol argument")))
|
|
}
|
|
|
|
retRes16798 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes16798)
|
|
var market interface{} = this.Market(symbol)
|
|
var timestamp interface{} = this.Milliseconds()
|
|
var byteArray interface{} = []interface{}{this.Base58ToBinary(this.ApiKey), this.NumberToBE(timestamp, 8)}
|
|
var binary interface{} = this.BinaryConcatArray(byteArray)
|
|
var hexSecret interface{} = this.BinaryToBase16(this.Base58ToBinary(this.Secret))
|
|
var signature interface{} = this.Axolotl(this.BinaryToBase16(binary), hexSecret, ed25519)
|
|
var request interface{} = map[string]interface{} {
|
|
"Accept": "application/json",
|
|
"Timestamp": ToString(timestamp),
|
|
"Signature": signature,
|
|
"publicKey": this.ApiKey,
|
|
"baseId": GetValue(market, "baseId"),
|
|
"quoteId": GetValue(market, "quoteId"),
|
|
}
|
|
|
|
response:= (<-this.MatcherGetMatcherOrderbookBaseIdQuoteIdPublicKeyPublicKey(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
|
|
// [ { id: "3KicDeWayY2mdrRoYdCkP3gUAoUZUNT1AA6GAtWuPLfa",
|
|
// "type": "sell",
|
|
// "orderType": "limit",
|
|
// "amount": 1,
|
|
// "fee": 300000,
|
|
// "price": 100000000,
|
|
// "timestamp": 1591651254076,
|
|
// "filled": 0,
|
|
// "filledFee": 0,
|
|
// "feeAsset": "WAVES",
|
|
// "status": "Accepted",
|
|
// "assetPair":
|
|
// { amountAsset: null,
|
|
// "priceAsset": "8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS" },
|
|
// "avgWeighedPrice": 0 }, ... ]
|
|
ch <- this.ParseOrders(response, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#fetchOpenOrders
|
|
* @description fetch all unfilled currently 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
|
|
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *wavesexchange) 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
|
|
|
|
retRes17278 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes17278)
|
|
|
|
retRes17288 := (<-this.SignIn())
|
|
PanicOnError(retRes17288)
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
}
|
|
|
|
address:= (<-this.GetWavesAddress())
|
|
PanicOnError(address)
|
|
var request interface{} = map[string]interface{} {
|
|
"address": address,
|
|
"activeOnly": true,
|
|
}
|
|
|
|
response:= (<-this.ForwardGetMatcherOrdersAddress(request))
|
|
PanicOnError(response)
|
|
|
|
ch <- this.ParseOrders(response, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#fetchClosedOrders
|
|
* @description fetches information on multiple closed orders made by the user
|
|
* @param {string} symbol unified market symbol of the market orders were made in
|
|
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *wavesexchange) 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
|
|
|
|
retRes17538 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes17538)
|
|
|
|
retRes17548 := (<-this.SignIn())
|
|
PanicOnError(retRes17548)
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
}
|
|
|
|
address:= (<-this.GetWavesAddress())
|
|
PanicOnError(address)
|
|
var request interface{} = map[string]interface{} {
|
|
"address": address,
|
|
"closedOnly": true,
|
|
}
|
|
|
|
response:= (<-this.ForwardGetMatcherOrdersAddress(request))
|
|
PanicOnError(response)
|
|
|
|
// [
|
|
// {
|
|
// "id": "9aXcxvXai73jbAm7tQNnqaQ2PwUjdmWuyjvRTKAHsw4f",
|
|
// "type": "buy",
|
|
// "orderType": "limit",
|
|
// "amount": 23738330,
|
|
// "fee": 300000,
|
|
// "price": 3828348334,
|
|
// "timestamp": 1591926905636,
|
|
// "filled": 23738330,
|
|
// "filledFee": 300000,
|
|
// "feeAsset": "WAVES",
|
|
// "status": "Filled",
|
|
// "assetPair": {
|
|
// "amountAsset": "HZk1mbfuJpmxU1Fs4AX5MWLVYtctsNcg6e2C6VKqK8zk",
|
|
// "priceAsset": null
|
|
// },
|
|
// "avgWeighedPrice": 3828348334
|
|
// }, ...
|
|
// ]
|
|
ch <- this.ParseOrders(response, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *wavesexchange) ParseOrderStatus(status interface{}) interface{} {
|
|
var statuses interface{} = map[string]interface{} {
|
|
"Cancelled": "canceled",
|
|
"Accepted": "open",
|
|
"Filled": "closed",
|
|
"PartiallyFilled": "open",
|
|
}
|
|
return this.SafeString(statuses, status, status)
|
|
}
|
|
func (this *wavesexchange) GetSymbolFromAssetPair(assetPair interface{}) interface{} {
|
|
// a blank string or null can indicate WAVES
|
|
var baseId interface{} = this.SafeString(assetPair, "amountAsset", "WAVES")
|
|
var quoteId interface{} = this.SafeString(assetPair, "priceAsset", "WAVES")
|
|
return Add(Add(this.SafeCurrencyCode(baseId), "/"), this.SafeCurrencyCode(quoteId))
|
|
}
|
|
func (this *wavesexchange) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// createOrder
|
|
//
|
|
// {
|
|
// "version": 4,
|
|
// "id": "BshyeHXDfJmTnjTdBYt371jD4yWaT3JTP6KpjpsiZepS",
|
|
// "sender": "3P8VzLSa23EW5CVckHbV7d5BoN75fF1hhFH",
|
|
// "senderPublicKey": "AHXn8nBA4SfLQF7hLQiSn16kxyehjizBGW1TdrmSZ1gF",
|
|
// "matcherPublicKey": "9cpfKN9suPNvfeUNphzxXMjcnn974eme8ZhWUjaktzU5",
|
|
// "assetPair": {
|
|
// "amountAsset": "474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu",
|
|
// "priceAsset": "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p",
|
|
// },
|
|
// "orderType": "buy",
|
|
// "amount": 10000,
|
|
// "price": 400000000,
|
|
// "timestamp": 1599848586891,
|
|
// "expiration": 1602267786891,
|
|
// "matcherFee": 3008,
|
|
// "matcherFeeAssetId": "474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu",
|
|
// "signature": "3D2h8ubrhuWkXbVn4qJ3dvjmZQxLoRNfjTqb9uNpnLxUuwm4fGW2qGH6yKFe2SQPrcbgkS3bDVe7SNtMuatEJ7qy",
|
|
// "proofs": [
|
|
// "3D2h8ubrhuWkXbVn4qJ3dvjmZQxLoRNfjTqb9uNpnLxUuwm4fGW2qGH6yKFe2SQPrcbgkS3bDVe7SNtMuatEJ7qy",
|
|
// ],
|
|
// "attachment":"77rnoyFX5BDr15hqZiUtgXKSN46zsbHHQjVNrTMLZcLz62mmFKr39FJ"
|
|
// }
|
|
//
|
|
//
|
|
// fetchOrder, fetchOrders, fetchOpenOrders, fetchClosedOrders
|
|
//
|
|
// {
|
|
// "id": "81D9uKk2NfmZzfG7uaJsDtxqWFbJXZmjYvrL88h15fk8",
|
|
// "type": "buy",
|
|
// "orderType": "limit",
|
|
// "amount": 30000000000,
|
|
// "filled": 0,
|
|
// "price": 1000000,
|
|
// "fee": 300000,
|
|
// "filledFee": 0,
|
|
// "feeAsset": "WAVES",
|
|
// "timestamp": 1594303779322,
|
|
// "status": "Cancelled",
|
|
// "assetPair": {
|
|
// "amountAsset": "474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu",
|
|
// "priceAsset": "WAVES"
|
|
// },
|
|
// "avgWeighedPrice": 0,
|
|
// "version": 4,
|
|
// "totalExecutedPriceAssets": 0, // in fetchOpenOrder/s
|
|
// "attachment":"77rnoyFX5BDr15hqZiUtgXKSN46zsbHHQjVNrTMLZcLz62mmFKr39FJ"
|
|
// }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var timestamp interface{} = this.SafeInteger(order, "timestamp")
|
|
var side interface{} = this.SafeString2(order, "type", "orderType")
|
|
var typeVar interface{} = "limit"
|
|
if IsTrue(InOp(order, "type")) {
|
|
// fetchOrders
|
|
typeVar = this.SafeString(order, "orderType", typeVar)
|
|
}
|
|
var id interface{} = this.SafeString(order, "id")
|
|
var filledString interface{} = this.SafeString(order, "filled")
|
|
var priceString interface{} = this.SafeString(order, "price")
|
|
var amountString interface{} = this.SafeString(order, "amount")
|
|
var assetPair interface{} = this.SafeValue(order, "assetPair")
|
|
var symbol interface{} = nil
|
|
if IsTrue(!IsEqual(assetPair, nil)) {
|
|
symbol = this.GetSymbolFromAssetPair(assetPair)
|
|
} else if IsTrue(!IsEqual(market, nil)) {
|
|
symbol = GetValue(market, "symbol")
|
|
}
|
|
var amountCurrency interface{} = this.SafeCurrencyCode(this.SafeString(assetPair, "amountAsset", "WAVES"))
|
|
var price interface{} = this.FromRealSymbolPrice(symbol, priceString)
|
|
var amount interface{} = this.FromRealCurrencyAmount(amountCurrency, amountString)
|
|
var filled interface{} = this.FromRealCurrencyAmount(amountCurrency, filledString)
|
|
var average interface{} = this.FromRealSymbolPrice(symbol, this.SafeString(order, "avgWeighedPrice"))
|
|
var status interface{} = this.ParseOrderStatus(this.SafeString(order, "status"))
|
|
var fee interface{} = nil
|
|
if IsTrue(InOp(order, "type")) {
|
|
var code interface{} = this.SafeCurrencyCode(this.SafeString(order, "feeAsset"))
|
|
fee = map[string]interface{} {
|
|
"currency": code,
|
|
"fee": this.ParseNumber(this.FromRealCurrencyAmount(code, this.SafeString(order, "filledFee"))),
|
|
}
|
|
} else {
|
|
var code interface{} = this.SafeCurrencyCode(this.SafeString(order, "matcherFeeAssetId", "WAVES"))
|
|
fee = map[string]interface{} {
|
|
"currency": code,
|
|
"fee": this.ParseNumber(this.FromRealCurrencyAmount(code, this.SafeString(order, "matcherFee"))),
|
|
}
|
|
}
|
|
var triggerPrice interface{} = nil
|
|
var attachment interface{} = this.SafeString(order, "attachment")
|
|
if IsTrue(!IsEqual(attachment, nil)) {
|
|
var decodedAttachment interface{} = this.ParseJson(this.Decode(this.Base58ToBinary(attachment)))
|
|
if IsTrue(!IsEqual(decodedAttachment, nil)) {
|
|
var c interface{} = this.SafeValue(decodedAttachment, "c")
|
|
if IsTrue(!IsEqual(c, nil)) {
|
|
var v interface{} = this.SafeValue(c, "v")
|
|
if IsTrue(!IsEqual(v, nil)) {
|
|
triggerPrice = this.SafeString(v, "p")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return this.SafeOrder(map[string]interface{} {
|
|
"info": order,
|
|
"id": id,
|
|
"clientOrderId": nil,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"lastTradeTimestamp": nil,
|
|
"symbol": symbol,
|
|
"type": typeVar,
|
|
"timeInForce": nil,
|
|
"postOnly": nil,
|
|
"side": side,
|
|
"price": price,
|
|
"triggerPrice": triggerPrice,
|
|
"amount": amount,
|
|
"cost": nil,
|
|
"average": average,
|
|
"filled": filled,
|
|
"remaining": nil,
|
|
"status": status,
|
|
"fee": fee,
|
|
"trades": nil,
|
|
}, market)
|
|
}
|
|
func (this *wavesexchange) GetWavesAddress() <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
var cachedAddreess interface{} = this.SafeString(this.Options, "wavesAddress")
|
|
if IsTrue(IsEqual(cachedAddreess, nil)) {
|
|
var request interface{} = map[string]interface{} {
|
|
"publicKey": this.ApiKey,
|
|
}
|
|
|
|
response:= (<-this.NodeGetAddressesPublicKeyPublicKey(request))
|
|
PanicOnError(response)
|
|
AddElementToObject(this.Options, "wavesAddress", this.SafeString(response, "address"))
|
|
|
|
ch <- GetValue(this.Options, "wavesAddress")
|
|
return nil
|
|
} else {
|
|
|
|
ch <- cachedAddreess
|
|
return nil
|
|
}
|
|
return nil
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#fetchBalance
|
|
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
*/
|
|
func (this *wavesexchange) FetchBalance(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
// makes a lot of different requests to get all the data
|
|
// in particular:
|
|
// fetchMarkets, getWavesAddress,
|
|
// getTotalBalance (doesn't include waves), getReservedBalance (doesn't include waves)
|
|
// getReservedBalance (includes WAVES)
|
|
// I couldn't find another way to get all the data
|
|
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
|
_ = params
|
|
this.CheckRequiredDependencies()
|
|
this.CheckRequiredKeys()
|
|
|
|
retRes19658 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes19658)
|
|
|
|
wavesAddress:= (<-this.GetWavesAddress())
|
|
PanicOnError(wavesAddress)
|
|
var request interface{} = map[string]interface{} {
|
|
"address": wavesAddress,
|
|
}
|
|
|
|
totalBalance:= (<-this.NodeGetAssetsBalanceAddress(request))
|
|
PanicOnError(totalBalance)
|
|
// {
|
|
// "address": "3P8VzLSa23EW5CVckHbV7d5BoN75fF1hhFH",
|
|
// "balances": [
|
|
// {
|
|
// "assetId": "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p",
|
|
// "balance": 1177200,
|
|
// "reissuable": false,
|
|
// "minSponsoredAssetFee": 7420,
|
|
// "sponsorBalance": 47492147189709,
|
|
// "quantity": 999999999775381400,
|
|
// "issueTransaction": {
|
|
// "senderPublicKey": "BRnVwSVctnV8pge5vRpsJdWnkjWEJspFb6QvrmZvu3Ht",
|
|
// "quantity": 1000000000000000000,
|
|
// "fee": 100400000,
|
|
// "description": "Neutrino USD",
|
|
// "type": 3,
|
|
// "version": 2,
|
|
// "reissuable": false,
|
|
// "script": null,
|
|
// "sender": "3PC9BfRwJWWiw9AREE2B3eWzCks3CYtg4yo",
|
|
// "feeAssetId": null,
|
|
// "chainId": 87,
|
|
// "proofs": [
|
|
// "3HNpbVkgP69NWSeb9hGYauiQDaXrRXh3tXFzNsGwsAAXnFrA29SYGbLtziW9JLpXEq7qW1uytv5Fnm5XTUMB2BxU"
|
|
// ],
|
|
// "assetId": "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p",
|
|
// "decimals": 6,
|
|
// "name": "USD-N",
|
|
// "id": "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p",
|
|
// "timestamp": 1574429393962
|
|
// }
|
|
// }
|
|
// ]
|
|
// }
|
|
var balances interface{} = this.SafeValue(totalBalance, "balances", []interface{}{})
|
|
var result interface{} = map[string]interface{} {}
|
|
var timestamp interface{} = nil
|
|
var assetIds interface{} = []interface{}{}
|
|
var nonStandardBalances interface{} = []interface{}{}
|
|
for i := 0; IsLessThan(i, GetArrayLength(balances)); i++ {
|
|
var entry interface{} = GetValue(balances, i)
|
|
var entryTimestamp interface{} = this.SafeInteger(entry, "timestamp")
|
|
timestamp = Ternary(IsTrue((IsEqual(timestamp, nil))), entryTimestamp, mathMax(timestamp, entryTimestamp))
|
|
var issueTransaction interface{} = this.SafeValue(entry, "issueTransaction")
|
|
var currencyId interface{} = this.SafeString(entry, "assetId")
|
|
var balance interface{} = this.SafeString(entry, "balance")
|
|
var currencyExists interface{} = (InOp(this.Currencies_by_id, currencyId))
|
|
if IsTrue(currencyExists) {
|
|
var code interface{} = this.SafeCurrencyCode(currencyId)
|
|
AddElementToObject(result, code, this.Account())
|
|
AddElementToObject(GetValue(result, code), "total", this.FromRealCurrencyAmount(code, balance))
|
|
} else if IsTrue(IsEqual(issueTransaction, nil)) {
|
|
AppendToArray(&assetIds,currencyId)
|
|
AppendToArray(&nonStandardBalances,balance)
|
|
}
|
|
}
|
|
var nonStandardAssets interface{} = GetArrayLength(assetIds)
|
|
if IsTrue(nonStandardAssets) {
|
|
var requestInner interface{} = map[string]interface{} {
|
|
"ids": assetIds,
|
|
}
|
|
|
|
response:= (<-this.PublicGetAssets(requestInner))
|
|
PanicOnError(response)
|
|
var data interface{} = this.SafeValue(response, "data", []interface{}{})
|
|
for i := 0; IsLessThan(i, GetArrayLength(data)); i++ {
|
|
var entry interface{} = GetValue(data, i)
|
|
var balance interface{} = GetValue(nonStandardBalances, i)
|
|
var inner interface{} = this.SafeValue(entry, "data")
|
|
var precision interface{} = this.ParsePrecision(this.SafeString(inner, "precision"))
|
|
var ticker interface{} = this.SafeString(inner, "ticker")
|
|
var code interface{} = this.SafeCurrencyCode(ticker)
|
|
AddElementToObject(result, code, this.Account())
|
|
AddElementToObject(GetValue(result, code), "total", Precise.StringMul(balance, precision))
|
|
}
|
|
}
|
|
var currentTimestamp interface{} = this.Milliseconds()
|
|
var byteArray interface{} = []interface{}{this.Base58ToBinary(this.ApiKey), this.NumberToBE(currentTimestamp, 8)}
|
|
var binary interface{} = this.BinaryConcatArray(byteArray)
|
|
var hexSecret interface{} = this.BinaryToBase16(this.Base58ToBinary(this.Secret))
|
|
var signature interface{} = this.Axolotl(this.BinaryToBase16(binary), hexSecret, ed25519)
|
|
var matcherRequest interface{} = map[string]interface{} {
|
|
"publicKey": this.ApiKey,
|
|
"signature": signature,
|
|
"timestamp": ToString(currentTimestamp),
|
|
}
|
|
|
|
reservedBalance:= (<-this.MatcherGetMatcherBalanceReservedPublicKey(matcherRequest))
|
|
PanicOnError(reservedBalance)
|
|
// { WAVES: 200300000 }
|
|
var reservedKeys interface{} = ObjectKeys(reservedBalance)
|
|
for i := 0; IsLessThan(i, GetArrayLength(reservedKeys)); i++ {
|
|
var currencyId interface{} = GetValue(reservedKeys, i)
|
|
var code interface{} = this.SafeCurrencyCode(currencyId)
|
|
if !IsTrue((InOp(result, code))) {
|
|
AddElementToObject(result, code, this.Account())
|
|
}
|
|
var amount interface{} = this.SafeString(reservedBalance, currencyId)
|
|
AddElementToObject(GetValue(result, code), "used", this.FromRealCurrencyAmount(code, amount))
|
|
}
|
|
var wavesRequest interface{} = map[string]interface{} {
|
|
"address": wavesAddress,
|
|
}
|
|
|
|
wavesTotal:= (<-this.NodeGetAddressesBalanceAddress(wavesRequest))
|
|
PanicOnError(wavesTotal)
|
|
// {
|
|
// "address": "3P8VzLSa23EW5CVckHbV7d5BoN75fF1hhFH",
|
|
// "confirmations": 0,
|
|
// "balance": 909085978
|
|
// }
|
|
AddElementToObject(result, "WAVES", this.SafeValue(result, "WAVES", this.Account()))
|
|
AddElementToObject(GetValue(result, "WAVES"), "total", this.FromRealCurrencyAmount("WAVES", this.SafeString(wavesTotal, "balance")))
|
|
result = this.SetUndefinedBalancesToZero(result)
|
|
AddElementToObject(result, "timestamp", timestamp)
|
|
AddElementToObject(result, "datetime", this.Iso8601(timestamp))
|
|
|
|
ch <- this.SafeBalance(result)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *wavesexchange) SetUndefinedBalancesToZero(balances interface{}, optionalArgs ...interface{}) interface{} {
|
|
key := GetArg(optionalArgs, 0, "used")
|
|
_ = key
|
|
var codes interface{} = ObjectKeys(balances)
|
|
for i := 0; IsLessThan(i, GetArrayLength(codes)); i++ {
|
|
var code interface{} = GetValue(codes, i)
|
|
if IsTrue(IsEqual(this.SafeValue(GetValue(balances, code), "used"), nil)) {
|
|
AddElementToObject(GetValue(balances, code), key, "0")
|
|
}
|
|
}
|
|
return balances
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#fetchMyTrades
|
|
* @description fetch all trades made by the user
|
|
* @see https://api.wavesplatform.com/v0/docs/#/transactions/searchTxsExchange
|
|
* @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
|
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
*/
|
|
func (this *wavesexchange) 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
|
|
|
|
retRes21108 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes21108)
|
|
|
|
address:= (<-this.GetWavesAddress())
|
|
PanicOnError(address)
|
|
var request interface{} = map[string]interface{} {
|
|
"sender": address,
|
|
}
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
AddElementToObject(request, "amountAsset", GetValue(market, "baseId"))
|
|
AddElementToObject(request, "priceAsset", GetValue(market, "quoteId"))
|
|
}
|
|
|
|
response:= (<-this.PublicGetTransactionsExchange(request))
|
|
PanicOnError(response)
|
|
var data interface{} = this.SafeValue(response, "data")
|
|
|
|
//
|
|
// {
|
|
// "__type":"list",
|
|
// "isLastPage":true,
|
|
// "lastCursor":"MzA2MjQ0MzAwMDI5OjpkZXNj",
|
|
// "data": [
|
|
// {
|
|
// "__type":"transaction",
|
|
// "data": {
|
|
// "id":"GbjPqco2wRP5QSrY5LimFrUyJaM535K9nhK5zaQ7J7Tx",
|
|
// "timestamp":"2022-04-06T19:56:31.479Z",
|
|
// "height":3062443,
|
|
// "type":7,
|
|
// "version":2,
|
|
// "proofs":[
|
|
// "57mYrANw61eiArCTv2eYwzXm71jYC2KpZ5AeM9zHEstuRaYSAWSuSE7njAJYJu8zap6DMCm3nzqc6es3wQFDpRCN"
|
|
// ],
|
|
// "fee":0.003,
|
|
// "applicationStatus":"succeeded",
|
|
// "sender":"3PEjHv3JGjcWNpYEEkif2w8NXV4kbhnoGgu",
|
|
// "senderPublicKey":"9cpfKN9suPNvfeUNphzxXMjcnn974eme8ZhWUjaktzU5",
|
|
// "buyMatcherFee":0,
|
|
// "sellMatcherFee":0.00141728,
|
|
// "price":215.7431,
|
|
// "amount":0.09,
|
|
// "order1": {
|
|
// "id":"49qiuQj5frdZ6zpTCEpMuKPMAh1EimwXpXWB4BeCw33h",
|
|
// "senderPublicKey":"CjUfoH3dsDZsf5UuAjqqzpWHXgvKzBZpVG9YixF7L48K",
|
|
// "matcherPublicKey":"9cpfKN9suPNvfeUNphzxXMjcnn974eme8ZhWUjaktzU5",
|
|
// "assetPair": {
|
|
// "amountAsset":"7TMu26hAs7B2oW6c5sfx45KSZT7GQA3TZNYuCav8Dcqt",
|
|
// "priceAsset":"DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"
|
|
// },
|
|
// "orderType":"buy",
|
|
// "price":215.7431,
|
|
// "sender":"3PR9WmaHV5ueVw2Wr9xsiCG3t4ySXzkkGLy",
|
|
// "amount":0.36265477,
|
|
// "timestamp":"2022-04-06T19:55:06.832Z",
|
|
// "expiration":"2022-05-05T19:55:06.832Z",
|
|
// "matcherFee":3.000334,
|
|
// "signature":"2rBWhdeuRJNpQfXfTFtcR8x8Lpic8FUHPdLML9uxABRUuxe48YRJcZxbncwWAh9LWFCEUZiztv7RZBZfGMWfFxTs",
|
|
// "matcherFeeAssetId":"DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"
|
|
// },
|
|
// "order2": {
|
|
// "id":"AkxiJqCuv6wm8K41TUSgFNwShZMnCbMDT78MqrcWpQ53",
|
|
// "senderPublicKey":"72o7qNKyne5hthB1Ww6famE7uHrk5vTVB2ZfUMBEqL3Y",
|
|
// "matcherPublicKey":"9cpfKN9suPNvfeUNphzxXMjcnn974eme8ZhWUjaktzU5",
|
|
// "assetPair": {
|
|
// "amountAsset":"7TMu26hAs7B2oW6c5sfx45KSZT7GQA3TZNYuCav8Dcqt",
|
|
// "priceAsset":"DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"
|
|
// },
|
|
// "orderType":"sell",
|
|
// "price":210,
|
|
// "sender":"3P3CzbjGgiqEyUBeKZYfgZtyaZfMG8fjoUD",
|
|
// "amount":0.09,
|
|
// "timestamp":"2022-04-06T19:56:18.535Z",
|
|
// "expiration":"2022-05-04T19:56:18.535Z",
|
|
// "matcherFee":0.00141728,
|
|
// "signature":"5BZCjYn6QzVkMXBFDBnzcAUBdCZqhq9hQfRXFHfLUQCsbis4zeriw4sUqLa1BZRT2isC6iY4Z4HtekikPqZ461PT",
|
|
// "matcherFeeAssetId":"7TMu26hAs7B2oW6c5sfx45KSZT7GQA3TZNYuCav8Dcqt"
|
|
// }
|
|
// }
|
|
// },...
|
|
// ]
|
|
// }
|
|
//
|
|
ch <- this.ParseTrades(data, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#fetchTrades
|
|
* @description get the list of most recent trades for a particular symbol
|
|
* @see https://api.wavesplatform.com/v0/docs/#/transactions/searchTxsExchange
|
|
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
* @param {int} [limit] the maximum amount of trades to fetch
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
*/
|
|
func (this *wavesexchange) 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
|
|
|
|
retRes22048 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes22048)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"amountAsset": GetValue(market, "baseId"),
|
|
"priceAsset": GetValue(market, "quoteId"),
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", mathMin(limit, 100))
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "timeStart", since)
|
|
}
|
|
|
|
response:= (<-this.PublicGetTransactionsExchange(request))
|
|
PanicOnError(response)
|
|
var data interface{} = this.SafeValue(response, "data")
|
|
|
|
//
|
|
// {
|
|
// "__type":"list",
|
|
// "isLastPage":false,
|
|
// "lastCursor":"MzA2MjM2MTAwMDU0OjpkZXNj",
|
|
// "data": [
|
|
// {
|
|
// "__type":"transaction",
|
|
// "data": {
|
|
// "id":"F42WsvSsyEzvpPLFjVhQKkSNuopooP4zMkjSUs47NeML",
|
|
// "timestamp":"2022-04-06T18:39:49.145Z",
|
|
// "height":3062361,
|
|
// "type":7,
|
|
// "version":2,
|
|
// "proofs": [
|
|
// "39iJv82kFi4pyuBxYeZpP45NXXjbrCXdVsHPAAvj32UMLmTXLjMTfV43PcmZDSAuS93HKSDo1aKJrin8UvkeE9Bs"
|
|
// ],
|
|
// "fee":0.003,
|
|
// "applicationStatus":"succeeded",
|
|
// "sender":"3PEjHv3JGjcWNpYEEkif2w8NXV4kbhnoGgu",
|
|
// "senderPublicKey":"9cpfKN9suPNvfeUNphzxXMjcnn974eme8ZhWUjaktzU5",
|
|
// "buyMatcherFee":0.02314421,
|
|
// "sellMatcherFee":0,
|
|
// "price":217.3893,
|
|
// "amount":0.34523025,
|
|
// "order1": {
|
|
// "id":"HkM36PHGaeeZdDKT1mYgZXhaU9PRZ54RZiJc2K4YMT3Q",
|
|
// "senderPublicKey":"7wYCaDcc6GX1Jx2uS7QgLHBypBKvrezTS1HfiW6Xe4Bk",
|
|
// "matcherPublicKey":"9cpfKN9suPNvfeUNphzxXMjcnn974eme8ZhWUjaktzU5",
|
|
// "assetPair": {
|
|
// "amountAsset":"7TMu26hAs7B2oW6c5sfx45KSZT7GQA3TZNYuCav8Dcqt",
|
|
// "priceAsset":"DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"
|
|
// },
|
|
// "orderType":"buy",
|
|
// "price":225.2693,
|
|
// "sender":"3PLPc8f4DGYaF9C9bwJ2uVmHqRv3NCjg5VQ",
|
|
// "amount":2.529,
|
|
// "timestamp":"2022-04-06T18:39:48.796Z",
|
|
// "expiration":"2022-05-05T18:39:48.796Z",
|
|
// "matcherFee":0.17584444,
|
|
// "signature":"2yQfJoomv86evQDw36fg1uiRkHvPDZtRp3qvxqTBWPvz4JLTHGQtEHJF5NGTvym6U93CtgNprngzmD9ecHBjxf6U",
|
|
// "matcherFeeAssetId":"Atqv59EYzjFGuitKVnMRk6H8FukjoV3ktPorbEys25on"
|
|
// },
|
|
// "order2": {
|
|
// "id":"F7HKmeuzwWdk3wKitHLnVx5MuD4wBWPpphQ8kUGx4tT9",
|
|
// "senderPublicKey":"CjUfoH3dsDZsf5UuAjqqzpWHXgvKzBZpVG9YixF7L48K",
|
|
// "matcherPublicKey":"9cpfKN9suPNvfeUNphzxXMjcnn974eme8ZhWUjaktzU5",
|
|
// "assetPair": {
|
|
// "amountAsset":"7TMu26hAs7B2oW6c5sfx45KSZT7GQA3TZNYuCav8Dcqt",
|
|
// "priceAsset":"DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"
|
|
// },
|
|
// "orderType":"sell",
|
|
// "price":217.3893,
|
|
// "sender":"3PR9WmaHV5ueVw2Wr9xsiCG3t4ySXzkkGLy",
|
|
// "amount":0.35767793,
|
|
// "timestamp":"2022-04-06T18:32:01.390Z",
|
|
// "expiration":"2022-05-05T18:32:01.390Z",
|
|
// "matcherFee":0.0139168,
|
|
// "signature":"34HgWVLPgeYWkiSvAc5ChVepGTYDQDug2dMTSincs6idEyoM7AtaZuH3mqQ5RJG2fcxxH2QSB723Qq3dgLQwQmKf",
|
|
// "matcherFeeAssetId":"7TMu26hAs7B2oW6c5sfx45KSZT7GQA3TZNYuCav8Dcqt"
|
|
// }
|
|
// }
|
|
// }, ...
|
|
// ]
|
|
// }
|
|
//
|
|
ch <- this.ParseTrades(data, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *wavesexchange) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// { __type: "transaction",
|
|
// "data":
|
|
// { id: "HSdruioHqvYHeyn9hhyoHdRWPB2bFA8ujeCPZMK6992c",
|
|
// "timestamp": "2020-06-09T19:34:51.897Z",
|
|
// "height": 2099684,
|
|
// "type": 7,
|
|
// "version": 2,
|
|
// "proofs":
|
|
// [ "26teDHERQgwjjHqEn4REcDotNG8M21xjou3X42XuDuCvrRkQo6aPyrswByH3UrkWG8v27ZAaVNzoxDg4teNcLtde" ],
|
|
// "fee": 0.003,
|
|
// "sender": "3PEjHv3JGjcWNpYEEkif2w8NXV4kbhnoGgu",
|
|
// "senderPublicKey": "9cpfKN9suPNvfeUNphzxXMjcnn974eme8ZhWUjaktzU5",
|
|
// "buyMatcherFee": 0.00299999,
|
|
// "sellMatcherFee": 0.00299999,
|
|
// "price": 0.00012003,
|
|
// "amount": 60.80421562,
|
|
// "order1":
|
|
// { id: "CBRwP3ar4oMvvpUiGyfxc1syh41488SDi2GkrjuBDegv",
|
|
// "senderPublicKey": "DBXSHBz96NFsMu7xh4fi2eT9ZnyxefAHXsMxUayzgC6a",
|
|
// "matcherPublicKey": "9cpfKN9suPNvfeUNphzxXMjcnn974eme8ZhWUjaktzU5",
|
|
// "assetPair": [Object],
|
|
// "orderType": "buy",
|
|
// "price": 0.00012003,
|
|
// "sender": "3PJfFRgVuJ47UY4ckb74EGzEBzkHXtmG1LA",
|
|
// "amount": 60.80424773,
|
|
// "timestamp": "2020-06-09T19:34:51.885Z",
|
|
// "expiration": "2020-06-10T12:31:31.885Z",
|
|
// "matcherFee": 0.003,
|
|
// "signature": "4cA3ZAb3XAEEXaFG7caqpto5TRbpR5PkhZpxoNQZ9ZReNvjuJQs5a3THnumv7rcqmVUiVtuHAgk2f67ANcqtKyJ8",
|
|
// "matcherFeeAssetId": null },
|
|
// "order2":
|
|
// { id: "CHJSLQ6dfSPs6gu2mAegrMUcRiDEDqaj2GKfvptMjS3M",
|
|
// "senderPublicKey": "3RUC4NGFZm9H8VJhSSjJyFLdiE42qNiUagDcZPwjgDf8",
|
|
// "matcherPublicKey": "9cpfKN9suPNvfeUNphzxXMjcnn974eme8ZhWUjaktzU5",
|
|
// "assetPair": [Object],
|
|
// "orderType": "sell",
|
|
// "price": 0.00012003,
|
|
// "sender": "3P9vKoQpMZtaSkHKpNh977YY9ZPzTuntLAq",
|
|
// "amount": 60.80424773,
|
|
// "timestamp": "2020-06-09T19:34:51.887Z",
|
|
// "expiration": "2020-06-10T12:31:31.887Z",
|
|
// "matcherFee": 0.003,
|
|
// "signature": "3SFyrcqzou2ddZyNisnLYaGhLt5qRjKxH8Nw3s4T5U7CEKGX9DDo8dS27RgThPVGbYF1rYET1FwrWoQ2UFZ6SMTR",
|
|
// "matcherFeeAssetId": null } } }
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var data interface{} = this.SafeValue(trade, "data")
|
|
var datetime interface{} = this.SafeString(data, "timestamp")
|
|
var timestamp interface{} = this.Parse8601(datetime)
|
|
var id interface{} = this.SafeString(data, "id")
|
|
var priceString interface{} = this.SafeString(data, "price")
|
|
var amountString interface{} = this.SafeString(data, "amount")
|
|
var order1 interface{} = this.SafeValue(data, "order1")
|
|
var order2 interface{} = this.SafeValue(data, "order2")
|
|
var order interface{} = nil
|
|
// order2 arrived after order1
|
|
if IsTrue(IsEqual(this.SafeString(order1, "senderPublicKey"), this.ApiKey)) {
|
|
order = order1
|
|
} else {
|
|
order = order2
|
|
}
|
|
var symbol interface{} = nil
|
|
var assetPair interface{} = this.SafeValue(order, "assetPair")
|
|
if IsTrue(!IsEqual(assetPair, nil)) {
|
|
symbol = this.GetSymbolFromAssetPair(assetPair)
|
|
} else if IsTrue(!IsEqual(market, nil)) {
|
|
symbol = GetValue(market, "symbol")
|
|
}
|
|
var side interface{} = this.SafeString(order, "orderType")
|
|
var orderId interface{} = this.SafeString(order, "id")
|
|
var fee interface{} = map[string]interface{} {
|
|
"cost": this.SafeString(order, "matcherFee"),
|
|
"currency": this.SafeCurrencyCode(this.SafeString(order, "matcherFeeAssetId", "WAVES")),
|
|
}
|
|
return this.SafeTrade(map[string]interface{} {
|
|
"info": trade,
|
|
"timestamp": timestamp,
|
|
"datetime": datetime,
|
|
"symbol": symbol,
|
|
"id": id,
|
|
"order": orderId,
|
|
"type": nil,
|
|
"side": side,
|
|
"takerOrMaker": nil,
|
|
"price": priceString,
|
|
"amount": amountString,
|
|
"cost": nil,
|
|
"fee": fee,
|
|
}, market)
|
|
}
|
|
func (this *wavesexchange) ParseDepositWithdrawFees(response interface{}, optionalArgs ...interface{}) interface{} {
|
|
codes := GetArg(optionalArgs, 0, nil)
|
|
_ = codes
|
|
currencyIdKey := GetArg(optionalArgs, 1, nil)
|
|
_ = currencyIdKey
|
|
var depositWithdrawFees interface{} = map[string]interface{} {}
|
|
codes = this.MarketCodes(codes)
|
|
for i := 0; IsLessThan(i, GetArrayLength(response)); i++ {
|
|
var entry interface{} = GetValue(response, i)
|
|
var dictionary interface{} = entry
|
|
var currencyId interface{} = this.SafeString(dictionary, currencyIdKey)
|
|
var currency interface{} = this.SafeValue(this.Currencies_by_id, currencyId)
|
|
var code interface{} = this.SafeString(currency, "code", currencyId)
|
|
if IsTrue(IsTrue((IsEqual(codes, nil))) || IsTrue((this.InArray(code, codes)))) {
|
|
var depositWithdrawFee interface{} = this.SafeValue(depositWithdrawFees, code)
|
|
if IsTrue(IsEqual(depositWithdrawFee, nil)) {
|
|
depositWithdrawFee = map[string]interface{} {
|
|
"info": []interface{}{dictionary},
|
|
"withdraw": map[string]interface{} {
|
|
"fee": nil,
|
|
"percentage": nil,
|
|
},
|
|
"deposit": map[string]interface{} {
|
|
"fee": nil,
|
|
"percentage": nil,
|
|
},
|
|
"networks": map[string]interface{} {},
|
|
}
|
|
} else {
|
|
depositWithdrawFee = GetValue(depositWithdrawFees, code)
|
|
AddElementToObject(depositWithdrawFee, "info", this.ArrayConcat(GetValue(depositWithdrawFee, "info"), []interface{}{dictionary}))
|
|
}
|
|
var networkId interface{} = this.SafeString(dictionary, "platform_id")
|
|
var currencyCode interface{} = this.SafeString(currency, "code")
|
|
var networkCode interface{} = this.NetworkIdToCode(networkId, currencyCode)
|
|
var network interface{} = this.SafeValue(GetValue(depositWithdrawFee, "networks"), networkCode)
|
|
if IsTrue(IsEqual(network, nil)) {
|
|
network = map[string]interface{} {
|
|
"withdraw": map[string]interface{} {
|
|
"fee": nil,
|
|
"percentage": nil,
|
|
},
|
|
"deposit": map[string]interface{} {
|
|
"fee": nil,
|
|
"percentage": nil,
|
|
},
|
|
}
|
|
}
|
|
var feeType interface{} = this.SafeString(dictionary, "type")
|
|
var fees interface{} = this.SafeValue(dictionary, "fees")
|
|
var networkKey interface{} = "deposit"
|
|
if IsTrue(IsEqual(feeType, "withdrawal_currency")) {
|
|
networkKey = "withdraw"
|
|
}
|
|
AddElementToObject(network, networkKey, map[string]interface{} {
|
|
"fee": this.SafeNumber(fees, "flat"),
|
|
"percentage": false,
|
|
})
|
|
AddElementToObject(GetValue(depositWithdrawFee, "networks"), networkCode, network)
|
|
AddElementToObject(depositWithdrawFees, code, depositWithdrawFee)
|
|
}
|
|
}
|
|
var depositWithdrawFeesKeys interface{} = ObjectKeys(depositWithdrawFees)
|
|
for i := 0; IsLessThan(i, GetArrayLength(depositWithdrawFeesKeys)); i++ {
|
|
var code interface{} = GetValue(depositWithdrawFeesKeys, i)
|
|
var entry interface{} = GetValue(depositWithdrawFees, code)
|
|
var networks interface{} = this.SafeValue(entry, "networks")
|
|
var networkKeys interface{} = ObjectKeys(networks)
|
|
var networkKeysLength interface{} = GetArrayLength(networkKeys)
|
|
if IsTrue(IsEqual(networkKeysLength, 1)) {
|
|
var network interface{} = this.SafeValue(networks, GetValue(networkKeys, 0))
|
|
AddElementToObject(GetValue(depositWithdrawFees, code), "withdraw", this.SafeValue(network, "withdraw"))
|
|
AddElementToObject(GetValue(depositWithdrawFees, code), "deposit", this.SafeValue(network, "deposit"))
|
|
}
|
|
}
|
|
return depositWithdrawFees
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#fetchDepositWithdrawFees
|
|
* @description fetch deposit and withdraw fees
|
|
* @see https://docs.wx.network/en/api/gateways/deposit/currencies
|
|
* @see https://docs.wx.network/en/api/gateways/withdraw/currencies
|
|
* @param {string[]|undefined} codes list of unified currency codes
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a list of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure}
|
|
*/
|
|
func (this *wavesexchange) FetchDepositWithdrawFees(optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
codes := GetArg(optionalArgs, 0, nil)
|
|
_ = codes
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
|
|
retRes24618 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes24618)
|
|
var data interface{} = []interface{}{}
|
|
var promises interface{} = []interface{}{}
|
|
AppendToArray(&promises,this.PrivateGetDepositCurrencies(params))
|
|
AppendToArray(&promises,this.PrivateGetWithdrawCurrencies(params))
|
|
|
|
promises = (<-promiseAll(promises))
|
|
PanicOnError(promises)
|
|
//
|
|
// {
|
|
// "type": "list",
|
|
// "page_info": {
|
|
// "has_next_page": false,
|
|
// "last_cursor": null
|
|
// },
|
|
// "items": [
|
|
// {
|
|
// "type": "deposit_currency",
|
|
// "id": "WEST",
|
|
// "platform_id": "WEST",
|
|
// "waves_asset_id": "4LHHvYGNKJUg5hj65aGD5vgScvCBmLpdRFtjokvCjSL8",
|
|
// "platform_asset_id": "WEST",
|
|
// "decimals": 8,
|
|
// "status": "active",
|
|
// "allowed_amount": {
|
|
// "min": 0.1,
|
|
// "max": 2000000
|
|
// },
|
|
// "fees": {
|
|
// "flat": 0,
|
|
// "rate": 0
|
|
// }
|
|
// },
|
|
// ]
|
|
// }
|
|
//
|
|
//
|
|
// {
|
|
// "type": "list",
|
|
// "page_info": {
|
|
// "has_next_page": false,
|
|
// "last_cursor": null
|
|
// },
|
|
// "items": [
|
|
// {
|
|
// "type": "withdrawal_currency",
|
|
// "id": "BTC",
|
|
// "platform_id": "BTC",
|
|
// "waves_asset_id": "8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS",
|
|
// "platform_asset_id": "BTC",
|
|
// "decimals": 8,
|
|
// "status": "inactive",
|
|
// "allowed_amount": {
|
|
// "min": 0.001,
|
|
// "max": 10
|
|
// },
|
|
// "fees": {
|
|
// "flat": 0.001,
|
|
// "rate": 0
|
|
// }
|
|
// },
|
|
// ]
|
|
// }
|
|
//
|
|
for i := 0; IsLessThan(i, GetArrayLength(promises)); i++ {
|
|
var items interface{} = this.SafeValue(GetValue(promises, i), "items")
|
|
data = this.ArrayConcat(data, items)
|
|
}
|
|
|
|
ch <- this.ParseDepositWithdrawFees(data, codes, "id")
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *wavesexchange) HandleErrors(code interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} {
|
|
var errorCode interface{} = this.SafeString(response, "error")
|
|
var success interface{} = this.SafeBool(response, "success", true)
|
|
var Exception interface{} = this.SafeValue(this.Exceptions, errorCode)
|
|
if IsTrue(!IsEqual(Exception, nil)) {
|
|
var messageInner interface{} = this.SafeString(response, "message")
|
|
throwDynamicException(Exception, Add(Add(this.Id, " "), messageInner));return nil;
|
|
}
|
|
var message interface{} = this.SafeString(response, "message")
|
|
if IsTrue(IsEqual(message, "Validation Error")) {
|
|
panic(BadRequest(Add(Add(this.Id, " "), body)))
|
|
}
|
|
if !IsTrue(success) {
|
|
panic(ExchangeError(Add(Add(this.Id, " "), body)))
|
|
}
|
|
return nil
|
|
}
|
|
/**
|
|
* @method
|
|
* @name wavesexchange#withdraw
|
|
* @description make a withdrawal
|
|
* @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
|
|
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
*/
|
|
func (this *wavesexchange) Withdraw(code interface{}, amount interface{}, address interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
|
ch := make(chan interface{})
|
|
go func() interface{} {
|
|
defer close(ch)
|
|
defer ReturnPanicError(ch)
|
|
tag := GetArg(optionalArgs, 0, nil)
|
|
_ = tag
|
|
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
|
_ = params
|
|
tagparamsVariable := this.HandleWithdrawTagAndParams(tag, params);
|
|
tag = GetValue(tagparamsVariable,0);
|
|
params = GetValue(tagparamsVariable,1)
|
|
// currently only works for BTC and WAVES
|
|
if IsTrue(!IsEqual(code, "WAVES")) {
|
|
|
|
supportedCurrencies:= (<-this.PrivateGetWithdrawCurrencies())
|
|
PanicOnError(supportedCurrencies)
|
|
var currencies interface{} = map[string]interface{} {}
|
|
var items interface{} = this.SafeValue(supportedCurrencies, "items", []interface{}{})
|
|
for i := 0; IsLessThan(i, GetArrayLength(items)); i++ {
|
|
var entry interface{} = GetValue(items, i)
|
|
var currencyCode interface{} = this.SafeString(entry, "id")
|
|
AddElementToObject(currencies, currencyCode, true)
|
|
}
|
|
if !IsTrue((InOp(currencies, code))) {
|
|
var codes interface{} = ObjectKeys(currencies)
|
|
panic(ExchangeError(Add(Add(Add(Add(this.Id, " withdraw() "), code), " not supported. Currency code must be one of "), ToString(codes))))
|
|
}
|
|
}
|
|
|
|
retRes25768 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes25768)
|
|
var hexChars interface{} = []interface{}{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}
|
|
var set interface{} = map[string]interface{} {}
|
|
for i := 0; IsLessThan(i, GetArrayLength(hexChars)); i++ {
|
|
var key interface{} = GetValue(hexChars, i)
|
|
AddElementToObject(set, key, true)
|
|
}
|
|
var isErc20 interface{} = true
|
|
var noPrefix interface{} = this.Remove0xPrefix(address)
|
|
var lower interface{} = ToLower(noPrefix)
|
|
var stringLength interface{} = Multiply(GetArrayLength(lower), 1)
|
|
for i := 0; IsLessThan(i, stringLength); i++ {
|
|
var character interface{} = GetValue(lower, i)
|
|
if !IsTrue((InOp(set, character))) {
|
|
isErc20 = false
|
|
break
|
|
}
|
|
}
|
|
|
|
retRes25948 := (<-this.SignIn())
|
|
PanicOnError(retRes25948)
|
|
var proxyAddress interface{} = nil
|
|
if IsTrue(IsTrue(IsEqual(code, "WAVES")) && !IsTrue(isErc20)) {
|
|
proxyAddress = address
|
|
} else {
|
|
var withdrawAddressRequest interface{} = map[string]interface{} {
|
|
"address": address,
|
|
"currency": code,
|
|
}
|
|
|
|
withdrawAddress:= (<-this.PrivateGetWithdrawAddressesCurrencyAddress(withdrawAddressRequest))
|
|
PanicOnError(withdrawAddress)
|
|
var currencyInner interface{} = this.SafeValue(withdrawAddress, "currency")
|
|
var allowedAmount interface{} = this.SafeValue(currencyInner, "allowed_amount")
|
|
var minimum interface{} = this.SafeNumber(allowedAmount, "min")
|
|
if IsTrue(IsLessThanOrEqual(amount, minimum)) {
|
|
panic(BadRequest(Add(Add(Add(Add(Add(Add(this.Id, " "), code), " withdraw failed, amount "), ToString(amount)), " must be greater than the minimum allowed amount of "), ToString(minimum))))
|
|
}
|
|
// {
|
|
// "type": "withdrawal_addresses",
|
|
// "currency": {
|
|
// "type": "withdrawal_currency",
|
|
// "id": "BTC",
|
|
// "waves_asset_id": "8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS",
|
|
// "decimals": 8,
|
|
// "status": "active",
|
|
// "allowed_amount": {
|
|
// "min": 0.001,
|
|
// "max": 20
|
|
// },
|
|
// "fees": {
|
|
// "flat": 0.001,
|
|
// "rate": 0
|
|
// }
|
|
// },
|
|
// "proxy_addresses": [
|
|
// "3P3qqmkiLwNHB7x1FeoE8bvkRtULwGpo9ga"
|
|
// ]
|
|
// }
|
|
var proxyAddresses interface{} = this.SafeValue(withdrawAddress, "proxy_addresses", []interface{}{})
|
|
proxyAddress = this.SafeString(proxyAddresses, 0)
|
|
}
|
|
var fee interface{} = this.SafeInteger(this.Options, "withdrawFeeWAVES", 100000) // 0.001 WAVES
|
|
var feeAssetId interface{} = "WAVES"
|
|
var typeVar interface{} = 4 // transfer
|
|
var version interface{} = 2
|
|
var amountInteger interface{} = this.ToRealCurrencyAmount(code, amount)
|
|
var currency interface{} = this.Currency(code)
|
|
var timestamp interface{} = this.Milliseconds()
|
|
var byteArray interface{} = []interface{}{this.NumberToBE(4, 1), this.NumberToBE(2, 1), this.Base58ToBinary(this.ApiKey), this.GetAssetBytes(GetValue(currency, "id")), this.GetAssetBytes(feeAssetId), this.NumberToBE(timestamp, 8), this.NumberToBE(amountInteger, 8), this.NumberToBE(fee, 8), this.Base58ToBinary(proxyAddress), this.NumberToBE(0, 2)}
|
|
var binary interface{} = this.BinaryConcatArray(byteArray)
|
|
var hexSecret interface{} = this.BinaryToBase16(this.Base58ToBinary(this.Secret))
|
|
var signature interface{} = this.Axolotl(this.BinaryToBase16(binary), hexSecret, ed25519)
|
|
var request interface{} = map[string]interface{} {
|
|
"senderPublicKey": this.ApiKey,
|
|
"amount": amountInteger,
|
|
"fee": fee,
|
|
"type": typeVar,
|
|
"version": version,
|
|
"attachment": "",
|
|
"feeAssetId": this.GetAssetId(feeAssetId),
|
|
"proofs": []interface{}{signature},
|
|
"assetId": this.GetAssetId(GetValue(currency, "id")),
|
|
"recipient": proxyAddress,
|
|
"timestamp": timestamp,
|
|
"signature": signature,
|
|
}
|
|
|
|
result:= (<-this.NodePostTransactionsBroadcast(request))
|
|
PanicOnError(result)
|
|
|
|
//
|
|
// {
|
|
// "id": "string",
|
|
// "signature": "string",
|
|
// "fee": 0,
|
|
// "timestamp": 1460678400000,
|
|
// "recipient": "3P274YB5qseSE9DTTL3bpSjosZrYBPDpJ8k",
|
|
// "amount": 0
|
|
// }
|
|
//
|
|
ch <- this.ParseTransaction(result, currency)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *wavesexchange) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// withdraw
|
|
//
|
|
// {
|
|
// "id": "string",
|
|
// "signature": "string",
|
|
// "fee": 0,
|
|
// "timestamp": 1460678400000,
|
|
// "recipient": "3P274YB5qseSE9DTTL3bpSjosZrYBPDpJ8k",
|
|
// "amount": 0
|
|
// }
|
|
//
|
|
// withdraw new:
|
|
// {
|
|
// type: "4",
|
|
// id: "2xnWTqG9ar7jEDrLxfbVyyspPZ6XZNrrw9ai9sQ81Eya",
|
|
// fee: "100000",
|
|
// feeAssetId: null,
|
|
// timestamp: "1715786263807",
|
|
// version: "2",
|
|
// sender: "3P81LLX1kk2CSJC9L8C2enxdHB7XvnSGAEE",
|
|
// senderPublicKey: "DdmzmXf9mty1FBE8AdVGnrncVLEAzP4gR4nWoTFAJoXz",
|
|
// proofs: [ "RyoKwdSYv3EqotJCYftfFM9JE2j1ZpDRxKwYfiRhLAFeyNp6VfJUXNDS884XfeCeHeNypNmTCZt5NYR1ekyjCX3", ],
|
|
// recipient: "3P9tXxu38a8tgewNEKFzourVxeqHd11ppOc",
|
|
// assetId: null,
|
|
// feeAsset: null,
|
|
// amount: "2000000",
|
|
// attachment: "",
|
|
// }
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
currency = this.SafeCurrency(nil, currency)
|
|
var code interface{} = GetValue(currency, "code")
|
|
var typeRaw interface{} = this.SafeString(transaction, "type")
|
|
var typeVar interface{} = Ternary(IsTrue((IsEqual(typeRaw, "4"))), "withdraw", "deposit")
|
|
var amount interface{} = this.ParseNumber(this.FromRealCurrencyAmount(code, this.SafeString(transaction, "amount")))
|
|
var feeString interface{} = this.SafeString(transaction, "fee")
|
|
var feeAssetId interface{} = this.SafeString(transaction, "feeAssetId", "WAVES")
|
|
var feeCode interface{} = this.SafeCurrencyCode(feeAssetId)
|
|
var feeAmount interface{} = this.ParseNumber(this.FromRealCurrencyAmount(feeCode, feeString))
|
|
var timestamp interface{} = this.SafeInteger(transaction, "timestamp")
|
|
return map[string]interface{} {
|
|
"id": this.SafeString(transaction, "id"),
|
|
"txid": nil,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"network": nil,
|
|
"addressFrom": this.SafeString(transaction, "sender"),
|
|
"address": nil,
|
|
"addressTo": this.SafeString(transaction, "recipient"),
|
|
"amount": amount,
|
|
"type": typeVar,
|
|
"currency": GetValue(currency, "code"),
|
|
"status": nil,
|
|
"updated": nil,
|
|
"tagFrom": nil,
|
|
"tag": nil,
|
|
"tagTo": nil,
|
|
"comment": nil,
|
|
"internal": nil,
|
|
"fee": map[string]interface{} {
|
|
"currency": feeCode,
|
|
"cost": feeAmount,
|
|
},
|
|
"info": transaction,
|
|
}
|
|
}
|
|
|
|
|
|
func (this *wavesexchange) Init(userConfig map[string]interface{}) {
|
|
this.Exchange = Exchange{}
|
|
this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this)
|
|
this.Exchange.DerivedExchange = this
|
|
}
|