ccxt 4.3.44__py2.py3-none-any.whl → 4.3.45__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,7 +21,7 @@ from ccxt.base.errors import InvalidOrder
21
21
  from ccxt.base.errors import OrderNotFound
22
22
  from ccxt.base.errors import DuplicateOrderId
23
23
  from ccxt.base.errors import ExchangeNotAvailable
24
- from ccxt.base.decimal_to_precision import DECIMAL_PLACES
24
+ from ccxt.base.decimal_to_precision import TICK_SIZE
25
25
  from ccxt.base.precise import Precise
26
26
 
27
27
 
@@ -329,9 +329,9 @@ class wavesexchange(Exchange, ImplicitAPI):
329
329
  },
330
330
  },
331
331
  'currencies': {
332
- 'WX': self.safe_currency_structure({'id': 'EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc', 'numericId': None, 'code': 'WX', 'precision': self.parse_to_int('8')}),
332
+ 'WX': self.safe_currency_structure({'id': 'EMAMLxDnv3xiz8RXg8Btj33jcEw3wLczL3JKYYmuubpc', 'numericId': None, 'code': 'WX', 'precision': self.parse_number('1e-8')}),
333
333
  },
334
- 'precisionMode': DECIMAL_PLACES,
334
+ 'precisionMode': TICK_SIZE,
335
335
  'options': {
336
336
  'allowedCandles': 1440,
337
337
  'accessToken': None,
@@ -342,7 +342,7 @@ class wavesexchange(Exchange, ImplicitAPI):
342
342
  'wavesAddress': None,
343
343
  'withdrawFeeUSDN': 7420,
344
344
  'withdrawFeeWAVES': 100000,
345
- 'wavesPrecision': 8,
345
+ 'wavesPrecision': 1e-8,
346
346
  'messagePrefix': 'W', # W for production, T for testnet
347
347
  'networks': {
348
348
  'ERC20': 'ETH',
@@ -390,8 +390,8 @@ class wavesexchange(Exchange, ImplicitAPI):
390
390
  async def get_fees_for_asset(self, symbol: str, side, amount, price, params={}):
391
391
  await self.load_markets()
392
392
  market = self.market(symbol)
393
- amount = self.custom_amount_to_precision(symbol, amount)
394
- price = self.custom_price_to_precision(symbol, price)
393
+ amount = self.to_real_symbol_amount(symbol, amount)
394
+ price = self.to_real_symbol_price(symbol, price)
395
395
  request = self.extend({
396
396
  'baseId': market['baseId'],
397
397
  'quoteId': market['quoteId'],
@@ -422,7 +422,7 @@ class wavesexchange(Exchange, ImplicitAPI):
422
422
  matcherFee = self.safe_string(mode, 'matcherFee')
423
423
  feeAssetId = self.safe_string(mode, 'feeAssetId')
424
424
  feeAsset = self.safe_currency_code(feeAssetId)
425
- adjustedMatcherFee = self.currency_from_precision(feeAsset, matcherFee)
425
+ adjustedMatcherFee = self.from_real_currency_amount(feeAsset, matcherFee)
426
426
  amountAsString = self.number_to_string(amount)
427
427
  priceAsString = self.number_to_string(price)
428
428
  feeCost = self.fee_to_precision(symbol, self.parse_number(adjustedMatcherFee))
@@ -570,8 +570,8 @@ class wavesexchange(Exchange, ImplicitAPI):
570
570
  'strike': None,
571
571
  'optionType': None,
572
572
  'precision': {
573
- 'amount': self.safe_integer(entry, 'amountAssetDecimals'),
574
- 'price': self.safe_integer(entry, 'priceAssetDecimals'),
573
+ 'amount': self.parse_number(self.parse_precision(self.safe_string(entry, 'amountAssetDecimals'))),
574
+ 'price': self.parse_number(self.parse_precision(self.safe_string(entry, 'priceAssetDecimals'))),
575
575
  },
576
576
  'limits': {
577
577
  'leverage': {
@@ -625,12 +625,11 @@ class wavesexchange(Exchange, ImplicitAPI):
625
625
 
626
626
  def parse_order_book_side(self, bookSide, market=None, limit: Int = None):
627
627
  precision = market['precision']
628
- wavesPrecision = self.safe_string(self.options, 'wavesPrecision', '8')
629
- amountPrecision = '1e' + self.number_to_string(precision['amount'])
630
- amountPrecisionString = self.number_to_string(precision['amount'])
631
- pricePrecisionString = self.number_to_string(precision['price'])
632
- difference = Precise.string_sub(amountPrecisionString, pricePrecisionString)
633
- pricePrecision = '1e' + Precise.string_sub(wavesPrecision, difference)
628
+ wavesPrecision = self.safe_string(self.options, 'wavesPrecision', '1e-8')
629
+ amountPrecisionString = self.safe_string(precision, 'amount')
630
+ pricePrecisionString = self.safe_string(precision, 'price')
631
+ difference = Precise.string_div(amountPrecisionString, pricePrecisionString)
632
+ pricePrecision = Precise.string_div(wavesPrecision, difference)
634
633
  result = []
635
634
  for i in range(0, len(bookSide)):
636
635
  entry = bookSide[i]
@@ -639,9 +638,9 @@ class wavesexchange(Exchange, ImplicitAPI):
639
638
  price = None
640
639
  amount = None
641
640
  if (pricePrecision is not None) and (entryPrice is not None):
642
- price = Precise.string_div(entryPrice, pricePrecision)
643
- if (amountPrecision is not None) and (entryAmount is not None):
644
- amount = Precise.string_div(entryAmount, amountPrecision)
641
+ price = Precise.string_mul(entryPrice, pricePrecision)
642
+ if (amountPrecisionString is not None) and (entryAmount is not None):
643
+ amount = Precise.string_mul(entryAmount, amountPrecisionString)
645
644
  if (limit is not None) and (i > limit):
646
645
  break
647
646
  result.append([
@@ -1171,50 +1170,35 @@ class wavesexchange(Exchange, ImplicitAPI):
1171
1170
  return ''
1172
1171
  return currencyId
1173
1172
 
1174
- def custom_price_to_precision(self, symbol, price):
1175
- market = self.markets[symbol]
1176
- wavesPrecision = self.safe_string(self.options, 'wavesPrecision', '8')
1177
- amount = self.number_to_string(market['precision']['amount'])
1178
- precisionPrice = self.number_to_string(market['precision']['price'])
1179
- difference = Precise.string_sub(amount, precisionPrice)
1180
- precision = Precise.string_sub(wavesPrecision, difference)
1181
- pricePrecision = self.to_precision(price, str(precision))
1182
- return self.parse_to_int(float(pricePrecision))
1183
-
1184
- def custom_amount_to_precision(self, symbol, amount):
1185
- amountPrecision = self.number_to_string(self.to_precision(amount, self.number_to_string(self.markets[symbol]['precision']['amount'])))
1186
- return self.parse_to_int(float(amountPrecision))
1173
+ def to_real_currency_amount(self, code: str, amount: float, networkCode=None):
1174
+ currency = self.currency(code)
1175
+ stringValue = Precise.string_div(self.number_to_string(amount), self.safe_string(currency, 'precision'))
1176
+ return int(stringValue)
1187
1177
 
1188
- def custom_currency_to_precision(self, code, amount, networkCode=None):
1189
- amountPrecision = self.number_to_string(self.to_precision(amount, self.currencies[code]['precision']))
1190
- return self.parse_to_int(float(amountPrecision))
1178
+ def from_real_currency_amount(self, code: str, amountString: str):
1179
+ if not (code in self.currencies):
1180
+ return amountString
1181
+ currency = self.currency(code)
1182
+ precisionAmount = self.safe_string(currency, 'precision')
1183
+ return Precise.string_mul(amountString, precisionAmount)
1191
1184
 
1192
- def from_precision(self, amount, scale):
1193
- if amount is None:
1194
- return None
1195
- precise = Precise(amount)
1196
- precise.decimals = self.sum(precise.decimals, scale)
1197
- precise.reduce()
1198
- return str(precise)
1185
+ def to_real_symbol_price(self, symbol: str, price: float):
1186
+ market = self.market(symbol)
1187
+ stringValue = Precise.string_div(self.number_to_string(price), self.safe_string(market['precision'], 'price'))
1188
+ return int(stringValue)
1199
1189
 
1200
- def to_precision(self, amount, scale):
1201
- amountString = self.number_to_string(amount)
1202
- precise = Precise(amountString)
1203
- # precise.decimals should be integer
1204
- precise.decimals = self.parse_to_int(Precise.string_sub(self.number_to_string(precise.decimals), self.number_to_string(scale)))
1205
- precise.reduce()
1206
- stringValue = str(precise)
1207
- return stringValue
1190
+ def from_real_symbol_price(self, symbol: str, priceString: str):
1191
+ market = self.markets[symbol]
1192
+ return Precise.string_mul(priceString, self.safe_string(market['precision'], 'price'))
1208
1193
 
1209
- def currency_from_precision(self, currency, amount):
1210
- scale = self.currencies[currency]['precision']
1211
- return self.from_precision(amount, scale)
1194
+ def to_real_symbol_amount(self, symbol: str, amount: float):
1195
+ market = self.market(symbol)
1196
+ stringValue = Precise.string_div(self.number_to_string(amount), self.safe_string(market['precision'], 'amount'))
1197
+ return int(stringValue)
1212
1198
 
1213
- def price_from_precision(self, symbol, price):
1199
+ def from_real_symbol_amount(self, symbol: str, amountString: str):
1214
1200
  market = self.markets[symbol]
1215
- wavesPrecision = self.safe_integer(self.options, 'wavesPrecision', 8)
1216
- scale = self.sum(wavesPrecision, market['precision']['price']) - market['precision']['amount']
1217
- return self.from_precision(price, scale)
1201
+ return Precise.string_mul(amountString, market['precision']['amount'])
1218
1202
 
1219
1203
  def safe_get_dynamic(self, settings):
1220
1204
  orderFee = self.safe_value(settings, 'orderFee')
@@ -1288,26 +1272,26 @@ class wavesexchange(Exchange, ImplicitAPI):
1288
1272
  raise InvalidOrder(self.id + ' asset fee must be ' + baseFeeAsset + ' or ' + discountFeeAsset)
1289
1273
  matcherFeeAsset = self.safe_currency_code(matcherFeeAssetId)
1290
1274
  rawMatcherFee = baseMatcherFee if (matcherFeeAssetId == baseFeeAssetId) else discountMatcherFee
1291
- floatMatcherFee = float(self.currency_from_precision(matcherFeeAsset, rawMatcherFee))
1275
+ floatMatcherFee = float(self.from_real_currency_amount(matcherFeeAsset, rawMatcherFee))
1292
1276
  if (matcherFeeAsset in balances) and (balances[matcherFeeAsset]['free'] >= floatMatcherFee):
1293
1277
  matcherFee = int(rawMatcherFee)
1294
1278
  else:
1295
1279
  raise InsufficientFunds(self.id + ' not enough funds of the selected asset fee')
1280
+ floatBaseMatcherFee = self.from_real_currency_amount(baseFeeAsset, baseMatcherFee)
1281
+ floatDiscountMatcherFee = self.from_real_currency_amount(discountFeeAsset, discountMatcherFee)
1296
1282
  if matcherFeeAssetId is None:
1297
1283
  # try to the pay the fee using the base first then discount asset
1298
- floatBaseMatcherFee = float(self.currency_from_precision(baseFeeAsset, baseMatcherFee))
1299
- if (baseFeeAsset in balances) and (balances[baseFeeAsset]['free'] >= floatBaseMatcherFee):
1284
+ if (baseFeeAsset in balances) and (balances[baseFeeAsset]['free'] >= float(floatBaseMatcherFee)):
1300
1285
  matcherFeeAssetId = baseFeeAssetId
1301
1286
  matcherFee = int(baseMatcherFee)
1302
1287
  else:
1303
- floatDiscountMatcherFee = float(self.currency_from_precision(discountFeeAsset, discountMatcherFee))
1304
- if (discountFeeAsset in balances) and (balances[discountFeeAsset]['free'] >= floatDiscountMatcherFee):
1288
+ if (discountFeeAsset in balances) and (balances[discountFeeAsset]['free'] >= float(floatDiscountMatcherFee)):
1305
1289
  matcherFeeAssetId = discountFeeAssetId
1306
1290
  matcherFee = int(discountMatcherFee)
1307
1291
  if matcherFeeAssetId is None:
1308
- raise InsufficientFunds(self.id + ' not enough funds on none of the eligible asset fees')
1309
- amount = self.custom_amount_to_precision(symbol, amount)
1310
- price = self.custom_price_to_precision(symbol, price)
1292
+ raise InsufficientFunds(self.id + ' not enough funds on none of the eligible asset fees: ' + baseFeeAsset + ' ' + floatBaseMatcherFee + ' or ' + discountFeeAsset + ' ' + floatDiscountMatcherFee)
1293
+ amount = self.to_real_symbol_amount(symbol, amount)
1294
+ price = self.to_real_symbol_price(symbol, price)
1311
1295
  assetPair: dict = {
1312
1296
  'amountAsset': amountAsset,
1313
1297
  'priceAsset': priceAsset,
@@ -1345,7 +1329,7 @@ class wavesexchange(Exchange, ImplicitAPI):
1345
1329
  'c': {
1346
1330
  't': 'sp',
1347
1331
  'v': {
1348
- 'p': self.custom_price_to_precision(symbol, stopPrice),
1332
+ 'p': self.to_real_symbol_price(symbol, stopPrice),
1349
1333
  },
1350
1334
  },
1351
1335
  }
@@ -1671,23 +1655,23 @@ class wavesexchange(Exchange, ImplicitAPI):
1671
1655
  elif market is not None:
1672
1656
  symbol = market['symbol']
1673
1657
  amountCurrency = self.safe_currency_code(self.safe_string(assetPair, 'amountAsset', 'WAVES'))
1674
- price = self.price_from_precision(symbol, priceString)
1675
- amount = self.currency_from_precision(amountCurrency, amountString)
1676
- filled = self.currency_from_precision(amountCurrency, filledString)
1677
- average = self.price_from_precision(symbol, self.safe_string(order, 'avgWeighedPrice'))
1658
+ price = self.from_real_symbol_price(symbol, priceString)
1659
+ amount = self.from_real_currency_amount(amountCurrency, amountString)
1660
+ filled = self.from_real_currency_amount(amountCurrency, filledString)
1661
+ average = self.from_real_symbol_price(symbol, self.safe_string(order, 'avgWeighedPrice'))
1678
1662
  status = self.parse_order_status(self.safe_string(order, 'status'))
1679
1663
  fee = None
1680
1664
  if 'type' in order:
1681
- currency = self.safe_currency_code(self.safe_string(order, 'feeAsset'))
1665
+ code = self.safe_currency_code(self.safe_string(order, 'feeAsset'))
1682
1666
  fee = {
1683
- 'currency': currency,
1684
- 'fee': self.parse_number(self.currency_from_precision(currency, self.safe_string(order, 'filledFee'))),
1667
+ 'currency': code,
1668
+ 'fee': self.parse_number(self.from_real_currency_amount(code, self.safe_string(order, 'filledFee'))),
1685
1669
  }
1686
1670
  else:
1687
- currency = self.safe_currency_code(self.safe_string(order, 'matcherFeeAssetId', 'WAVES'))
1671
+ code = self.safe_currency_code(self.safe_string(order, 'matcherFeeAssetId', 'WAVES'))
1688
1672
  fee = {
1689
- 'currency': currency,
1690
- 'fee': self.parse_number(self.currency_from_precision(currency, self.safe_string(order, 'matcherFee'))),
1673
+ 'currency': code,
1674
+ 'fee': self.parse_number(self.from_real_currency_amount(code, self.safe_string(order, 'matcherFee'))),
1691
1675
  }
1692
1676
  triggerPrice = None
1693
1677
  attachment = self.safe_string(order, 'attachment')
@@ -1802,16 +1786,14 @@ class wavesexchange(Exchange, ImplicitAPI):
1802
1786
  issueTransaction = self.safe_value(entry, 'issueTransaction')
1803
1787
  currencyId = self.safe_string(entry, 'assetId')
1804
1788
  balance = self.safe_string(entry, 'balance')
1805
- if issueTransaction is None:
1806
- assetIds.append(currencyId)
1807
- nonStandardBalances.append(balance)
1808
- continue
1809
- decimals = self.safe_integer(issueTransaction, 'decimals')
1810
- code = None
1811
- if currencyId in self.currencies_by_id:
1789
+ currencyExists = (currencyId in self.currencies_by_id)
1790
+ if currencyExists:
1812
1791
  code = self.safe_currency_code(currencyId)
1813
1792
  result[code] = self.account()
1814
- result[code]['total'] = self.from_precision(balance, decimals)
1793
+ result[code]['total'] = self.from_real_currency_amount(code, balance)
1794
+ elif issueTransaction is None:
1795
+ assetIds.append(currencyId)
1796
+ nonStandardBalances.append(balance)
1815
1797
  nonStandardAssets = len(assetIds)
1816
1798
  if nonStandardAssets:
1817
1799
  requestInner: dict = {
@@ -1823,11 +1805,11 @@ class wavesexchange(Exchange, ImplicitAPI):
1823
1805
  entry = data[i]
1824
1806
  balance = nonStandardBalances[i]
1825
1807
  inner = self.safe_value(entry, 'data')
1826
- decimals = self.safe_integer(inner, 'precision')
1808
+ precision = self.parse_precision(self.safe_string(inner, 'precision'))
1827
1809
  ticker = self.safe_string(inner, 'ticker')
1828
1810
  code = self.safe_currency_code(ticker)
1829
1811
  result[code] = self.account()
1830
- result[code]['total'] = self.from_precision(balance, decimals)
1812
+ result[code]['total'] = Precise.string_mul(balance, precision)
1831
1813
  currentTimestamp = self.milliseconds()
1832
1814
  byteArray = [
1833
1815
  self.base58_to_binary(self.apiKey),
@@ -1850,10 +1832,7 @@ class wavesexchange(Exchange, ImplicitAPI):
1850
1832
  if not (code in result):
1851
1833
  result[code] = self.account()
1852
1834
  amount = self.safe_string(reservedBalance, currencyId)
1853
- if code in self.currencies:
1854
- result[code]['used'] = self.currency_from_precision(code, amount)
1855
- else:
1856
- result[code]['used'] = amount
1835
+ result[code]['used'] = self.from_real_currency_amount(code, amount)
1857
1836
  wavesRequest: dict = {
1858
1837
  'address': wavesAddress,
1859
1838
  }
@@ -1863,17 +1842,21 @@ class wavesexchange(Exchange, ImplicitAPI):
1863
1842
  # "confirmations": 0,
1864
1843
  # "balance": 909085978
1865
1844
  # }
1866
- result['WAVES'] = self.safe_value(result, 'WAVES', {})
1867
- result['WAVES']['total'] = self.currency_from_precision('WAVES', self.safe_string(wavesTotal, 'balance'))
1868
- codes = list(result.keys())
1869
- for i in range(0, len(codes)):
1870
- code = codes[i]
1871
- if self.safe_value(result[code], 'used') is None:
1872
- result[code]['used'] = '0'
1845
+ result['WAVES'] = self.safe_value(result, 'WAVES', self.account())
1846
+ result['WAVES']['total'] = self.from_real_currency_amount('WAVES', self.safe_string(wavesTotal, 'balance'))
1847
+ result = self.set_undefined_balances_to_zero(result)
1873
1848
  result['timestamp'] = timestamp
1874
1849
  result['datetime'] = self.iso8601(timestamp)
1875
1850
  return self.safe_balance(result)
1876
1851
 
1852
+ def set_undefined_balances_to_zero(self, balances, key='used'):
1853
+ codes = list(balances.keys())
1854
+ for i in range(0, len(codes)):
1855
+ code = codes[i]
1856
+ if self.safe_value(balances[code], 'used') is None:
1857
+ balances[code][key] = '0'
1858
+ return balances
1859
+
1877
1860
  async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1878
1861
  """
1879
1862
  fetch all trades made by the user
@@ -2374,7 +2357,7 @@ class wavesexchange(Exchange, ImplicitAPI):
2374
2357
  feeAssetId = 'WAVES'
2375
2358
  type = 4 # transfer
2376
2359
  version = 2
2377
- amountInteger = self.custom_currency_to_precision(code, amount)
2360
+ amountInteger = self.to_real_currency_amount(code, amount)
2378
2361
  currency = self.currency(code)
2379
2362
  timestamp = self.milliseconds()
2380
2363
  byteArray = [
@@ -2434,18 +2417,45 @@ class wavesexchange(Exchange, ImplicitAPI):
2434
2417
  # "amount": 0
2435
2418
  # }
2436
2419
  #
2420
+ # withdraw new:
2421
+ # {
2422
+ # type: "4",
2423
+ # id: "2xnWTqG9ar7jEDrLxfbVyyspPZ6XZNrrw9ai9sQ81Eya",
2424
+ # fee: "100000",
2425
+ # feeAssetId: null,
2426
+ # timestamp: "1715786263807",
2427
+ # version: "2",
2428
+ # sender: "3P81LLX1kk2CSJC9L8C2enxdHB7XvnSGAEE",
2429
+ # senderPublicKey: "DdmzmXf9mty1FBE8AdVGnrncVLEAzP4gR4nWoTFAJoXz",
2430
+ # proofs: ["RyoKwdSYv3EqotJCYftfFM9JE2j1ZpDRxKwYfiRhLAFeyNp6VfJUXNDS884XfeCeHeNypNmTCZt5NYR1ekyjCX3",],
2431
+ # recipient: "3P9tXxu38a8tgewNEKFzourVxeqHd11ppOc",
2432
+ # assetId: null,
2433
+ # feeAsset: null,
2434
+ # amount: "2000000",
2435
+ # attachment: "",
2436
+ # }
2437
+ #
2437
2438
  currency = self.safe_currency(None, currency)
2439
+ code = currency['code']
2440
+ typeRaw = self.safe_string(transaction, 'type')
2441
+ type = 'withdraw' if (typeRaw == '4') else 'deposit'
2442
+ amount = self.parse_number(self.from_real_currency_amount(code, self.safe_string(transaction, 'amount')))
2443
+ feeString = self.safe_string(transaction, 'fee')
2444
+ feeAssetId = self.safe_string(transaction, 'feeAssetId', 'WAVES')
2445
+ feeCode = self.safe_currency_code(feeAssetId)
2446
+ feeAmount = self.parse_number(self.from_real_currency_amount(feeCode, feeString))
2447
+ timestamp = self.safe_integer(transaction, 'timestamp')
2438
2448
  return {
2439
- 'id': None,
2449
+ 'id': self.safe_string(transaction, 'id'),
2440
2450
  'txid': None,
2441
- 'timestamp': None,
2442
- 'datetime': None,
2451
+ 'timestamp': timestamp,
2452
+ 'datetime': self.iso8601(timestamp),
2443
2453
  'network': None,
2444
- 'addressFrom': None,
2454
+ 'addressFrom': self.safe_string(transaction, 'sender'),
2445
2455
  'address': None,
2446
- 'addressTo': None,
2447
- 'amount': None,
2448
- 'type': None,
2456
+ 'addressTo': self.safe_string(transaction, 'recipient'),
2457
+ 'amount': amount,
2458
+ 'type': type,
2449
2459
  'currency': currency['code'],
2450
2460
  'status': None,
2451
2461
  'updated': None,
@@ -2454,6 +2464,9 @@ class wavesexchange(Exchange, ImplicitAPI):
2454
2464
  'tagTo': None,
2455
2465
  'comment': None,
2456
2466
  'internal': None,
2457
- 'fee': None,
2467
+ 'fee': {
2468
+ 'currency': feeCode,
2469
+ 'cost': feeAmount,
2470
+ },
2458
2471
  'info': transaction,
2459
2472
  }
ccxt/async_support/xt.py CHANGED
@@ -39,7 +39,7 @@ class xt(Exchange, ImplicitAPI):
39
39
  # futures 1000 times per minute for each single IP -> Otherwise account locked for 10min
40
40
  'rateLimit': 100,
41
41
  'version': 'v4',
42
- 'certified': True,
42
+ 'certified': False,
43
43
  'pro': False,
44
44
  'has': {
45
45
  'CORS': False,
ccxt/base/exchange.py CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # -----------------------------------------------------------------------------
6
6
 
7
- __version__ = '4.3.44'
7
+ __version__ = '4.3.45'
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
 
ccxt/bitstamp.py CHANGED
@@ -232,7 +232,7 @@ class bitstamp(Exchange, ImplicitAPI):
232
232
  'uni_withdrawal/': 1,
233
233
  'uni_address/': 1,
234
234
  'yfi_withdrawal/': 1,
235
- 'yfi_address': 1,
235
+ 'yfi_address/': 1,
236
236
  'audio_withdrawal/': 1,
237
237
  'audio_address/': 1,
238
238
  'crv_withdrawal/': 1,
@@ -241,7 +241,7 @@ class bitstamp(Exchange, ImplicitAPI):
241
241
  'algo_address/': 1,
242
242
  'comp_withdrawal/': 1,
243
243
  'comp_address/': 1,
244
- 'grt_withdrawal': 1,
244
+ 'grt_withdrawal/': 1,
245
245
  'grt_address/': 1,
246
246
  'usdt_withdrawal/': 1,
247
247
  'usdt_address/': 1,
@@ -379,6 +379,22 @@ class bitstamp(Exchange, ImplicitAPI):
379
379
  'vchf_address/': 1,
380
380
  'veur_withdrawal/': 1,
381
381
  'veur_address/': 1,
382
+ 'truf_withdrawal/': 1,
383
+ 'truf_address/': 1,
384
+ 'wif_withdrawal/': 1,
385
+ 'wif_address/': 1,
386
+ 'smt_withdrawal/': 1,
387
+ 'smt_address/': 1,
388
+ 'sui_withdrawal/': 1,
389
+ 'sui_address/': 1,
390
+ 'jup_withdrawal/': 1,
391
+ 'jup_address/': 1,
392
+ 'ondo_withdrawal/': 1,
393
+ 'ondo_address/': 1,
394
+ 'boba_withdrawal/': 1,
395
+ 'boba_address/': 1,
396
+ 'pyth_withdrawal/': 1,
397
+ 'pyth_address/': 1,
382
398
  },
383
399
  },
384
400
  },
ccxt/kucoin.py CHANGED
@@ -140,6 +140,7 @@ class kucoin(Exchange, ImplicitAPI):
140
140
  'futuresPublic': 'https://api-futures.kucoin.com',
141
141
  'webExchange': 'https://kucoin.com/_api',
142
142
  'broker': 'https://api-broker.kucoin.com',
143
+ 'earn': 'https://api.kucoin.com',
143
144
  },
144
145
  'www': 'https://www.kucoin.com',
145
146
  'doc': [
@@ -407,6 +408,9 @@ class kucoin(Exchange, ImplicitAPI):
407
408
  'broker/nd/account': 2,
408
409
  'broker/nd/account/apikey': 2,
409
410
  'broker/nd/rebase/download': 3,
411
+ 'broker/nd/transfer/detail': 1,
412
+ 'broker/nd/deposit/detail': 1,
413
+ 'broker/nd/withdraw/detail': 1,
410
414
  },
411
415
  'post': {
412
416
  'broker/nd/transfer': 1,
@@ -418,6 +422,25 @@ class kucoin(Exchange, ImplicitAPI):
418
422
  'broker/nd/account/apikey': 3,
419
423
  },
420
424
  },
425
+ 'earn': {
426
+ 'get': {
427
+ 'otc-loan/loan': 1,
428
+ 'otc-loan/accounts': 1,
429
+ 'earn/redeem-preview': 7.5, # 5EW
430
+ 'earn/saving/products': 7.5, # 5EW
431
+ 'earn/hold-assets': 7.5, # 5EW
432
+ 'earn/promotion/products': 7.5, # 5EW
433
+ 'earn/kcs-staking/products': 7.5, # 5EW
434
+ 'earn/staking/products': 7.5, # 5EW
435
+ 'earn/eth-staking/products': 7.5, # 5EW
436
+ },
437
+ 'post': {
438
+ 'earn/orders': 7.5, # 5EW
439
+ },
440
+ 'delete': {
441
+ 'earn/orders': 7.5, # 5EW
442
+ },
443
+ },
421
444
  },
422
445
  'timeframes': {
423
446
  '1m': '1min',
@@ -4506,6 +4529,8 @@ class kucoin(Exchange, ImplicitAPI):
4506
4529
  endpoint = '/api/' + version + '/' + self.implode_params(path, params)
4507
4530
  if api == 'webExchange':
4508
4531
  endpoint = '/' + self.implode_params(path, params)
4532
+ if api == 'earn':
4533
+ endpoint = '/api/v1/' + self.implode_params(path, params)
4509
4534
  query = self.omit(params, self.extract_params(path))
4510
4535
  endpart = ''
4511
4536
  headers = headers if (headers is not None) else {}
@@ -4521,7 +4546,8 @@ class kucoin(Exchange, ImplicitAPI):
4521
4546
  isFuturePrivate = (api == 'futuresPrivate')
4522
4547
  isPrivate = (api == 'private')
4523
4548
  isBroker = (api == 'broker')
4524
- if isPrivate or isFuturePrivate or isBroker:
4549
+ isEarn = (api == 'earn')
4550
+ if isPrivate or isFuturePrivate or isBroker or isEarn:
4525
4551
  self.check_required_credentials()
4526
4552
  timestamp = str(self.nonce())
4527
4553
  headers = self.extend({
ccxt/luno.py CHANGED
@@ -897,7 +897,15 @@ class luno(Exchange, ImplicitAPI):
897
897
  request: dict = {
898
898
  'order_id': id,
899
899
  }
900
- return self.privatePostStoporder(self.extend(request, params))
900
+ response = self.privatePostStoporder(self.extend(request, params))
901
+ #
902
+ # {
903
+ # "success": True
904
+ # }
905
+ #
906
+ return self.safe_order({
907
+ 'info': response,
908
+ })
901
909
 
902
910
  def fetch_ledger_by_entries(self, code: Str = None, entry=None, limit=None, params={}):
903
911
  # by default without entry number or limit number, return most recent entry