@subwallet/extension-base 1.3.76-0 → 1.3.78-0

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 +4 -1
  2. package/cjs/core/logic-validation/index.js +1 -1
  3. package/cjs/core/substrate/xcm-parser.js +17 -11
  4. package/cjs/koni/background/handlers/Extension.js +293 -71
  5. package/cjs/koni/background/handlers/State.js +20 -0
  6. package/cjs/koni/background/handlers/Tabs.js +2 -3
  7. package/cjs/packageInfo.js +1 -1
  8. package/cjs/services/balance-service/helpers/subscribe/evm.js +85 -6
  9. package/cjs/services/balance-service/helpers/subscribe/index.js +2 -1
  10. package/cjs/services/balance-service/index.js +6 -2
  11. package/cjs/services/balance-service/transfer/token.js +15 -0
  12. package/cjs/services/balance-service/transfer/xcm/bittensorBridge/index.js +27 -0
  13. package/cjs/services/balance-service/transfer/xcm/bittensorBridge/nativeTokenBridge.js +58 -0
  14. package/cjs/services/balance-service/transfer/xcm/bittensorBridge/utils.js +36 -0
  15. package/cjs/services/balance-service/transfer/xcm/index.js +61 -2
  16. package/cjs/services/balance-service/transfer/xcm/utils.js +94 -6
  17. package/cjs/services/chain-service/constants.js +4 -2
  18. package/cjs/services/chain-service/utils/patch.js +1 -1
  19. package/cjs/services/earning-service/constants/chains.js +7 -2
  20. package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +8 -5
  21. package/cjs/services/earning-service/handlers/special.js +82 -65
  22. package/cjs/services/earning-service/service.js +19 -2
  23. package/cjs/services/multisig-service/index.js +1 -1
  24. package/cjs/services/request-service/handler/SubstrateRequestHandler.js +12 -0
  25. package/cjs/services/request-service/index.js +3 -0
  26. package/cjs/services/setting-service/constants.js +2 -1
  27. package/cjs/services/storage-service/db-stores/InappNotification.js +1 -1
  28. package/cjs/services/swap-service/handler/bittensor-handler.js +197 -0
  29. package/cjs/services/swap-service/index.js +7 -0
  30. package/cjs/services/transaction-service/index.js +10 -0
  31. package/cjs/types/balance/index.js +1 -0
  32. package/cjs/types/swap/index.js +3 -1
  33. package/cjs/utils/fee/transfer.js +20 -5
  34. package/core/logic-validation/index.js +1 -1
  35. package/core/substrate/xcm-parser.d.ts +3 -0
  36. package/core/substrate/xcm-parser.js +14 -11
  37. package/koni/background/handlers/Extension.d.ts +19 -0
  38. package/koni/background/handlers/Extension.js +233 -14
  39. package/koni/background/handlers/State.d.ts +1 -0
  40. package/koni/background/handlers/State.js +20 -0
  41. package/koni/background/handlers/Tabs.js +2 -3
  42. package/package.json +26 -6
  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 +87 -1
  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 +2 -0
  65. package/services/earning-service/constants/chains.js +4 -1
  66. package/services/earning-service/handlers/liquid-staking/stella-swap.d.ts +1 -0
  67. package/services/earning-service/handlers/liquid-staking/stella-swap.js +6 -4
  68. package/services/earning-service/handlers/special.d.ts +1 -1
  69. package/services/earning-service/handlers/special.js +85 -68
  70. package/services/earning-service/service.js +21 -4
  71. package/services/inapp-notification-service/interfaces.d.ts +1 -0
  72. package/services/multisig-service/index.js +1 -1
  73. package/services/request-service/handler/SubstrateRequestHandler.d.ts +1 -0
  74. package/services/request-service/handler/SubstrateRequestHandler.js +12 -0
  75. package/services/request-service/index.d.ts +1 -0
  76. package/services/request-service/index.js +3 -0
  77. package/services/request-service/types.d.ts +1 -0
  78. package/services/setting-service/constants.js +2 -1
  79. package/services/storage-service/db-stores/InappNotification.js +1 -1
  80. package/services/swap-service/handler/bittensor-handler.d.ts +21 -0
  81. package/services/swap-service/handler/bittensor-handler.js +189 -0
  82. package/services/swap-service/index.js +7 -0
  83. package/services/transaction-service/index.d.ts +1 -1
  84. package/services/transaction-service/index.js +10 -0
  85. package/services/transaction-service/types.d.ts +4 -3
  86. package/types/balance/index.d.ts +3 -1
  87. package/types/balance/index.js +1 -0
  88. package/types/balance/transfer.d.ts +9 -0
  89. package/types/fee/base.d.ts +1 -0
  90. package/types/multisig/index.d.ts +12 -0
  91. package/types/swap/index.d.ts +3 -1
  92. package/types/swap/index.js +3 -1
  93. package/types/yield/actions/join/step.d.ts +6 -0
  94. package/types/yield/actions/join/submit.d.ts +1 -0
  95. package/utils/fee/transfer.d.ts +1 -0
  96. package/utils/fee/transfer.js +21 -6
@@ -3,7 +3,8 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports._STAKING_CHAIN_GROUP = exports.TON_CHAINS = exports.ST_LIQUID_TOKEN_ABI = exports.STAKING_IDENTITY_API_SLUG = exports.RELAY_HANDLER_DIRECT_STAKING_CHAINS = exports.MaxEraRewardPointsEras = exports.MANTA_VALIDATOR_POINTS_PER_BLOCK = exports.MANTA_MIN_DELEGATION = exports.CHANNEL_ID = void 0;
6
+ exports._STAKING_CHAIN_GROUP = exports.TON_CHAINS = exports.SUNSETTED_YIELD_POOL_SLUGS = exports.ST_LIQUID_TOKEN_ABI = exports.STAKING_IDENTITY_API_SLUG = exports.RELAY_HANDLER_DIRECT_STAKING_CHAINS = exports.MaxEraRewardPointsEras = exports.MIN_XCM_LIQUID_STAKING_DOT = exports.MANTA_VALIDATOR_POINTS_PER_BLOCK = exports.MANTA_MIN_DELEGATION = exports.CHANNEL_ID = void 0;
7
+ var _stellaSwap = require("../handlers/liquid-staking/stella-swap");
7
8
  // Copyright 2019-2022 @subwallet/extension-base
8
9
  // SPDX-License-Identifier: Apache-2.0
9
10
 
@@ -29,6 +30,8 @@ const _STAKING_CHAIN_GROUP = {
29
30
  tanssi: ['tanssi', 'dancelight']
30
31
  };
31
32
  exports._STAKING_CHAIN_GROUP = _STAKING_CHAIN_GROUP;
33
+ const SUNSETTED_YIELD_POOL_SLUGS = [_stellaSwap.STELLA_SWAP_LIQUID_STAKING_SLUG, 'MANTA___native_staking___manta_network'];
34
+ exports.SUNSETTED_YIELD_POOL_SLUGS = SUNSETTED_YIELD_POOL_SLUGS;
32
35
  const RELAY_HANDLER_DIRECT_STAKING_CHAINS = [..._STAKING_CHAIN_GROUP.relay, ..._STAKING_CHAIN_GROUP.assetHub];
33
36
  exports.RELAY_HANDLER_DIRECT_STAKING_CHAINS = RELAY_HANDLER_DIRECT_STAKING_CHAINS;
34
37
  const TON_CHAINS = ['ton', 'ton_testnet'];
@@ -49,4 +52,6 @@ const STAKING_IDENTITY_API_SLUG = {
49
52
  statemine: 'peopleKusama',
50
53
  statemint: 'polkadot_people'
51
54
  };
52
- exports.STAKING_IDENTITY_API_SLUG = STAKING_IDENTITY_API_SLUG;
55
+ exports.STAKING_IDENTITY_API_SLUG = STAKING_IDENTITY_API_SLUG;
56
+ const MIN_XCM_LIQUID_STAKING_DOT = '15000000000';
57
+ exports.MIN_XCM_LIQUID_STAKING_DOT = MIN_XCM_LIQUID_STAKING_DOT;
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.getStellaswapLiquidStakingContract = exports.default = void 0;
7
+ exports.getStellaswapLiquidStakingContract = exports.default = exports.STELLA_SWAP_LIQUID_STAKING_SLUG = void 0;
8
8
  var _TransactionError = require("@subwallet/extension-base/background/errors/TransactionError");
9
9
  var _KoniTypes = require("@subwallet/extension-base/background/KoniTypes");
10
10
  var _web = require("@subwallet/extension-base/koni/api/contract-handler/evm/web3");
@@ -28,6 +28,8 @@ exports.getStellaswapLiquidStakingContract = getStellaswapLiquidStakingContract;
28
28
  const APR_STATS_URL = 'https://stdot-apr.stellaswap.com/';
29
29
  const SUBWALLET_REFERRAL = '0x7e6815f45E624768548d085231f2d453f16FD7DD';
30
30
  const TOP_HOLDER = '0x4300e09284e3bB4d9044DdAB31EfAF5f3301DABa';
31
+ const STELLA_SWAP_LIQUID_STAKING_SLUG = 'xcDOT___liquid_staking___stellaswap';
32
+ exports.STELLA_SWAP_LIQUID_STAKING_SLUG = STELLA_SWAP_LIQUID_STAKING_SLUG;
31
33
  class StellaSwapLiquidStakingPoolHandler extends _base.default {
32
34
  inputAsset = 'moonbeam-LOCAL-xcDOT';
33
35
  altInputAsset = '';
@@ -37,8 +39,8 @@ class StellaSwapLiquidStakingPoolHandler extends _base.default {
37
39
  transactionChainType = _KoniTypes.ChainType.EVM;
38
40
  rateDecimals = 10; // Derivative asset decimals
39
41
  availableMethod = {
40
- join: true,
41
- defaultUnstake: true,
42
+ join: false,
43
+ defaultUnstake: false,
42
44
  fastUnstake: false,
43
45
  cancelUnstake: false,
44
46
  withdraw: true,
@@ -47,7 +49,7 @@ class StellaSwapLiquidStakingPoolHandler extends _base.default {
47
49
  };
48
50
  constructor(state, chain) {
49
51
  super(state, chain);
50
- this.slug = 'xcDOT___liquid_staking___stellaswap';
52
+ this.slug = STELLA_SWAP_LIQUID_STAKING_SLUG;
51
53
  this.name = 'StellaSwap Liquid Staking';
52
54
  this._logo = 'stellaswap';
53
55
  this.shortName = 'StellaSwap';
@@ -170,7 +172,8 @@ class StellaSwapLiquidStakingPoolHandler extends _base.default {
170
172
  unstakeBalance: unlockBalance.toString(),
171
173
  isBondedBefore: totalBalance.gt(_util.BN_ZERO),
172
174
  derivativeToken: derivativeTokenSlug,
173
- status: activeBalance.gt(_util.BN_ZERO) ? _types.EarningStatus.EARNING_REWARD : _types.EarningStatus.NOT_EARNING,
175
+ // StellaSwap announced all stDOT positions are auto-unstaking, so rewards are no longer earned.
176
+ status: _types.EarningStatus.NOT_EARNING,
174
177
  nominations: [],
175
178
  unstakings
176
179
  };
@@ -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,51 @@ 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
+ originTokenInfo: altInputTokenInfo,
259
+ destinationTokenInfo: inputTokenInfo
260
+ };
256
261
  const step = {
257
- metadata: {
258
- sendingValue: bnTransferAmount.toString(),
259
- originTokenInfo: altInputTokenInfo,
260
- destinationTokenInfo: inputTokenInfo
261
- },
262
+ metadata: metadata,
262
263
  name: `Transfer ${symbol} from ${networkName}`,
263
264
  type: _types.YieldStepType.XCM
264
265
  };
@@ -301,31 +302,35 @@ class BaseSpecialStakingPoolHandler extends _base.default {
301
302
  return Promise.resolve([new _TransactionError.TransactionError(_types.BasicTxErrorType.UNSUPPORTED)]);
302
303
  }
303
304
  async validateXcmStep(params, path, bnInputTokenBalance) {
305
+ // todo: BN -> BigN or BigInt
304
306
  const processValidation = {
305
307
  ok: true,
306
308
  status: _types.YieldValidationStatus.OK
307
309
  };
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)) {
310
+ const metadata = path.steps[1].metadata;
311
+ const {
312
+ destinationTokenInfo,
313
+ originTokenInfo,
314
+ sendingValue
315
+ } = metadata;
316
+ const originChainInfo = this.state.getChainInfo(originTokenInfo.originChain);
317
+ const originTokenBalance = await this.state.balanceService.getTransferableBalance(params.address, originTokenInfo.originChain, originTokenInfo.slug);
318
+ const bnOriginTokenBalance = new _util.BN(originTokenBalance.value || '0');
319
+ const bnAdjustOriginFee = new _util.BN(path.totalFee[1].amount || '0').mul(new _util.BN(_constants.XCM_MIN_AMOUNT_RATIO));
320
+ const bnSendingValue = new _util.BN(sendingValue);
321
+ if (!bnOriginTokenBalance.sub(bnSendingValue).sub(bnAdjustOriginFee).gt(_util.BN_ZERO)) {
317
322
  processValidation.failedStep = path.steps[1];
318
323
  processValidation.ok = false;
319
324
  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);
325
+ const bnMaxXCM = new _util.BN(originTokenBalance.value).sub(bnAdjustOriginFee);
326
+ const destinationTokenDecimal = (0, _utils3._getAssetDecimals)(destinationTokenInfo);
327
+ const maxBn = bnInputTokenBalance.add(bnOriginTokenBalance.sub(bnAdjustOriginFee));
328
+ const maxValue = (0, _utils4.formatNumber)(maxBn.toString(), destinationTokenInfo.decimals || 0);
329
+ const maxXCMValue = (0, _utils4.formatNumber)(bnMaxXCM.toString(), destinationTokenDecimal);
330
+ const symbol = (0, _utils3._getAssetSymbol)(originTokenInfo);
326
331
  const inputNetworkName = this.chainInfo.name;
327
- const altNetworkName = (0, _utils3._getAssetName)(altInputTokenInfo);
328
- const currentValue = (0, _utils4.formatNumber)(bnInputTokenBalance.toString(), inputTokenDecimal);
332
+ const altNetworkName = (0, _utils3._getChainName)(originChainInfo);
333
+ const currentValue = (0, _utils4.formatNumber)(bnInputTokenBalance.toString(), destinationTokenDecimal);
329
334
  processValidation.message = (0, _i18next.t)('bg.EARNING.services.service.earning.specialHandler.maximumInputExceeded', {
330
335
  replace: {
331
336
  symbol,
@@ -338,6 +343,24 @@ class BaseSpecialStakingPoolHandler extends _base.default {
338
343
  });
339
344
  return [new _TransactionError.TransactionError(_types.YieldValidationStatus.NOT_ENOUGH_BALANCE, processValidation.message, processValidation)];
340
345
  }
346
+ const id = (0, _getId.getId)();
347
+ const feeInfo = await this.state.feeService.subscribeChainFee(id, originChainInfo.slug, 'substrate');
348
+ const substrateApi = this.state.getSubstrateApi(originChainInfo.slug);
349
+ const xcmRequest = {
350
+ destinationTokenInfo: destinationTokenInfo,
351
+ originTokenInfo: originTokenInfo,
352
+ recipient: params.address,
353
+ sendingValue,
354
+ substrateApi,
355
+ sender: params.address,
356
+ originChain: originChainInfo,
357
+ destinationChain: this.chainInfo,
358
+ feeInfo
359
+ };
360
+ const isDryRunSuccess = await (0, _xcm.dryRunXcmExtrinsicV2)(xcmRequest);
361
+ if (!isDryRunSuccess) {
362
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.UNABLE_TO_SEND, 'Unable to perform transaction. Select another token or destination chain and try again')];
363
+ }
341
364
  return [];
342
365
  }
343
366
  async validateJoinStep(id, params, path, bnInputTokenBalance, isXcmOk) {
@@ -357,7 +380,7 @@ class BaseSpecialStakingPoolHandler extends _base.default {
357
380
  const feeTokenInfo = this.state.getAssetBySlug(feeTokenSlug);
358
381
  const inputTokenInfo = this.state.getAssetBySlug(this.inputAsset);
359
382
  const defaultFeeTokenSlug = this.feeAssets[0];
360
- const bnAmount = new _util.BN(params.amount);
383
+ const bnStakeAmount = new _util.BN(params.amount);
361
384
  if (this.feeAssets.length === 1 && feeTokenSlug === defaultFeeTokenSlug) {
362
385
  var _path$totalFee$id;
363
386
  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 +394,13 @@ class BaseSpecialStakingPoolHandler extends _base.default {
371
394
  return [new _TransactionError.TransactionError(_types.YieldValidationStatus.NOT_ENOUGH_FEE, processValidation.message, processValidation)];
372
395
  }
373
396
  }
374
- if (!bnAmount.gte(new _util.BN(poolInfo.statistic.earningThreshold.join || '0'))) {
397
+ if (!bnStakeAmount.gte(new _util.BN(poolInfo.statistic.earningThreshold.join || '0'))) {
375
398
  processValidation.failedStep = path.steps[id];
376
399
  processValidation.ok = false;
377
400
  processValidation.status = _types.YieldValidationStatus.NOT_ENOUGH_MIN_JOIN_POOL;
378
401
  return [new _TransactionError.TransactionError(_types.YieldValidationStatus.NOT_ENOUGH_MIN_JOIN_POOL, processValidation.message, processValidation)];
379
402
  }
380
- if (!isXcmOk && bnAmount.gt(bnInputTokenBalance)) {
403
+ if (!isXcmOk && bnStakeAmount.gt(bnInputTokenBalance)) {
381
404
  processValidation.failedStep = path.steps[id];
382
405
  processValidation.ok = false;
383
406
  processValidation.status = _types.YieldValidationStatus.NOT_ENOUGH_BALANCE;
@@ -401,8 +424,8 @@ class BaseSpecialStakingPoolHandler extends _base.default {
401
424
  const balanceService = this.state.balanceService;
402
425
  const inputTokenBalance = await balanceService.getTransferableBalance(params.address, inputTokenInfo.originChain, inputTokenSlug);
403
426
  const bnInputTokenBalance = new _util.BN(inputTokenBalance.value || '0');
404
- const bnAmount = new _util.BN(params.amount);
405
- if (bnAmount.lte(_util.BN_ZERO)) {
427
+ const bnStakeAmount = new _util.BN(params.amount);
428
+ if (bnStakeAmount.lte(_util.BN_ZERO)) {
406
429
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')];
407
430
  }
408
431
  let isXcmOk = false;
@@ -436,31 +459,25 @@ class BaseSpecialStakingPoolHandler extends _base.default {
436
459
  async handleTokenApproveStep(data, path) {
437
460
  return Promise.reject(new _TransactionError.TransactionError(_types.BasicTxErrorType.UNSUPPORTED));
438
461
  }
439
- async handleXcmStep(data, path, xcmFee) {
462
+ async handleXcmStep(data, path) {
463
+ const metadata = path.steps[1].metadata;
464
+ const xcmStepFee = path.totalFee[1].amount;
465
+ const address = data.address;
440
466
  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);
467
+ destinationTokenInfo,
468
+ originTokenInfo,
469
+ sendingValue
470
+ } = metadata;
471
+ const originChainInfo = this.state.getChainInfo(originTokenInfo.originChain);
448
472
  const originTokenSlug = (0, _utils3._getChainNativeTokenSlug)(originChainInfo);
449
- const originTokenInfo = this.state.getAssetBySlug(originTokenSlug);
450
- const destinationTokenInfo = this.state.getAssetBySlug(destinationTokenSlug);
451
473
  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
474
  const id = (0, _getId.getId)();
458
475
  const feeInfo = await this.state.feeService.subscribeChainFee(id, originChainInfo.slug, 'substrate');
459
476
  const xcmRequest = {
460
477
  destinationTokenInfo,
461
478
  originTokenInfo,
462
479
  recipient: address,
463
- sendingValue: bnTotalAmount.toString(),
480
+ sendingValue,
464
481
  substrateApi,
465
482
  sender: address,
466
483
  originChain: originChainInfo,
@@ -476,7 +493,7 @@ class BaseSpecialStakingPoolHandler extends _base.default {
476
493
  destinationNetworkKey: destinationTokenInfo.originChain,
477
494
  from: address,
478
495
  to: address,
479
- value: bnTotalAmount.toString(),
496
+ value: sendingValue,
480
497
  tokenSlug: originTokenSlug,
481
498
  showExtraWarning: true
482
499
  };
@@ -485,8 +502,9 @@ class BaseSpecialStakingPoolHandler extends _base.default {
485
502
  extrinsicType: _KoniTypes.ExtrinsicType.TRANSFER_XCM,
486
503
  extrinsic,
487
504
  txData: xcmData,
488
- transferNativeAmount: bnTotalAmount.toString(),
489
- chainType: _KoniTypes.ChainType.SUBSTRATE
505
+ transferNativeAmount: sendingValue,
506
+ chainType: _KoniTypes.ChainType.SUBSTRATE,
507
+ xcmStepFee
490
508
  };
491
509
  }
492
510
  handleYieldJoin(data, path, currentStep) {
@@ -498,8 +516,7 @@ class BaseSpecialStakingPoolHandler extends _base.default {
498
516
  return this.handleTokenApproveStep(data, path);
499
517
  case _types.YieldStepType.XCM:
500
518
  {
501
- const xcmFee = path.totalFee[currentStep].amount || '0';
502
- return this.handleXcmStep(data, path, xcmFee);
519
+ return this.handleXcmStep(data, path);
503
520
  }
504
521
  default:
505
522
  return this.handleSubmitStep(data, path);
@@ -441,6 +441,14 @@ class EarningService {
441
441
  }
442
442
  const updatedItem = structuredClone(item);
443
443
  updatedItem.metadata.availableMethod = handler.availableMethod;
444
+
445
+ // Disable staking for sunsetted pools
446
+ if (_constants2.SUNSETTED_YIELD_POOL_SLUGS.includes(item.slug)) {
447
+ updatedItem.metadata.availableMethod = {
448
+ ...updatedItem.metadata.availableMethod,
449
+ join: false
450
+ };
451
+ }
444
452
  this.updateYieldPoolInfo(updatedItem);
445
453
  });
446
454
  return onlineData;
@@ -535,7 +543,11 @@ class EarningService {
535
543
  const yieldPositionInfo = this.yieldPositionSubject.getValue();
536
544
  existedYieldPosition.forEach(item => {
537
545
  if (!this.inactivePoolSlug.has(item.slug)) {
538
- yieldPositionInfo[this._getYieldPositionKey(item.slug, item.address)] = item;
546
+ const normalizedItem = _constants2.SUNSETTED_YIELD_POOL_SLUGS.includes(item.slug) ? {
547
+ ...item,
548
+ status: _types2.EarningStatus.NOT_EARNING
549
+ } : item;
550
+ yieldPositionInfo[this._getYieldPositionKey(item.slug, item.address)] = normalizedItem;
539
551
  }
540
552
  });
541
553
  this.yieldPositionSubject.next(yieldPositionInfo);
@@ -558,7 +570,11 @@ class EarningService {
558
570
  return `${slug}---${address}`;
559
571
  }
560
572
  updateYieldPosition(data) {
561
- this.yieldPositionPersistQueue.push(data);
573
+ const normalizedData = _constants2.SUNSETTED_YIELD_POOL_SLUGS.includes(data.slug) ? {
574
+ ...data,
575
+ status: _types2.EarningStatus.NOT_EARNING
576
+ } : data;
577
+ this.yieldPositionPersistQueue.push(normalizedData);
562
578
  (0, _utils2.addLazy)('persistYieldPositionInfo', () => {
563
579
  const yieldPositionInfo = this.yieldPositionSubject.getValue();
564
580
  const queue = [...this.yieldPositionPersistQueue];
@@ -867,6 +883,7 @@ class EarningService {
867
883
  } = params;
868
884
  const handler = this.getPoolHandler(slug);
869
885
  if (handler) {
886
+ console.log('all step', await handler.generateOptimalPath(params));
870
887
  return handler.generateOptimalPath(params);
871
888
  } else {
872
889
  throw new _TransactionError.TransactionError(_types2.BasicTxErrorType.INTERNAL_ERROR);
@@ -212,7 +212,7 @@ class MultisigService {
212
212
  */
213
213
  handleEvents(events, eventTypes) {
214
214
  let needReload = false;
215
- if (eventTypes.includes('account.add') || eventTypes.includes('account.remove')) {
215
+ if (eventTypes.includes('account.add') || eventTypes.includes('account.remove') || eventTypes.includes('account.updateCurrent')) {
216
216
  needReload = true;
217
217
  }
218
218
  if (eventTypes.includes('chain.updateState') || eventTypes.includes('transaction.done')) {
@@ -44,6 +44,18 @@ class SubstrateRequestHandler {
44
44
  };
45
45
  });
46
46
  }
47
+ updateSignRequest(id, request, signerAddress) {
48
+ const current = this.getSignRequest(id);
49
+ if (!current) {
50
+ throw new _TransactionError.TransactionError(_types.BasicTxErrorType.INVALID_PARAMS, 'Sign request not found');
51
+ }
52
+ this.#substrateRequests[id] = {
53
+ ...current,
54
+ request,
55
+ signerAddress: signerAddress || current.signerAddress
56
+ };
57
+ this.updateIconSign();
58
+ }
47
59
  updateIconSign(shouldClose) {
48
60
  this.signSubject.next(this.allSubstrateRequests);
49
61
  this.#requestService.updateIconV2(shouldClose);
@@ -175,6 +175,9 @@ class RequestService {
175
175
  getSignRequest(id) {
176
176
  return this.#substrateRequestHandler.getSignRequest(id);
177
177
  }
178
+ updateSignRequest(id, request, signerAddress) {
179
+ this.#substrateRequestHandler.updateSignRequest(id, request, signerAddress);
180
+ }
178
181
  async signInternalTransaction(id, address, url, payload, onSign, isWrappedTx) {
179
182
  if (isWrappedTx === _types.SubstrateTransactionWrappingStatus.WRAP_RESULT) {
180
183
  return this.#substrateRequestHandler.signWrappedTransaction(id, address, url, payload, onSign);
@@ -41,7 +41,8 @@ const DEFAULT_NOTIFICATION_SETUP = {
41
41
  earningClaim: true,
42
42
  earningWithdraw: true,
43
43
  availBridgeClaim: true,
44
- polygonBridgeClaim: true
44
+ polygonBridgeClaim: true,
45
+ pendingMultisigApprovals: true
45
46
  // isHideWithdraw: false, // todo: just for test, remove later
46
47
  // isHideMarketing: false,
47
48
  // isHideAnnouncement: false
@@ -89,7 +89,7 @@ class InappNotificationStore extends _BaseStore.default {
89
89
  isRead: true
90
90
  });
91
91
  }
92
- return this.table.where('proxyId').equalsIgnoreCase(proxyId).modify({
92
+ return this.table.where('proxyId').equalsIgnoreCase(proxyId).filter(notification => !excludeNotificationIds.includes(notification.id)).modify({
93
93
  isRead: true
94
94
  });
95
95
  }
@@ -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;