@subwallet/extension-base 1.3.77-0 → 1.3.79-1

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.
Files changed (96) hide show
  1. package/background/KoniTypes.d.ts +5 -3
  2. package/cjs/core/logic-validation/index.js +1 -13
  3. package/cjs/core/substrate/xcm-parser.js +10 -1
  4. package/cjs/koni/background/handlers/Extension.js +41 -9
  5. package/cjs/koni/background/handlers/State.js +20 -0
  6. package/cjs/packageInfo.js +1 -1
  7. package/cjs/services/balance-service/helpers/subscribe/evm.js +85 -6
  8. package/cjs/services/balance-service/helpers/subscribe/index.js +2 -1
  9. package/cjs/services/balance-service/index.js +6 -2
  10. package/cjs/services/balance-service/transfer/token.js +15 -0
  11. package/cjs/services/balance-service/transfer/xcm/bittensorBridge/index.js +27 -0
  12. package/cjs/services/balance-service/transfer/xcm/bittensorBridge/nativeTokenBridge.js +58 -0
  13. package/cjs/services/balance-service/transfer/xcm/bittensorBridge/utils.js +36 -0
  14. package/cjs/services/balance-service/transfer/xcm/index.js +61 -2
  15. package/cjs/services/balance-service/transfer/xcm/utils.js +103 -15
  16. package/cjs/services/chain-service/constants.js +4 -2
  17. package/cjs/services/chain-service/utils/patch.js +1 -1
  18. package/cjs/services/earning-service/constants/chains.js +4 -2
  19. package/cjs/services/earning-service/handlers/native-staking/dtao.js +13 -13
  20. package/cjs/services/earning-service/handlers/native-staking/tao.js +16 -10
  21. package/cjs/services/earning-service/handlers/special.js +89 -65
  22. package/cjs/services/earning-service/service.js +1 -0
  23. package/cjs/services/swap-service/handler/asset-hub/handler.js +7 -4
  24. package/cjs/services/swap-service/handler/asset-hub/router.js +2 -66
  25. package/cjs/services/swap-service/handler/base-handler.js +4 -3
  26. package/cjs/services/swap-service/handler/bittensor-handler.js +197 -0
  27. package/cjs/services/swap-service/handler/hydradx-handler.js +9 -5
  28. package/cjs/services/swap-service/index.js +12 -4
  29. package/cjs/services/transaction-service/index.js +1 -0
  30. package/cjs/types/balance/index.js +1 -0
  31. package/cjs/types/swap/index.js +7 -10
  32. package/cjs/utils/account/common.js +44 -8
  33. package/cjs/utils/fee/transfer.js +20 -5
  34. package/core/logic-validation/index.d.ts +0 -1
  35. package/core/logic-validation/index.js +1 -2
  36. package/core/substrate/xcm-parser.d.ts +2 -0
  37. package/core/substrate/xcm-parser.js +8 -1
  38. package/koni/background/handlers/Extension.d.ts +3 -0
  39. package/koni/background/handlers/Extension.js +42 -10
  40. package/koni/background/handlers/State.d.ts +1 -0
  41. package/koni/background/handlers/State.js +20 -0
  42. package/package.json +26 -11
  43. package/packageInfo.js +1 -1
  44. package/services/balance-service/helpers/subscribe/evm.d.ts +1 -0
  45. package/services/balance-service/helpers/subscribe/evm.js +76 -1
  46. package/services/balance-service/helpers/subscribe/index.js +2 -1
  47. package/services/balance-service/index.js +6 -2
  48. package/services/balance-service/transfer/token.d.ts +2 -1
  49. package/services/balance-service/transfer/token.js +15 -0
  50. package/services/balance-service/transfer/xcm/bittensorBridge/index.d.ts +2 -0
  51. package/services/balance-service/transfer/xcm/bittensorBridge/index.js +5 -0
  52. package/services/balance-service/transfer/xcm/bittensorBridge/nativeTokenBridge.d.ts +6 -0
  53. package/services/balance-service/transfer/xcm/bittensorBridge/nativeTokenBridge.js +50 -0
  54. package/services/balance-service/transfer/xcm/bittensorBridge/utils.d.ts +8 -0
  55. package/services/balance-service/transfer/xcm/bittensorBridge/utils.js +29 -0
  56. package/services/balance-service/transfer/xcm/index.d.ts +5 -0
  57. package/services/balance-service/transfer/xcm/index.js +57 -2
  58. package/services/balance-service/transfer/xcm/utils.d.ts +3 -2
  59. package/services/balance-service/transfer/xcm/utils.js +96 -10
  60. package/services/chain-service/constants.d.ts +2 -0
  61. package/services/chain-service/constants.js +4 -2
  62. package/services/chain-service/utils/patch.d.ts +1 -1
  63. package/services/chain-service/utils/patch.js +1 -1
  64. package/services/earning-service/constants/chains.d.ts +1 -0
  65. package/services/earning-service/constants/chains.js +2 -1
  66. package/services/earning-service/handlers/native-staking/dtao.js +12 -13
  67. package/services/earning-service/handlers/native-staking/tao.d.ts +2 -1
  68. package/services/earning-service/handlers/native-staking/tao.js +15 -10
  69. package/services/earning-service/handlers/special.d.ts +1 -1
  70. package/services/earning-service/handlers/special.js +92 -68
  71. package/services/earning-service/service.js +1 -0
  72. package/services/swap-service/handler/asset-hub/handler.js +7 -4
  73. package/services/swap-service/handler/asset-hub/router.d.ts +0 -4
  74. package/services/swap-service/handler/asset-hub/router.js +1 -64
  75. package/services/swap-service/handler/base-handler.js +4 -3
  76. package/services/swap-service/handler/bittensor-handler.d.ts +21 -0
  77. package/services/swap-service/handler/bittensor-handler.js +189 -0
  78. package/services/swap-service/handler/hydradx-handler.js +9 -5
  79. package/services/swap-service/index.js +12 -4
  80. package/services/transaction-service/index.js +1 -0
  81. package/services/transaction-service/types.d.ts +4 -3
  82. package/types/balance/index.d.ts +3 -1
  83. package/types/balance/index.js +1 -0
  84. package/types/balance/transfer.d.ts +7 -0
  85. package/types/fee/base.d.ts +1 -0
  86. package/types/swap/index.d.ts +10 -36
  87. package/types/swap/index.js +6 -9
  88. package/types/yield/actions/join/step.d.ts +7 -0
  89. package/types/yield/actions/join/submit.d.ts +3 -1
  90. package/utils/account/common.d.ts +22 -1
  91. package/utils/account/common.js +44 -8
  92. package/utils/fee/transfer.d.ts +1 -0
  93. package/utils/fee/transfer.js +21 -6
  94. package/cjs/core/logic-validation/swap.js +0 -235
  95. package/core/logic-validation/swap.d.ts +0 -26
  96. package/core/logic-validation/swap.js +0 -219
@@ -12,6 +12,7 @@ var _utils = require("@subwallet/extension-base/koni/api/yield/helper/utils");
12
12
  var _xcm = require("@subwallet/extension-base/services/balance-service/transfer/xcm");
13
13
  var _utils2 = require("@subwallet/extension-base/services/balance-service/transfer/xcm/utils");
14
14
  var _utils3 = require("@subwallet/extension-base/services/chain-service/utils");
15
+ var _constants2 = require("@subwallet/extension-base/services/earning-service/constants");
15
16
  var _types = require("@subwallet/extension-base/types");
16
17
  var _utils4 = require("@subwallet/extension-base/utils");
17
18
  var _getId = require("@subwallet/extension-base/utils/getId");
@@ -214,51 +215,52 @@ class BaseSpecialStakingPoolHandler extends _base.default {
214
215
  address,
215
216
  amount
216
217
  } = params;
217
- const bnAmount = new _util.BN(amount);
218
+ const bnStakeAmount = new _bignumber.default(amount);
218
219
  const inputTokenSlug = this.inputAsset; // assume that the pool only has 1 input token, will update later
219
220
  const inputTokenInfo = this.state.getAssetBySlug(inputTokenSlug);
220
221
  const inputTokenBalance = await this.state.balanceService.getTransferableBalance(address, inputTokenInfo.originChain, inputTokenSlug);
221
- const bnInputTokenBalance = new _util.BN(inputTokenBalance.value);
222
- if (!bnInputTokenBalance.gte(bnAmount)) {
222
+ const bnInputTokenBalance = new _bignumber.default(inputTokenBalance.value);
223
+ if (amount && !bnInputTokenBalance.gte(bnStakeAmount)) {
223
224
  if (this.altInputAsset) {
224
225
  const altInputTokenSlug = this.altInputAsset;
225
226
  const altInputTokenInfo = this.state.getAssetBySlug(altInputTokenSlug);
226
227
  const altInputTokenBalance = await this.state.balanceService.getTransferableBalance(address, altInputTokenInfo.originChain, altInputTokenSlug);
227
- const bnAltInputTokenBalance = new _util.BN(altInputTokenBalance.value || '0');
228
- if (bnAltInputTokenBalance.gt(_util.BN_ZERO)) {
228
+ const bnAltInputTokenBalance = new _bignumber.default(altInputTokenBalance.value || '0');
229
+ if (bnAltInputTokenBalance.gt((0, _bignumber.default)(0))) {
229
230
  const altChainInfo = this.state.getChainInfo(altInputTokenInfo.originChain);
230
231
  const symbol = altInputTokenInfo.symbol;
231
232
  const networkName = altChainInfo.name;
232
-
233
- // TODO: calculate fee for destination chain
234
- const xcmFeeInfo = await (0, _utils2.estimateXcmFee)({
233
+ const xcmRequest = {
235
234
  fromChainInfo: altChainInfo,
236
235
  fromTokenInfo: altInputTokenInfo,
237
236
  toChainInfo: this.chainInfo,
238
237
  recipient: address,
239
238
  sender: address,
240
- value: bnAmount.toString()
241
- });
239
+ value: bnStakeAmount.toString()
240
+ };
241
+ const [xcmFeeInfo, _minXcmTransferableAmount] = await Promise.all([(0, _utils2.estimateXcmFee)(xcmRequest), (0, _xcm.getMinXcmTransferableAmount)(xcmRequest)]);
242
242
  if (!xcmFeeInfo) {
243
243
  throw new Error('Error estimating XCM fee');
244
244
  }
245
- const xcmFee = (0, _bignumber.default)(xcmFeeInfo.origin.fee).multipliedBy(_constants.XCM_MIN_AMOUNT_RATIO).toFixed(0, 1);
245
+ const xcmOriginFee = (0, _bignumber.default)(xcmFeeInfo.origin.fee).toFixed(0, 1);
246
+ const xcmDestinationFee = (0, _bignumber.default)(xcmFeeInfo.destination.fee).toFixed(0, 1);
246
247
  const fee = {
247
248
  slug: altInputTokenSlug,
248
- amount: xcmFee
249
+ amount: xcmOriginFee
249
250
  };
250
- let bnTransferAmount = bnAmount.sub(bnInputTokenBalance);
251
- if ((0, _utils3._isNativeToken)(altInputTokenInfo)) {
252
- const bnXcmFee = new _util.BN(fee.amount || 0); // xcm fee is paid in native token but swap token is not always native token
253
-
254
- bnTransferAmount = bnTransferAmount.add(bnXcmFee);
251
+ let sendingValue = bnStakeAmount.minus(bnInputTokenBalance).plus(xcmDestinationFee).toString();
252
+ const minXcmTransferableAmount = _minXcmTransferableAmount || _constants2.MIN_XCM_LIQUID_STAKING_DOT;
253
+ if (new _bignumber.default(minXcmTransferableAmount).gt(sendingValue)) {
254
+ sendingValue = minXcmTransferableAmount;
255
255
  }
256
+ const metadata = {
257
+ sendingValue,
258
+ xcmDestinationFee,
259
+ originTokenInfo: altInputTokenInfo,
260
+ destinationTokenInfo: inputTokenInfo
261
+ };
256
262
  const step = {
257
- metadata: {
258
- sendingValue: bnTransferAmount.toString(),
259
- originTokenInfo: altInputTokenInfo,
260
- destinationTokenInfo: inputTokenInfo
261
- },
263
+ metadata: metadata,
262
264
  name: `Transfer ${symbol} from ${networkName}`,
263
265
  type: _types.YieldStepType.XCM
264
266
  };
@@ -301,31 +303,35 @@ class BaseSpecialStakingPoolHandler extends _base.default {
301
303
  return Promise.resolve([new _TransactionError.TransactionError(_types.BasicTxErrorType.UNSUPPORTED)]);
302
304
  }
303
305
  async validateXcmStep(params, path, bnInputTokenBalance) {
306
+ // todo: BN -> BigN or BigInt
304
307
  const processValidation = {
305
308
  ok: true,
306
309
  status: _types.YieldValidationStatus.OK
307
310
  };
308
- const bnAmount = new _util.BN(params.amount);
309
- const altInputTokenSlug = this.altInputAsset || '';
310
- const altInputTokenInfo = this.state.getAssetBySlug(altInputTokenSlug);
311
- const inputTokenInfo = this.state.getAssetBySlug(this.inputAsset);
312
- const altInputTokenBalance = await this.state.balanceService.getTransferableBalance(params.address, altInputTokenInfo.originChain, altInputTokenSlug);
313
- const missingAmount = bnAmount.sub(bnInputTokenBalance); // TODO: what if input token is not LOCAL ??
314
- const xcmFeeValidate = new _util.BN(path.totalFee[1].amount || '0').mul(new _util.BN(_constants.XCM_FEE_RATIO));
315
- const bnAltInputTokenBalance = new _util.BN(altInputTokenBalance.value || '0');
316
- if (!bnAltInputTokenBalance.sub(missingAmount).sub(xcmFeeValidate).gt(_util.BN_ZERO)) {
311
+ const metadata = path.steps[1].metadata;
312
+ const {
313
+ destinationTokenInfo,
314
+ originTokenInfo,
315
+ sendingValue
316
+ } = metadata;
317
+ const originChainInfo = this.state.getChainInfo(originTokenInfo.originChain);
318
+ const originTokenBalance = await this.state.balanceService.getTransferableBalance(params.address, originTokenInfo.originChain, originTokenInfo.slug);
319
+ const bnOriginTokenBalance = new _util.BN(originTokenBalance.value || '0');
320
+ const bnAdjustOriginFee = new _util.BN(path.totalFee[1].amount || '0').mul(new _util.BN(_constants.XCM_MIN_AMOUNT_RATIO));
321
+ const bnSendingValue = new _util.BN(sendingValue);
322
+ if (!bnOriginTokenBalance.sub(bnSendingValue).sub(bnAdjustOriginFee).gt(_util.BN_ZERO)) {
317
323
  processValidation.failedStep = path.steps[1];
318
324
  processValidation.ok = false;
319
325
  processValidation.status = _types.YieldValidationStatus.NOT_ENOUGH_BALANCE;
320
- const bnMaxXCM = new _util.BN(altInputTokenBalance.value).sub(xcmFeeValidate);
321
- const inputTokenDecimal = (0, _utils3._getAssetDecimals)(inputTokenInfo);
322
- const maxBn = bnInputTokenBalance.add(bnAltInputTokenBalance.sub(xcmFeeValidate));
323
- const maxValue = (0, _utils4.formatNumber)(maxBn.toString(), inputTokenInfo.decimals || 0);
324
- const maxXCMValue = (0, _utils4.formatNumber)(bnMaxXCM.toString(), inputTokenDecimal);
325
- const symbol = (0, _utils3._getAssetSymbol)(altInputTokenInfo);
326
+ const bnMaxXCM = new _util.BN(originTokenBalance.value).sub(bnAdjustOriginFee);
327
+ const destinationTokenDecimal = (0, _utils3._getAssetDecimals)(destinationTokenInfo);
328
+ const maxBn = bnInputTokenBalance.add(bnOriginTokenBalance.sub(bnAdjustOriginFee));
329
+ const maxValue = (0, _utils4.formatNumber)(maxBn.toString(), destinationTokenInfo.decimals || 0);
330
+ const maxXCMValue = (0, _utils4.formatNumber)(bnMaxXCM.toString(), destinationTokenDecimal);
331
+ const symbol = (0, _utils3._getAssetSymbol)(originTokenInfo);
326
332
  const inputNetworkName = this.chainInfo.name;
327
- const altNetworkName = (0, _utils3._getAssetName)(altInputTokenInfo);
328
- const currentValue = (0, _utils4.formatNumber)(bnInputTokenBalance.toString(), inputTokenDecimal);
333
+ const altNetworkName = (0, _utils3._getChainName)(originChainInfo);
334
+ const currentValue = (0, _utils4.formatNumber)(bnInputTokenBalance.toString(), destinationTokenDecimal);
329
335
  processValidation.message = (0, _i18next.t)('bg.EARNING.services.service.earning.specialHandler.maximumInputExceeded', {
330
336
  replace: {
331
337
  symbol,
@@ -338,6 +344,24 @@ class BaseSpecialStakingPoolHandler extends _base.default {
338
344
  });
339
345
  return [new _TransactionError.TransactionError(_types.YieldValidationStatus.NOT_ENOUGH_BALANCE, processValidation.message, processValidation)];
340
346
  }
347
+ const id = (0, _getId.getId)();
348
+ const feeInfo = await this.state.feeService.subscribeChainFee(id, originChainInfo.slug, 'substrate');
349
+ const substrateApi = this.state.getSubstrateApi(originChainInfo.slug);
350
+ const xcmRequest = {
351
+ destinationTokenInfo: destinationTokenInfo,
352
+ originTokenInfo: originTokenInfo,
353
+ recipient: params.address,
354
+ sendingValue,
355
+ substrateApi,
356
+ sender: params.address,
357
+ originChain: originChainInfo,
358
+ destinationChain: this.chainInfo,
359
+ feeInfo
360
+ };
361
+ const isDryRunSuccess = await (0, _xcm.dryRunXcmExtrinsicV2)(xcmRequest);
362
+ if (!isDryRunSuccess) {
363
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.UNABLE_TO_SEND, 'Unable to perform transaction. Select another token or destination chain and try again')];
364
+ }
341
365
  return [];
342
366
  }
343
367
  async validateJoinStep(id, params, path, bnInputTokenBalance, isXcmOk) {
@@ -357,7 +381,7 @@ class BaseSpecialStakingPoolHandler extends _base.default {
357
381
  const feeTokenInfo = this.state.getAssetBySlug(feeTokenSlug);
358
382
  const inputTokenInfo = this.state.getAssetBySlug(this.inputAsset);
359
383
  const defaultFeeTokenSlug = this.feeAssets[0];
360
- const bnAmount = new _util.BN(params.amount);
384
+ const bnStakeAmount = new _util.BN(params.amount);
361
385
  if (this.feeAssets.length === 1 && feeTokenSlug === defaultFeeTokenSlug) {
362
386
  var _path$totalFee$id;
363
387
  const bnFeeAmount = new _util.BN(((_path$totalFee$id = path.totalFee[id]) === null || _path$totalFee$id === void 0 ? void 0 : _path$totalFee$id.amount) || '0');
@@ -371,13 +395,13 @@ class BaseSpecialStakingPoolHandler extends _base.default {
371
395
  return [new _TransactionError.TransactionError(_types.YieldValidationStatus.NOT_ENOUGH_FEE, processValidation.message, processValidation)];
372
396
  }
373
397
  }
374
- if (!bnAmount.gte(new _util.BN(poolInfo.statistic.earningThreshold.join || '0'))) {
398
+ if (!bnStakeAmount.gte(new _util.BN(poolInfo.statistic.earningThreshold.join || '0'))) {
375
399
  processValidation.failedStep = path.steps[id];
376
400
  processValidation.ok = false;
377
401
  processValidation.status = _types.YieldValidationStatus.NOT_ENOUGH_MIN_JOIN_POOL;
378
402
  return [new _TransactionError.TransactionError(_types.YieldValidationStatus.NOT_ENOUGH_MIN_JOIN_POOL, processValidation.message, processValidation)];
379
403
  }
380
- if (!isXcmOk && bnAmount.gt(bnInputTokenBalance)) {
404
+ if (!isXcmOk && bnStakeAmount.gt(bnInputTokenBalance)) {
381
405
  processValidation.failedStep = path.steps[id];
382
406
  processValidation.ok = false;
383
407
  processValidation.status = _types.YieldValidationStatus.NOT_ENOUGH_BALANCE;
@@ -401,8 +425,8 @@ class BaseSpecialStakingPoolHandler extends _base.default {
401
425
  const balanceService = this.state.balanceService;
402
426
  const inputTokenBalance = await balanceService.getTransferableBalance(params.address, inputTokenInfo.originChain, inputTokenSlug);
403
427
  const bnInputTokenBalance = new _util.BN(inputTokenBalance.value || '0');
404
- const bnAmount = new _util.BN(params.amount);
405
- if (bnAmount.lte(_util.BN_ZERO)) {
428
+ const bnStakeAmount = new _util.BN(params.amount);
429
+ if (bnStakeAmount.lte(_util.BN_ZERO)) {
406
430
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')];
407
431
  }
408
432
  let isXcmOk = false;
@@ -436,31 +460,26 @@ class BaseSpecialStakingPoolHandler extends _base.default {
436
460
  async handleTokenApproveStep(data, path) {
437
461
  return Promise.reject(new _TransactionError.TransactionError(_types.BasicTxErrorType.UNSUPPORTED));
438
462
  }
439
- async handleXcmStep(data, path, xcmFee) {
463
+ async handleXcmStep(data, path) {
464
+ const metadata = path.steps[1].metadata;
465
+ const xcmStepFee = path.totalFee[1].amount;
466
+ const address = data.address;
440
467
  const {
441
- address,
442
- amount
443
- } = data;
444
- const destinationTokenSlug = this.inputAsset;
445
- const altInputTokenSlug = this.altInputAsset || '';
446
- const altInputTokenInfo = this.state.getAssetBySlug(altInputTokenSlug);
447
- const originChainInfo = this.state.getChainInfo(altInputTokenInfo.originChain);
468
+ destinationTokenInfo,
469
+ originTokenInfo,
470
+ sendingValue,
471
+ xcmDestinationFee
472
+ } = metadata;
473
+ const originChainInfo = this.state.getChainInfo(originTokenInfo.originChain);
448
474
  const originTokenSlug = (0, _utils3._getChainNativeTokenSlug)(originChainInfo);
449
- const originTokenInfo = this.state.getAssetBySlug(originTokenSlug);
450
- const destinationTokenInfo = this.state.getAssetBySlug(destinationTokenSlug);
451
475
  const substrateApi = this.state.getSubstrateApi(originChainInfo.slug);
452
- const inputTokenBalance = await this.state.balanceService.getTransferableBalance(address, destinationTokenInfo.originChain, destinationTokenSlug);
453
- const bnInputTokenBalance = new _util.BN(inputTokenBalance.value);
454
- const bnXcmFee = new _util.BN(xcmFee);
455
- const bnAmount = new _util.BN(amount);
456
- const bnTotalAmount = bnAmount.sub(bnInputTokenBalance).add(bnXcmFee);
457
476
  const id = (0, _getId.getId)();
458
477
  const feeInfo = await this.state.feeService.subscribeChainFee(id, originChainInfo.slug, 'substrate');
459
478
  const xcmRequest = {
460
479
  destinationTokenInfo,
461
480
  originTokenInfo,
462
481
  recipient: address,
463
- sendingValue: bnTotalAmount.toString(),
482
+ sendingValue,
464
483
  substrateApi,
465
484
  sender: address,
466
485
  originChain: originChainInfo,
@@ -476,7 +495,7 @@ class BaseSpecialStakingPoolHandler extends _base.default {
476
495
  destinationNetworkKey: destinationTokenInfo.originChain,
477
496
  from: address,
478
497
  to: address,
479
- value: bnTotalAmount.toString(),
498
+ value: sendingValue,
480
499
  tokenSlug: originTokenSlug,
481
500
  showExtraWarning: true
482
501
  };
@@ -485,8 +504,14 @@ class BaseSpecialStakingPoolHandler extends _base.default {
485
504
  extrinsicType: _KoniTypes.ExtrinsicType.TRANSFER_XCM,
486
505
  extrinsic,
487
506
  txData: xcmData,
488
- transferNativeAmount: bnTotalAmount.toString(),
489
- chainType: _KoniTypes.ChainType.SUBSTRATE
507
+ transferNativeAmount: sendingValue,
508
+ chainType: _KoniTypes.ChainType.SUBSTRATE,
509
+ xcmStepFee,
510
+ xcmDestinationFee: xcmDestinationFee ? {
511
+ decimals: (0, _utils3._getAssetDecimals)(destinationTokenInfo),
512
+ symbol: (0, _utils3._getAssetSymbol)(destinationTokenInfo),
513
+ value: xcmDestinationFee
514
+ } : undefined
490
515
  };
491
516
  }
492
517
  handleYieldJoin(data, path, currentStep) {
@@ -498,8 +523,7 @@ class BaseSpecialStakingPoolHandler extends _base.default {
498
523
  return this.handleTokenApproveStep(data, path);
499
524
  case _types.YieldStepType.XCM:
500
525
  {
501
- const xcmFee = path.totalFee[currentStep].amount || '0';
502
- return this.handleXcmStep(data, path, xcmFee);
526
+ return this.handleXcmStep(data, path);
503
527
  }
504
528
  default:
505
529
  return this.handleSubmitStep(data, path);
@@ -883,6 +883,7 @@ class EarningService {
883
883
  } = params;
884
884
  const handler = this.getPoolHandler(slug);
885
885
  if (handler) {
886
+ console.log('all step', await handler.generateOptimalPath(params));
886
887
  return handler.generateOptimalPath(params);
887
888
  } else {
888
889
  throw new _TransactionError.TransactionError(_types2.BasicTxErrorType.INTERNAL_ERROR);
@@ -71,7 +71,10 @@ class AssetHubSwapHandler {
71
71
  const {
72
72
  path,
73
73
  request: {
74
- fromAmount
74
+ address,
75
+ alternativeAddress,
76
+ fromAmount,
77
+ recipient
75
78
  },
76
79
  selectedQuote
77
80
  } = params;
@@ -93,12 +96,12 @@ class AssetHubSwapHandler {
93
96
  const needModifyData = swapXcm || xcmSwapXcm;
94
97
  let bnSendingValue = (0, _bignumber.default)(fromAmount);
95
98
  let bnExpectedReceive = (0, _bignumber.default)(selectedQuote.toAmount);
96
- const sender = (0, _utils3._reformatAddressWithChain)(params.request.address, originChain);
97
- let receiver = (0, _utils3._reformatAddressWithChain)(params.request.recipient || params.request.address, destinationChain);
99
+ const sender = (0, _utils3._reformatAddressWithChain)(address, originChain, alternativeAddress);
100
+ let receiver = (0, _utils3._reformatAddressWithChain)(recipient || address, destinationChain);
98
101
  if (needModifyData) {
99
102
  bnSendingValue = bnSendingValue.multipliedBy(_utils2.DEFAULT_EXCESS_AMOUNT_WEIGHT);
100
103
  bnExpectedReceive = bnExpectedReceive.multipliedBy(_utils2.DEFAULT_EXCESS_AMOUNT_WEIGHT);
101
- receiver = (0, _utils3._reformatAddressWithChain)(params.request.address, destinationChain);
104
+ receiver = (0, _utils3._reformatAddressWithChain)(address, destinationChain, alternativeAddress);
102
105
  }
103
106
  const submitStep = {
104
107
  name: 'Swap',
@@ -1,14 +1,10 @@
1
1
  "use strict";
2
2
 
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
3
  Object.defineProperty(exports, "__esModule", {
5
4
  value: true
6
5
  });
7
6
  exports.AssetHubRouter = void 0;
8
- var _utils = require("@subwallet/extension-base/services/chain-service/utils");
9
- var _utils2 = require("@subwallet/extension-base/services/swap-service/handler/asset-hub/utils");
10
- var _swap = require("@subwallet/extension-base/types/swap");
11
- var _bignumber = _interopRequireDefault(require("bignumber.js"));
7
+ var _utils = require("@subwallet/extension-base/services/swap-service/handler/asset-hub/utils");
12
8
  // Copyright 2019-2022 @subwallet/extension-base
13
9
  // SPDX-License-Identifier: Apache-2.0
14
10
 
@@ -23,70 +19,10 @@ class AssetHubRouter {
23
19
  get nativeToken() {
24
20
  return this.chainService.getNativeTokenInfo(this.chain);
25
21
  }
26
- buildPath(pair) {
27
- // const nativeToken = this.nativeToken;
28
- // const nativeTokenSlug = nativeToken.slug;
29
-
30
- const assetFrom = this.chainService.getAssetBySlug(pair.from);
31
- const assetTo = this.chainService.getAssetBySlug(pair.to);
32
- return [assetFrom, assetTo];
33
- // if (pair.from === nativeTokenSlug || pair.to === nativeTokenSlug) {
34
- // return [assetFrom, assetTo];
35
- // } else {
36
- // return [assetFrom, nativeToken, assetTo];
37
- // }
38
- }
39
- async earlyValidateSwapValidation(request) {
40
- const substrateApi = await this.substrateApi.isReady;
41
- const paths = this.buildPath(request.pair);
42
- const api = await substrateApi.api.isReady;
43
- const amount = request.fromAmount;
44
- const reserves = await (0, _utils2.getReserveForPath)(api, paths);
45
- const amounts = (0, _utils2.estimateTokensForPath)(amount, reserves);
46
- const marketRate = (0, _utils2.estimateRateForPath)(reserves);
47
- const marketRateAfter = (0, _utils2.estimateRateAfterForPath)(amount, reserves);
48
- const priceImpactPct = (0, _utils2.estimatePriceImpactPct)(marketRate, marketRateAfter);
49
- const errors = [];
50
-
51
- // Check liquidity
52
- const liquidityError = (0, _utils2.checkLiquidityForPath)(amounts, reserves);
53
- if (liquidityError) {
54
- errors.push(liquidityError);
55
- }
56
-
57
- // Check amount token in pool after swap
58
- const minAmounts = paths.map(asset => (0, _utils._getTokenMinAmount)(asset));
59
- const minAmountAfterSwapError = (0, _utils2.checkMinAmountForPath)(reserves, amounts, minAmounts);
60
- if (minAmountAfterSwapError) {
61
- errors.push(minAmountAfterSwapError);
62
- }
63
- const bnAmount = new _bignumber.default(request.fromAmount);
64
- if (bnAmount.lte(0)) {
65
- errors.push(_swap.SwapErrorType.AMOUNT_CANNOT_BE_ZERO);
66
- }
67
- const metadata = {
68
- chain: this.chainService.getChainInfoByKey(this.chain),
69
- toAmount: amounts[amounts.length - 1],
70
- quoteRate: marketRate,
71
- priceImpactPct: priceImpactPct
72
- };
73
- return {
74
- error: errors[0],
75
- metadata
76
- };
77
- }
78
- async estimateAmountOut(pair, amountIn) {
79
- const substrateApi = await this.substrateApi.isReady;
80
- const paths = this.buildPath(pair);
81
- const api = await substrateApi.api.isReady;
82
- const reserves = await (0, _utils2.getReserveForPath)(api, paths);
83
- const amounts = (0, _utils2.estimateTokensForPath)(amountIn, reserves);
84
- return amounts[amounts.length - 1];
85
- }
86
22
  async buildSwapExtrinsic(path, recipient, amountIn, amountOutMin) {
87
23
  const substrateApi = await this.substrateApi.isReady;
88
24
  const api = await substrateApi.api.isReady;
89
- return (0, _utils2.buildSwapExtrinsic)(api, path, recipient, amountIn, amountOutMin);
25
+ return (0, _utils.buildSwapExtrinsic)(api, path, recipient, amountIn, amountOutMin);
90
26
  }
91
27
  }
92
28
  exports.AssetHubRouter = AssetHubRouter;
@@ -79,6 +79,7 @@ class SwapBaseHandler {
79
79
  path,
80
80
  request: {
81
81
  address,
82
+ alternativeAddress,
82
83
  fromAmount,
83
84
  recipient
84
85
  },
@@ -102,12 +103,12 @@ class SwapBaseHandler {
102
103
  throw Error('Token or chain not found');
103
104
  }
104
105
  let recipientAddress;
105
- const senderAddress = (0, _utils5._reformatAddressWithChain)(address, fromChainInfo);
106
+ const senderAddress = (0, _utils5._reformatAddressWithChain)(address, fromChainInfo, alternativeAddress);
106
107
  if (stepIndex === 0) {
107
- recipientAddress = (0, _utils5._reformatAddressWithChain)(address, toChainInfo);
108
+ recipientAddress = (0, _utils5._reformatAddressWithChain)(address, toChainInfo, alternativeAddress);
108
109
  } else {
109
110
  // bridge after swap
110
- recipientAddress = (0, _utils5._reformatAddressWithChain)(recipient || address, toChainInfo);
111
+ recipientAddress = (0, _utils5._reformatAddressWithChain)(recipient || address, toChainInfo, alternativeAddress);
111
112
  }
112
113
  if (!(0, _xcmParser._isXcmWithinSameConsensus)(fromChainInfo, toChainInfo) || (0, _xcmParser._isSnowBridgeXcm)(fromChainInfo, toChainInfo) || (0, _xcmParser._isAcrossBridgeXcm)(fromChainInfo, toChainInfo)) {
113
114
  return undefined;
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.BittensorSwapHandler = void 0;
8
+ var _TransactionError = require("@subwallet/extension-base/background/errors/TransactionError");
9
+ var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
10
+ var _types = require("@subwallet/extension-base/types");
11
+ var _utils = require("@subwallet/extension-base/utils");
12
+ var _bignumber = _interopRequireDefault(require("bignumber.js"));
13
+ var _utils2 = require("../../chain-service/utils");
14
+ var _baseHandler = require("./base-handler");
15
+ // Copyright 2019-2022 @subwallet/extension-base
16
+ // SPDX-License-Identifier: Apache-2.0
17
+
18
+ class BittensorSwapHandler {
19
+ isReady = false;
20
+ constructor(chainService, balanceService, feeService, isTestnet) {
21
+ this.swapBaseHandler = new _baseHandler.SwapBaseHandler({
22
+ chainService,
23
+ balanceService,
24
+ feeService,
25
+ providerName: isTestnet ? 'Bittensor Testnet' : 'Bittensor',
26
+ providerSlug: isTestnet ? _types.SwapProviderId.BITTENSOR_TESTNET : _types.SwapProviderId.BITTENSOR
27
+ });
28
+ this.providerSlug = isTestnet ? _types.SwapProviderId.BITTENSOR_TESTNET : _types.SwapProviderId.BITTENSOR;
29
+ }
30
+ get chainService() {
31
+ return this.swapBaseHandler.chainService;
32
+ }
33
+ get providerInfo() {
34
+ return this.swapBaseHandler.providerInfo;
35
+ }
36
+ generateOptimalProcessV2(params) {
37
+ return this.swapBaseHandler.generateOptimalProcessV2(params, [this.getSubmitStep.bind(this)]);
38
+ }
39
+ async getSubmitStep(params) {
40
+ if (!params.selectedQuote) {
41
+ return Promise.resolve(undefined);
42
+ }
43
+ const originTokenInfo = this.chainService.getAssetBySlug(params.selectedQuote.pair.from);
44
+ const destinationTokenInfo = this.chainService.getAssetBySlug(params.selectedQuote.pair.to);
45
+ const originChain = this.chainService.getChainInfoByKey(originTokenInfo.originChain);
46
+ const destinationChain = this.chainService.getChainInfoByKey(destinationTokenInfo.originChain);
47
+ const submitStep = {
48
+ name: 'Swap',
49
+ type: _types.SwapStepType.SWAP,
50
+ // @ts-ignore
51
+ metadata: {
52
+ sendingValue: params.request.fromAmount.toString(),
53
+ expectedReceive: params.selectedQuote.toAmount,
54
+ originTokenInfo,
55
+ destinationTokenInfo,
56
+ sender: (0, _utils._reformatAddressWithChain)(params.request.address, originChain),
57
+ receiver: (0, _utils._reformatAddressWithChain)(params.request.recipient || params.request.address, destinationChain),
58
+ version: 2
59
+ }
60
+ };
61
+ return Promise.resolve([submitStep, params.selectedQuote.feeInfo]);
62
+ }
63
+ async validateSwapProcessV2(params) {
64
+ // todo: recheck address and recipient format in params
65
+ const {
66
+ process,
67
+ selectedQuote
68
+ } = params; // todo: review flow, currentStep param.
69
+
70
+ // todo: validate path with optimalProcess
71
+ // todo: review error message in case many step swap
72
+ if ((0, _bignumber.default)(selectedQuote.fromAmount).lte(0)) {
73
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')];
74
+ }
75
+ const actionList = JSON.stringify(process.path.map(step => step.action));
76
+ const swap = actionList === JSON.stringify([_types.DynamicSwapType.SWAP]);
77
+ const swapXcm = actionList === JSON.stringify([_types.DynamicSwapType.SWAP, _types.DynamicSwapType.BRIDGE]);
78
+ const xcmSwap = actionList === JSON.stringify([_types.DynamicSwapType.BRIDGE, _types.DynamicSwapType.SWAP]);
79
+ const xcmSwapXcm = actionList === JSON.stringify([_types.DynamicSwapType.BRIDGE, _types.DynamicSwapType.SWAP, _types.DynamicSwapType.BRIDGE]);
80
+ const swapIndex = params.process.steps.findIndex(step => step.type === _types.SwapStepType.SWAP); // todo
81
+
82
+ if (swapIndex <= -1) {
83
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
84
+ }
85
+ if (swap) {
86
+ return this.swapBaseHandler.validateSwapOnlyProcess(params, swapIndex); // todo: create interface for input request
87
+ }
88
+ if (swapXcm) {
89
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
90
+ }
91
+ if (xcmSwap) {
92
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
93
+ }
94
+ if (xcmSwapXcm) {
95
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
96
+ }
97
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
98
+ }
99
+ async handleSwapProcess(params) {
100
+ const {
101
+ currentStep,
102
+ process
103
+ } = params;
104
+ const type = process.steps[currentStep].type;
105
+ switch (type) {
106
+ case _types.CommonStepType.DEFAULT:
107
+ return Promise.reject(new _TransactionError.TransactionError(_types.BasicTxErrorType.UNSUPPORTED));
108
+ case _types.SwapStepType.SWAP:
109
+ return this.handleSubmitStep(params);
110
+ default:
111
+ return this.handleSubmitStep(params);
112
+ }
113
+ }
114
+ async handleSubmitStep(params) {
115
+ var _fromAsset$metadata, _toAsset$metadata;
116
+ const {
117
+ address,
118
+ quote
119
+ } = params;
120
+ const pair = quote.pair;
121
+ const fromAsset = this.chainService.getAssetBySlug(pair.from);
122
+ const toAsset = this.chainService.getAssetBySlug(pair.to);
123
+ const chainInfo = this.chainService.getChainInfoByKey(fromAsset.originChain);
124
+ const fromNetuid = (0, _utils2._isNativeTokenBySlug)(fromAsset.slug) ? 0 : (_fromAsset$metadata = fromAsset.metadata) === null || _fromAsset$metadata === void 0 ? void 0 : _fromAsset$metadata.netuid;
125
+ const toNetuid = (0, _utils2._isNativeTokenBySlug)(toAsset.slug) ? 0 : (_toAsset$metadata = toAsset.metadata) === null || _toAsset$metadata === void 0 ? void 0 : _toAsset$metadata.netuid;
126
+ if (fromNetuid == null || toNetuid == null || fromNetuid === toNetuid) {
127
+ return Promise.reject(new _TransactionError.TransactionError(_types.BasicTxErrorType.UNSUPPORTED));
128
+ }
129
+ const txData = {
130
+ address,
131
+ provider: this.providerInfo,
132
+ quote: params.quote,
133
+ slippage: params.slippage,
134
+ process: params.process
135
+ };
136
+ const chainApi = this.chainService.getSubstrateApi(chainInfo.slug);
137
+ const substrateApi = await chainApi.isReady;
138
+ const _stakeInfo = await substrateApi.api.call.stakeInfoRuntimeApi.getStakeInfoForColdkey(address);
139
+ const stakeInfo = _stakeInfo.toPrimitive();
140
+
141
+ // TAO/ALPHA ratio
142
+ const priceRatio = new _bignumber.default((0, _utils.toBNString)(quote.rate, (0, _utils2._getAssetDecimals)(fromAsset)));
143
+ const limitPrice = priceRatio.multipliedBy(new _bignumber.default(1).minus(params.slippage)).integerValue(_bignumber.default.ROUND_DOWN).toFixed();
144
+ const calls = this.buildSwapCalls({
145
+ stakeInfo,
146
+ fromNetuid,
147
+ toNetuid,
148
+ amount: new _bignumber.default(quote.fromAmount),
149
+ limitPrice
150
+ }, substrateApi.api);
151
+ let extrinsic;
152
+ if (calls.length === 1) {
153
+ extrinsic = calls[0];
154
+ } else {
155
+ extrinsic = substrateApi.api.tx.utility.batchAll(calls);
156
+ }
157
+ return {
158
+ txChain: fromAsset.originChain,
159
+ extrinsic,
160
+ txData,
161
+ extrinsicType: _KoniTypes.ExtrinsicType.SWAP,
162
+ chainType: _KoniTypes.ChainType.SUBSTRATE
163
+ // using staked balance so we do not need transferNativeAmount
164
+ };
165
+ }
166
+
167
+ // Sort hotkeys by stake descending
168
+ getHotkeysByNetuidDesc(stakeInfo, fromNetuid) {
169
+ return stakeInfo.filter(i => i.netuid === fromNetuid && new _bignumber.default(i.stake).gt(0)).sort((a, b) => new _bignumber.default(b.stake).minus(a.stake).toNumber());
170
+ }
171
+ buildSwapCalls(params, api) {
172
+ const {
173
+ amount,
174
+ fromNetuid,
175
+ limitPrice,
176
+ stakeInfo,
177
+ toNetuid
178
+ } = params;
179
+ const hotkeys = this.getHotkeysByNetuidDesc(stakeInfo, fromNetuid);
180
+ let remaining = amount;
181
+ const calls = [];
182
+ for (const item of hotkeys) {
183
+ if (remaining.lte(0)) {
184
+ break;
185
+ }
186
+ const stake = new _bignumber.default(item.stake);
187
+ if (stake.lte(0)) {
188
+ continue;
189
+ }
190
+ const swapAmount = _bignumber.default.minimum(stake, remaining);
191
+ calls.push(api.tx.subtensorModule.swapStakeLimit(item.hotkey, fromNetuid, toNetuid, swapAmount.toFixed(), limitPrice, false));
192
+ remaining = remaining.minus(swapAmount);
193
+ }
194
+ return calls;
195
+ }
196
+ }
197
+ exports.BittensorSwapHandler = BittensorSwapHandler;
@@ -116,7 +116,11 @@ class HydradxHandler {
116
116
  const {
117
117
  path,
118
118
  request: {
119
- fromAmount
119
+ address,
120
+ alternativeAddress,
121
+ fromAmount,
122
+ recipient,
123
+ slippage
120
124
  },
121
125
  selectedQuote
122
126
  } = params;
@@ -135,8 +139,8 @@ class HydradxHandler {
135
139
  const destinationTokenInfo = this.chainService.getAssetBySlug(swapPairInfo.to);
136
140
  const originChain = this.chainService.getChainInfoByKey(originTokenInfo.originChain);
137
141
  const destinationChain = this.chainService.getChainInfoByKey(destinationTokenInfo.originChain);
138
- const sender = (0, _utils3._reformatAddressWithChain)(params.request.address, originChain);
139
- let receiver = (0, _utils3._reformatAddressWithChain)(params.request.recipient || params.request.address, destinationChain);
142
+ const sender = (0, _utils3._reformatAddressWithChain)(address, originChain, alternativeAddress);
143
+ let receiver = (0, _utils3._reformatAddressWithChain)(recipient || address, destinationChain);
140
144
  const actionList = JSON.stringify(path.map(step => step.action));
141
145
  const xcmSwapXcm = actionList === JSON.stringify([_types.DynamicSwapType.BRIDGE, _types.DynamicSwapType.SWAP, _types.DynamicSwapType.BRIDGE]);
142
146
  const swapXcm = actionList === JSON.stringify([_types.DynamicSwapType.SWAP, _types.DynamicSwapType.BRIDGE]);
@@ -160,7 +164,7 @@ class HydradxHandler {
160
164
  slug: swapPairInfo.slug
161
165
  },
162
166
  fromAmount: bnSendingValue.toFixed(0, 1),
163
- slippage: params.request.slippage
167
+ slippage: slippage
164
168
  });
165
169
  } catch (error) {
166
170
  throw new Error(`Failed to fetch swap quote: ${error.message}`);
@@ -171,7 +175,7 @@ class HydradxHandler {
171
175
  }
172
176
  const overrideQuote = quoteAskResponse.quote;
173
177
  txHex = overrideQuote.metadata;
174
- receiver = (0, _utils3._reformatAddressWithChain)(params.request.address, destinationChain);
178
+ receiver = (0, _utils3._reformatAddressWithChain)(address, destinationChain, alternativeAddress);
175
179
  }
176
180
  if (!txHex || !(0, _util.isHex)(txHex)) {
177
181
  return Promise.resolve(undefined);