@subwallet/extension-base 1.3.29-1 → 1.3.31-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 (142) hide show
  1. package/background/KoniTypes.d.ts +16 -4
  2. package/background/errors/SwapError.js +1 -1
  3. package/cjs/background/errors/SwapError.js +1 -1
  4. package/cjs/constants/blocked-actions.js +2 -2
  5. package/cjs/constants/paraspell-chain-map.js +13 -0
  6. package/cjs/constants/remind-notification-time.js +3 -3
  7. package/cjs/core/logic-validation/swap.js +63 -4
  8. package/cjs/core/logic-validation/transfer.js +13 -1
  9. package/cjs/core/substrate/xcm-parser.js +5 -1
  10. package/cjs/core/utils.js +36 -15
  11. package/cjs/koni/background/handlers/Extension.js +141 -172
  12. package/cjs/koni/background/handlers/State.js +8 -1
  13. package/cjs/packageInfo.js +1 -1
  14. package/cjs/services/balance-service/helpers/process.js +27 -0
  15. package/cjs/services/balance-service/index.js +9 -0
  16. package/cjs/services/balance-service/transfer/xcm/acrossBridge/index.js +229 -0
  17. package/cjs/services/balance-service/transfer/xcm/availBridge.js +6 -6
  18. package/cjs/services/balance-service/transfer/xcm/index.js +96 -7
  19. package/cjs/services/balance-service/transfer/xcm/utils.js +213 -0
  20. package/cjs/services/chain-service/constants.js +2 -4
  21. package/cjs/services/chain-service/index.js +71 -17
  22. package/cjs/services/chain-service/utils/patch.js +1 -1
  23. package/cjs/services/earning-service/handlers/base.js +6 -3
  24. package/cjs/services/earning-service/handlers/native-staking/base.js +4 -1
  25. package/cjs/services/earning-service/handlers/native-staking/dtao.js +68 -50
  26. package/cjs/services/earning-service/handlers/native-staking/tao.js +12 -2
  27. package/cjs/services/earning-service/handlers/special.js +18 -9
  28. package/cjs/services/earning-service/service.js +2 -1
  29. package/cjs/services/fee-service/utils/index.js +16 -4
  30. package/cjs/services/inapp-notification-service/index.js +19 -13
  31. package/cjs/services/keyring-service/context/handlers/Ledger.js +1 -1
  32. package/cjs/services/keyring-service/context/state.js +3 -0
  33. package/cjs/services/migration-service/scripts/DisableZeroBalanceTokens.js +60 -0
  34. package/cjs/services/migration-service/scripts/EnableChain.js +1 -1
  35. package/cjs/services/migration-service/scripts/index.js +3 -2
  36. package/cjs/services/swap-service/handler/asset-hub/handler.js +61 -314
  37. package/cjs/services/swap-service/handler/base-handler.js +406 -231
  38. package/cjs/services/swap-service/handler/chainflip-handler.js +18 -40
  39. package/cjs/services/swap-service/handler/hydradx-handler.js +77 -269
  40. package/cjs/services/swap-service/handler/simpleswap-handler.js +27 -48
  41. package/cjs/services/swap-service/handler/uniswap-handler.js +33 -54
  42. package/cjs/services/swap-service/index.js +154 -143
  43. package/cjs/services/swap-service/utils.js +107 -17
  44. package/cjs/services/transaction-service/index.js +1 -1
  45. package/cjs/services/transaction-service/utils.js +38 -14
  46. package/cjs/types/swap/index.js +13 -1
  47. package/cjs/utils/fee/transfer.js +52 -28
  48. package/cjs/utils/staticData/index.js +7 -2
  49. package/cjs/utils/swap.js +5 -1
  50. package/constants/blocked-actions.d.ts +1 -1
  51. package/constants/blocked-actions.js +1 -1
  52. package/constants/paraspell-chain-map.d.ts +1 -0
  53. package/constants/paraspell-chain-map.js +7 -0
  54. package/constants/remind-notification-time.d.ts +1 -1
  55. package/constants/remind-notification-time.js +1 -1
  56. package/core/logic-validation/swap.d.ts +15 -0
  57. package/core/logic-validation/swap.js +60 -4
  58. package/core/logic-validation/transfer.d.ts +1 -0
  59. package/core/logic-validation/transfer.js +12 -1
  60. package/core/substrate/xcm-parser.d.ts +1 -0
  61. package/core/substrate/xcm-parser.js +4 -1
  62. package/core/utils.d.ts +2 -2
  63. package/core/utils.js +36 -15
  64. package/koni/background/handlers/Extension.d.ts +1 -1
  65. package/koni/background/handlers/Extension.js +66 -98
  66. package/koni/background/handlers/State.d.ts +1 -0
  67. package/koni/background/handlers/State.js +7 -1
  68. package/package.json +23 -13
  69. package/packageInfo.js +1 -1
  70. package/services/balance-service/helpers/process.d.ts +2 -1
  71. package/services/balance-service/helpers/process.js +26 -0
  72. package/services/balance-service/index.js +11 -2
  73. package/services/balance-service/transfer/xcm/acrossBridge/index.d.ts +15 -0
  74. package/services/balance-service/transfer/xcm/acrossBridge/index.js +216 -0
  75. package/services/balance-service/transfer/xcm/availBridge.js +6 -6
  76. package/services/balance-service/transfer/xcm/index.d.ts +5 -1
  77. package/services/balance-service/transfer/xcm/index.js +85 -1
  78. package/services/balance-service/transfer/xcm/utils.d.ts +11 -0
  79. package/services/balance-service/transfer/xcm/utils.js +208 -0
  80. package/services/base/types.d.ts +0 -4
  81. package/services/chain-service/constants.d.ts +0 -1
  82. package/services/chain-service/constants.js +1 -2
  83. package/services/chain-service/index.d.ts +9 -2
  84. package/services/chain-service/index.js +72 -18
  85. package/services/chain-service/utils/patch.js +1 -1
  86. package/services/earning-service/handlers/base.d.ts +4 -3
  87. package/services/earning-service/handlers/base.js +6 -4
  88. package/services/earning-service/handlers/native-staking/base.js +4 -1
  89. package/services/earning-service/handlers/native-staking/dtao.d.ts +9 -6
  90. package/services/earning-service/handlers/native-staking/dtao.js +69 -48
  91. package/services/earning-service/handlers/native-staking/tao.js +12 -2
  92. package/services/earning-service/handlers/special.js +19 -10
  93. package/services/earning-service/service.d.ts +2 -1
  94. package/services/earning-service/service.js +2 -1
  95. package/services/fee-service/utils/index.d.ts +1 -0
  96. package/services/fee-service/utils/index.js +14 -4
  97. package/services/inapp-notification-service/index.js +13 -7
  98. package/services/keyring-service/context/handlers/Ledger.js +1 -1
  99. package/services/keyring-service/context/state.d.ts +1 -0
  100. package/services/keyring-service/context/state.js +3 -0
  101. package/services/migration-service/scripts/DisableZeroBalanceTokens.d.ts +4 -0
  102. package/services/migration-service/scripts/DisableZeroBalanceTokens.js +51 -0
  103. package/services/migration-service/scripts/EnableChain.js +1 -1
  104. package/services/migration-service/scripts/index.js +3 -2
  105. package/services/swap-service/handler/asset-hub/handler.d.ts +2 -9
  106. package/services/swap-service/handler/asset-hub/handler.js +64 -317
  107. package/services/swap-service/handler/base-handler.d.ts +6 -9
  108. package/services/swap-service/handler/base-handler.js +405 -230
  109. package/services/swap-service/handler/chainflip-handler.d.ts +2 -4
  110. package/services/swap-service/handler/chainflip-handler.js +15 -37
  111. package/services/swap-service/handler/hydradx-handler.d.ts +3 -10
  112. package/services/swap-service/handler/hydradx-handler.js +78 -270
  113. package/services/swap-service/handler/simpleswap-handler.d.ts +2 -4
  114. package/services/swap-service/handler/simpleswap-handler.js +24 -45
  115. package/services/swap-service/handler/uniswap-handler.d.ts +4 -6
  116. package/services/swap-service/handler/uniswap-handler.js +25 -46
  117. package/services/swap-service/index.d.ts +8 -14
  118. package/services/swap-service/index.js +141 -129
  119. package/services/swap-service/utils.d.ts +11 -3
  120. package/services/swap-service/utils.js +96 -15
  121. package/services/transaction-service/index.js +2 -2
  122. package/services/transaction-service/types.d.ts +3 -2
  123. package/services/transaction-service/utils.d.ts +1 -0
  124. package/services/transaction-service/utils.js +38 -15
  125. package/types/balance/transfer.d.ts +1 -0
  126. package/types/service-base.d.ts +2 -3
  127. package/types/swap/index.d.ts +25 -9
  128. package/types/swap/index.js +10 -0
  129. package/types/transaction/process.d.ts +19 -0
  130. package/types/transaction/request.d.ts +7 -0
  131. package/types/yield/actions/join/submit.d.ts +4 -1
  132. package/types/yield/actions/others.d.ts +2 -0
  133. package/utils/fee/transfer.d.ts +1 -0
  134. package/utils/fee/transfer.js +54 -30
  135. package/utils/staticData/index.d.ts +4 -1
  136. package/utils/staticData/index.js +5 -1
  137. package/utils/staticData/paraSpellChainMap.json +1 -0
  138. package/utils/swap.d.ts +3 -0
  139. package/utils/swap.js +3 -0
  140. package/cjs/services/swap-service/interface.js +0 -14
  141. package/services/swap-service/interface.d.ts +0 -9
  142. package/services/swap-service/interface.js +0 -8
@@ -8,16 +8,17 @@ exports.SwapBaseHandler = 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 _logicValidation = require("@subwallet/extension-base/core/logic-validation");
11
- var _swap = require("@subwallet/extension-base/core/logic-validation/swap");
12
11
  var _systemPallet = require("@subwallet/extension-base/core/substrate/system-pallet");
13
12
  var _xcmParser = require("@subwallet/extension-base/core/substrate/xcm-parser");
14
13
  var _utils = require("@subwallet/extension-base/core/utils");
14
+ var _xcm = require("@subwallet/extension-base/services/balance-service/transfer/xcm");
15
15
  var _utils2 = require("@subwallet/extension-base/services/chain-service/utils");
16
16
  var _utils3 = require("@subwallet/extension-base/services/swap-service/utils");
17
17
  var _types = require("@subwallet/extension-base/types");
18
18
  var _serviceBase = require("@subwallet/extension-base/types/service-base");
19
- var _swap2 = require("@subwallet/extension-base/types/swap");
19
+ var _swap = require("@subwallet/extension-base/types/swap");
20
20
  var _utils4 = require("@subwallet/extension-base/utils");
21
+ var _getId = require("@subwallet/extension-base/utils/getId");
21
22
  var _bignumber = _interopRequireDefault(require("bignumber.js"));
22
23
  var _i18next = require("i18next");
23
24
  var _utilCrypto = require("@polkadot/util-crypto");
@@ -39,30 +40,6 @@ class SwapBaseHandler {
39
40
  this.balanceService = balanceService;
40
41
  this.feeService = feeService;
41
42
  }
42
-
43
- // public abstract getSwapQuote(request: SwapRequest): Promise<SwapQuote | SwapError>;
44
- async generateOptimalProcess(params, genStepFuncList) {
45
- const result = {
46
- totalFee: [_serviceBase.MOCK_STEP_FEE],
47
- steps: [_serviceBase.DEFAULT_FIRST_STEP],
48
- path: []
49
- };
50
- try {
51
- for (const genStepFunc of genStepFuncList) {
52
- const step = await genStepFunc(params);
53
- if (step) {
54
- result.steps.push({
55
- id: result.steps.length,
56
- ...step[0]
57
- });
58
- result.totalFee.push(step[1]);
59
- }
60
- }
61
- return result;
62
- } catch (e) {
63
- return result;
64
- }
65
- }
66
43
  async generateOptimalProcessV2(params, genStepFuncList) {
67
44
  const result = {
68
45
  totalFee: [_serviceBase.MOCK_STEP_FEE],
@@ -70,8 +47,8 @@ class SwapBaseHandler {
70
47
  path: params.path
71
48
  };
72
49
  try {
73
- for (const genStepFunc of genStepFuncList) {
74
- const step = await genStepFunc(params);
50
+ for (const [i, genStepFunc] of genStepFuncList.entries()) {
51
+ const step = await genStepFunc(params, i);
75
52
  if (step) {
76
53
  result.steps.push({
77
54
  id: result.steps.length,
@@ -85,158 +62,180 @@ class SwapBaseHandler {
85
62
  return result;
86
63
  }
87
64
  }
88
- async validateXcmStep(params, stepIndex) {
89
- const bnAmount = new _bignumber.default(params.selectedQuote.fromAmount);
90
- const swapPair = params.selectedQuote.pair;
91
- const alternativeAssetSlug = (0, _utils3.getSwapAlternativeAsset)(swapPair);
92
- if (!alternativeAssetSlug) {
93
- return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
65
+ async getBridgeStep(params, stepIndex) {
66
+ // only xcm on substrate for now
67
+ const {
68
+ path,
69
+ request: {
70
+ address,
71
+ fromAmount,
72
+ recipient
73
+ },
74
+ selectedQuote
75
+ } = params;
76
+ if (stepIndex < 0 || stepIndex > params.path.length - 1) {
77
+ return undefined;
78
+ }
79
+ const bridgePairInfo = path[stepIndex];
80
+ if (bridgePairInfo.action !== _swap.DynamicSwapType.BRIDGE) {
81
+ return undefined;
82
+ }
83
+ if (!bridgePairInfo || !selectedQuote) {
84
+ return undefined;
85
+ }
86
+ const fromTokenInfo = this.chainService.getAssetBySlug(bridgePairInfo.pair.from);
87
+ const toTokenInfo = this.chainService.getAssetBySlug(bridgePairInfo.pair.to);
88
+ const fromChainInfo = this.chainService.getChainInfoByKey(fromTokenInfo.originChain);
89
+ const toChainInfo = this.chainService.getChainInfoByKey(toTokenInfo.originChain);
90
+ if (!fromChainInfo || !toChainInfo || !fromChainInfo || !toChainInfo) {
91
+ throw Error('Token or chain not found');
92
+ }
93
+ let recipientAddress;
94
+ const senderAddress = (0, _utils4._reformatAddressWithChain)(address, fromChainInfo);
95
+ if (stepIndex === 0) {
96
+ recipientAddress = (0, _utils4._reformatAddressWithChain)(address, toChainInfo);
97
+ } else {
98
+ // bridge after swap
99
+ recipientAddress = (0, _utils4._reformatAddressWithChain)(recipient || address, toChainInfo);
100
+ }
101
+ if (!(0, _xcmParser._isXcmWithinSameConsensus)(fromChainInfo, toChainInfo) || (0, _xcmParser._isSnowBridgeXcm)(fromChainInfo, toChainInfo) || (0, _xcmParser._isAcrossBridgeXcm)(fromChainInfo, toChainInfo)) {
102
+ return undefined;
94
103
  }
95
- const alternativeAsset = this.chainService.getAssetBySlug(alternativeAssetSlug);
96
- const fromAsset = this.chainService.getAssetBySlug(swapPair.from);
97
- const [alternativeAssetBalance, fromAssetBalance] = await Promise.all([this.balanceService.getTransferableBalance(params.address, alternativeAsset.originChain, alternativeAssetSlug), this.balanceService.getTransferableBalance(params.address, fromAsset.originChain, fromAsset.slug)]);
98
- const bnAlternativeAssetBalance = new _bignumber.default(alternativeAssetBalance.value);
99
- const bnFromAssetBalance = new _bignumber.default(fromAssetBalance.value);
100
- const xcmFeeComponent = params.process.totalFee[stepIndex].feeComponent[0]; // todo: can do better than indexing
101
- const xcmFee = new _bignumber.default(xcmFeeComponent.amount || '0');
102
- let xcmAmount = bnAmount.minus(bnFromAssetBalance);
103
- let editedXcmFee = new _bignumber.default(0);
104
- if ((0, _utils2._isNativeToken)(alternativeAsset)) {
105
- xcmAmount = xcmAmount.plus(xcmFee);
106
- editedXcmFee = xcmFee.times(2);
107
- }
108
- if (!bnAlternativeAssetBalance.minus((0, _utils2._isNativeToken)(alternativeAsset) ? xcmAmount.plus(xcmFee) : xcmFee).gt(0)) {
109
- const maxBn = bnFromAssetBalance.plus(new _bignumber.default(alternativeAssetBalance.value)).minus((0, _utils2._isNativeToken)(alternativeAsset) ? editedXcmFee : xcmFee);
110
- const maxValue = (0, _utils4.formatNumber)(maxBn.toString(), fromAsset.decimals || 0);
111
- const altInputTokenInfo = this.chainService.getAssetBySlug(alternativeAssetSlug);
112
- const symbol = altInputTokenInfo.symbol;
113
- const alternativeChain = this.chainService.getChainInfoByKey(altInputTokenInfo.originChain);
114
- const chain = this.chainService.getChainInfoByKey(fromAsset.originChain);
115
- const inputNetworkName = chain.name;
116
- const altNetworkName = alternativeChain.name;
117
- const currentValue = (0, _utils4.formatNumber)(bnFromAssetBalance.toString(), fromAsset.decimals || 0);
118
- const bnMaxXCM = new _bignumber.default(alternativeAssetBalance.value).minus((0, _utils2._isNativeToken)(alternativeAsset) ? editedXcmFee : xcmFee);
119
- const maxXCMValue = (0, _utils4.formatNumber)(bnMaxXCM.toString(), fromAsset.decimals || 0);
120
- if (maxBn.lte(0) || bnFromAssetBalance.lte(0) || bnMaxXCM.lte(0)) {
121
- return [new _TransactionError.TransactionError(_types.BasicTxErrorType.NOT_ENOUGH_BALANCE, (0, _i18next.t)(`Insufficient balance. Deposit ${fromAsset.symbol} and try again.`))];
104
+ try {
105
+ if (!this.chainService.getChainStateByKey(toTokenInfo.originChain).active) {
106
+ await this.chainService.enableChain(toTokenInfo.originChain);
122
107
  }
123
- return [new _TransactionError.TransactionError(_types.BasicTxErrorType.NOT_ENOUGH_BALANCE, (0, _i18next.t)('You can only enter a maximum of {{maxValue}} {{symbol}}, which is {{currentValue}} {{symbol}} ({{inputNetworkName}}) and {{maxXCMValue}} {{symbol}} ({{altNetworkName}}). Lower your amount and try again.', {
124
- replace: {
125
- symbol,
126
- maxValue,
127
- inputNetworkName,
128
- altNetworkName,
129
- currentValue,
130
- maxXCMValue
131
- }
132
- }))];
133
- }
134
- return [];
135
- }
136
- async validateXcmStepV2(params, stepIndex) {
137
- var _currentFee$feeCompon, _params$recipient;
138
- const currentStep = params.process.steps[stepIndex];
139
- const currentFee = params.process.totalFee[stepIndex];
140
- const feeToken = currentFee.selectedFeeToken || currentFee.defaultFeeToken;
141
- const feeAmount = (_currentFee$feeCompon = currentFee.feeComponent.find(fee => fee.feeType === _swap2.SwapFeeType.NETWORK_FEE)) === null || _currentFee$feeCompon === void 0 ? void 0 : _currentFee$feeCompon.amount;
142
- if (!feeAmount) {
143
- throw new Error('Fee not found for XCM step');
144
- }
145
- const metadata = currentStep.metadata;
146
- const sendingAmount = metadata.sendingValue;
147
- const bnAmount = new _bignumber.default(sendingAmount);
148
- const fromAsset = metadata === null || metadata === void 0 ? void 0 : metadata.originTokenInfo;
149
- const toAsset = metadata === null || metadata === void 0 ? void 0 : metadata.destinationTokenInfo;
150
- if (!fromAsset || !toAsset) {
151
- return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
152
- }
153
- const fromChain = this.chainService.getChainInfoByKey(fromAsset.originChain);
154
- const toChain = this.chainService.getChainInfoByKey(toAsset.originChain);
155
- const toChainNativeAsset = this.chainService.getNativeTokenInfo(toAsset.originChain);
156
- const sender = (0, _utils4._reformatAddressWithChain)(params.address, fromChain);
157
- const receiver = (0, _utils4._reformatAddressWithChain)((_params$recipient = params.recipient) !== null && _params$recipient !== void 0 ? _params$recipient : sender, toChain);
158
-
159
- /* Get transferable balance */
160
- const [fromAssetBalance, feeTokenBalance] = await Promise.all([this.balanceService.getTransferableBalance(sender, fromAsset.originChain, fromAsset.slug, _KoniTypes.ExtrinsicType.TRANSFER_XCM), this.balanceService.getTransferableBalance(sender, fromAsset.originChain, feeToken, _KoniTypes.ExtrinsicType.TRANSFER_XCM)]);
161
- const bnFromAssetBalance = new _bignumber.default(fromAssetBalance.value);
162
- const bnFeeTokenBalance = new _bignumber.default(feeTokenBalance.value);
163
-
164
- /* Compare transferable balance with amount xcm */
165
- if (bnFromAssetBalance.lt(bnAmount)) {
166
- return [new _TransactionError.TransactionError(_types.BasicTxErrorType.NOT_ENOUGH_BALANCE, (0, _i18next.t)(`Insufficient balance. Deposit ${fromAsset.symbol} and try again.`))];
167
- }
108
+ const substrateApi = await this.chainService.getSubstrateApi(fromTokenInfo.originChain).isReady;
109
+ const id = (0, _getId.getId)();
110
+ const [feeInfo, toTokenBalance] = await Promise.all([this.feeService.subscribeChainFee(id, fromTokenInfo.originChain, 'substrate'), this.balanceService.getTotalBalance(senderAddress, toTokenInfo.originChain, toTokenInfo.slug, _KoniTypes.ExtrinsicType.TRANSFER_BALANCE)]);
111
+ const mockSendingValue = stepIndex === 0 ? fromAmount : (selectedQuote === null || selectedQuote === void 0 ? void 0 : selectedQuote.toAmount) || '0';
112
+ const xcmRequest = {
113
+ originTokenInfo: fromTokenInfo,
114
+ destinationTokenInfo: toTokenInfo,
115
+ originChain: fromChainInfo,
116
+ destinationChain: toChainInfo,
117
+ substrateApi: substrateApi,
118
+ feeInfo,
119
+ // Mock sending value to get payment info
120
+ sendingValue: mockSendingValue,
121
+ sender: senderAddress,
122
+ recipient: recipientAddress
123
+ };
168
124
 
169
- /**
170
- * Calculate fee token keep alive after xcm
171
- * If fee token is the same as from token, need to subtract sending amount
172
- * @TODO: Need to update logic if change fee token (multi with rate)
173
- * */
174
- const feeBalanceAfterTransfer = bnFeeTokenBalance.minus(feeAmount).minus(fromAsset.slug === feeToken ? bnAmount : 0);
175
-
176
- /**
177
- * Check fee token balance after transfer.
178
- * Because the balance had subtracted with existence deposit, so only need to check if it's less than 0
179
- * */
180
- if (feeBalanceAfterTransfer.lt(0)) {
181
- return [new _TransactionError.TransactionError(_types.BasicTxErrorType.NOT_ENOUGH_EXISTENTIAL_DEPOSIT, (0, _i18next.t)(`Insufficient balance. Deposit ${fromAsset.symbol} and try again.`))];
182
- }
183
- const destMinAmount = (0, _utils2._getTokenMinAmount)(toAsset);
184
- // TODO: Need to update with new logic, calculate fee to claim on dest chain
185
- const minSendingRequired = new _bignumber.default(destMinAmount).multipliedBy(_utils3.FEE_RATE_MULTIPLIER.high);
125
+ // TODO: calculate fee for destination chain
126
+ const bridgeFeeByDryRun = await (0, _xcm.dryRunXcmExtrinsicV2)(xcmRequest);
127
+ if (!bridgeFeeByDryRun.fee) {
128
+ return undefined;
129
+ }
130
+ const estimatedBridgeFee = (0, _bignumber.default)(bridgeFeeByDryRun.fee).multipliedBy(_utils3.FEE_RATE_MULTIPLIER.medium).toFixed(0, 1);
131
+ const fee = {
132
+ feeComponent: [{
133
+ feeType: _swap.SwapFeeType.NETWORK_FEE,
134
+ amount: estimatedBridgeFee,
135
+ tokenSlug: (0, _utils2._getChainNativeTokenSlug)(fromChainInfo)
136
+ }],
137
+ defaultFeeToken: (0, _utils2._getChainNativeTokenSlug)(fromChainInfo),
138
+ feeOptions: [(0, _utils2._getChainNativeTokenSlug)(fromChainInfo)]
139
+ };
140
+ const isBridgeNativeToken = (0, _utils2._isNativeToken)(fromTokenInfo);
141
+ let bnSendingValue;
142
+ let expectedReceive;
143
+ const actionList = JSON.stringify(path.map(step => step.action));
144
+ const xcmSwapXcm = actionList === JSON.stringify([_swap.DynamicSwapType.BRIDGE, _swap.DynamicSwapType.SWAP, _swap.DynamicSwapType.BRIDGE]);
145
+ const swapXcm = actionList === JSON.stringify([_swap.DynamicSwapType.SWAP, _swap.DynamicSwapType.BRIDGE]);
146
+ const needEditAmount = swapXcm || xcmSwapXcm;
186
147
 
187
- // Check sending token ED for receiver
188
- if (bnAmount.lt(minSendingRequired)) {
189
- const atLeastStr = (0, _utils4.formatNumber)(minSendingRequired, (0, _utils2._getAssetDecimals)(toAsset), _utils4.balanceFormatter, {
190
- maxNumberFormat: (0, _utils2._getAssetDecimals)(toAsset) || 6
191
- });
192
- return [new _TransactionError.TransactionError(_types.TransferTxErrorType.RECEIVER_NOT_ENOUGH_EXISTENTIAL_DEPOSIT, (0, _i18next.t)('You must transfer at least {{amount}} {{symbol}} to keep the destination account alive', {
193
- replace: {
194
- amount: atLeastStr,
195
- symbol: fromAsset.symbol
148
+ // todo: increase transfer amount when XCM local token
149
+ if (stepIndex === 0) {
150
+ expectedReceive = fromAmount;
151
+ bnSendingValue = (0, _bignumber.default)(fromAmount);
152
+ if (needEditAmount) {
153
+ bnSendingValue = bnSendingValue.multipliedBy(_utils3.DEFAULT_EXCESS_AMOUNT_WEIGHT);
154
+ expectedReceive = bnSendingValue.toFixed(0, 1);
196
155
  }
197
- }))];
198
- }
199
-
200
- // Check keepAlive on dest chain for receiver
201
- if (!(0, _utils2._isNativeToken)(toAsset)) {
202
- const toChainApi = this.chainService.getSubstrateApi(toAsset.originChain);
203
-
204
- // TODO: Need to update, currently only support substrate xcm
205
- if (!toChainApi) {
206
- return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR, (0, _i18next.t)('Destination chain is not active'))];
207
- }
208
- const isSendingTokenSufficient = await (0, _utils._isSufficientToken)(toAsset, toChainApi);
209
- if (!isSendingTokenSufficient) {
210
- const toChainNativeAssetBalance = await this.balanceService.getTotalBalance(receiver, toAsset.originChain, toChainNativeAsset.slug, _KoniTypes.ExtrinsicType.TRANSFER_BALANCE);
211
- const isReceiverAliveByNativeToken = (0, _systemPallet._isAccountActive)(toChainNativeAssetBalance.metadata);
212
- if (!isReceiverAliveByNativeToken) {
213
- // TODO: Update message
214
- return [new _TransactionError.TransactionError(_types.TransferTxErrorType.RECEIVER_NOT_ENOUGH_EXISTENTIAL_DEPOSIT, (0, _i18next.t)('The recipient account has less than {{amount}} {{nativeSymbol}}, which can lead to your {{localSymbol}} being lost. Change recipient account and try again', {
215
- replace: {
216
- amount: toChainNativeAssetBalance.value,
217
- nativeSymbol: toChainNativeAsset.symbol,
218
- localSymbol: toAsset.symbol
219
- }
220
- }))];
156
+ if (isBridgeNativeToken) {
157
+ bnSendingValue = bnSendingValue.plus((0, _bignumber.default)(estimatedBridgeFee));
158
+ } else {
159
+ bnSendingValue = bnSendingValue.plus((0, _bignumber.default)((0, _utils2._getTokenMinAmount)(toTokenInfo)).multipliedBy(_utils3.FEE_RATE_MULTIPLIER.medium)).plus((0, _utils2._getTokenMinAmount)(toTokenInfo));
221
160
  }
161
+ if ((0, _bignumber.default)(toTokenBalance.value).lte(0)) {
162
+ bnSendingValue = bnSendingValue.plus((0, _utils2._getTokenMinAmount)(toTokenInfo));
163
+ }
164
+ } else {
165
+ // bridge after swap
166
+ expectedReceive = selectedQuote.toAmount;
167
+ if (needEditAmount) {
168
+ bnSendingValue = (0, _bignumber.default)(selectedQuote.toAmount).multipliedBy(_utils3.DEFAULT_EXCESS_AMOUNT_WEIGHT); // need to round
169
+ } else {
170
+ bnSendingValue = (0, _bignumber.default)(selectedQuote.toAmount);
171
+ }
172
+ }
173
+ if (toTokenInfo.originChain === 'mythos' && (0, _utils2._isNativeToken)(toTokenInfo)) {
174
+ bnSendingValue = bnSendingValue.plus((0, _bignumber.default)(2.5).shiftedBy((0, _utils2._getAssetDecimals)(toTokenInfo)));
222
175
  }
176
+ const step = {
177
+ // @ts-ignore
178
+ metadata: {
179
+ sendingValue: bnSendingValue.toFixed(0, 1),
180
+ expectedReceive,
181
+ originTokenInfo: fromTokenInfo,
182
+ destinationTokenInfo: toTokenInfo,
183
+ receiver: recipientAddress,
184
+ sender: senderAddress
185
+ },
186
+ name: `Transfer ${fromTokenInfo.symbol} from ${fromChainInfo.name}`,
187
+ type: _serviceBase.CommonStepType.XCM
188
+ };
189
+ return [step, fee];
190
+ } catch (e) {
191
+ console.error('Error creating xcm step', e);
192
+ return undefined;
223
193
  }
224
-
225
- // SKIP: BECAUSE CURRENTLY NOT SUPPORT SNOWBRIDGE FOR SWAP FEATURE
226
- // check native token ED on dest chain for receiver
227
- // const bnKeepAliveBalance = _isNativeToken(destinationTokenInfo) ? new BigN(receiverNativeBalance).plus(sendingAmount) : new BigN(receiverNativeBalance);
228
- //
229
- // if (isSnowBridge && bnKeepAliveBalance.lt(_getChainExistentialDeposit(destChainInfo))) {
230
- // const { decimals, symbol } = _getChainNativeTokenBasicInfo(destChainInfo);
231
- // const atLeastStr = formatNumber(_getChainExistentialDeposit(destChainInfo), decimals || 0, balanceFormatter, { maxNumberFormat: 6 });
232
- //
233
- // error = new TransactionError(TransferTxErrorType.RECEIVER_NOT_ENOUGH_EXISTENTIAL_DEPOSIT, t(' Insufficient {{symbol}} on {{chain}} to cover min balance ({{amount}} {{symbol}})', { replace: { amount: atLeastStr, symbol, chain: destChainInfo.name } }));
234
- // }
235
-
236
- return [];
237
194
  }
238
- async validateTokenApproveStep(params, stepIndex) {
239
- return Promise.resolve([]);
195
+ async handleBridgeStep(params) {
196
+ const briefXcmStep = params.process.steps[params.currentStep].metadata;
197
+ if (!briefXcmStep || !briefXcmStep.originTokenInfo || !briefXcmStep.destinationTokenInfo || !briefXcmStep.sendingValue) {
198
+ throw new Error('XCM metadata error');
199
+ }
200
+ const originAsset = briefXcmStep.originTokenInfo;
201
+ const destinationAsset = briefXcmStep.destinationTokenInfo;
202
+ const originChain = this.chainService.getChainInfoByKey(originAsset.originChain);
203
+ const destinationChain = this.chainService.getChainInfoByKey(destinationAsset.originChain);
204
+ const substrateApi = this.chainService.getSubstrateApi(originAsset.originChain);
205
+ const chainApi = await substrateApi.isReady;
206
+ const feeInfo = await this.feeService.subscribeChainFee((0, _getId.getId)(), originAsset.originChain, 'substrate');
207
+ const xcmRequest = {
208
+ originTokenInfo: originAsset,
209
+ destinationTokenInfo: destinationAsset,
210
+ sendingValue: briefXcmStep.sendingValue,
211
+ recipient: briefXcmStep.receiver,
212
+ substrateApi: chainApi,
213
+ sender: briefXcmStep.sender,
214
+ destinationChain,
215
+ originChain,
216
+ feeInfo
217
+ };
218
+ const extrinsic = await (0, _xcm.createXcmExtrinsicV2)(xcmRequest);
219
+ if (!extrinsic) {
220
+ throw new Error('XCM extrinsic error');
221
+ }
222
+ const xcmData = {
223
+ originNetworkKey: originAsset.originChain,
224
+ destinationNetworkKey: destinationAsset.originChain,
225
+ from: briefXcmStep.sender,
226
+ to: briefXcmStep.receiver,
227
+ value: briefXcmStep.sendingValue,
228
+ tokenSlug: originAsset.slug,
229
+ showExtraWarning: true
230
+ };
231
+ return {
232
+ txChain: originAsset.originChain,
233
+ extrinsic,
234
+ transferNativeAmount: (0, _utils2._isNativeToken)(originAsset) ? briefXcmStep.sendingValue : '0',
235
+ extrinsicType: _KoniTypes.ExtrinsicType.TRANSFER_XCM,
236
+ chainType: _KoniTypes.ChainType.SUBSTRATE,
237
+ txData: xcmData
238
+ };
240
239
  }
241
240
  async validateSetFeeTokenStep(params, stepIndex) {
242
241
  if (!params.selectedQuote) {
@@ -253,46 +252,6 @@ class SwapBaseHandler {
253
252
  }
254
253
  return [];
255
254
  }
256
- async validateSwapStep(params, isXcmOk, stepIndex) {
257
- // check swap quote timestamp
258
- // check balance to pay transaction fee
259
- // check balance against spending amount
260
- if (!params.selectedQuote) {
261
- return Promise.resolve([new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)]);
262
- }
263
- const selectedQuote = params.selectedQuote;
264
- const currentTimestamp = +Date.now();
265
- if (selectedQuote.aliveUntil <= currentTimestamp) {
266
- return Promise.resolve([new _TransactionError.TransactionError(_swap2.SwapErrorType.QUOTE_TIMEOUT)]);
267
- }
268
- const stepFee = params.process.totalFee[stepIndex].feeComponent;
269
- const networkFee = stepFee.find(fee => fee.feeType === _swap2.SwapFeeType.NETWORK_FEE);
270
- if (!networkFee) {
271
- return Promise.resolve([new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)]);
272
- }
273
- const fromAsset = this.chainService.getAssetBySlug(params.selectedQuote.pair.from);
274
- const feeTokenInfo = this.chainService.getAssetBySlug(networkFee.tokenSlug);
275
- const feeTokenChain = this.chainService.getChainInfoByKey(feeTokenInfo.originChain);
276
- const {
277
- fromAmount,
278
- minSwap
279
- } = params.selectedQuote;
280
- const [feeTokenBalance, fromAssetBalance] = await Promise.all([this.balanceService.getTransferableBalance(params.address, feeTokenInfo.originChain, feeTokenInfo.slug), this.balanceService.getTransferableBalance(params.address, fromAsset.originChain, fromAsset.slug)]);
281
- const balanceError = (0, _swap._validateBalanceToSwap)(fromAsset, feeTokenInfo, feeTokenChain, networkFee.amount, fromAssetBalance.value, feeTokenBalance.value, fromAmount, isXcmOk, minSwap);
282
- if (balanceError) {
283
- return Promise.resolve([balanceError]);
284
- }
285
- if (!params.recipient) {
286
- return Promise.resolve([]);
287
- }
288
- const toAsset = this.chainService.getAssetBySlug(params.selectedQuote.pair.to);
289
- const toAssetChain = this.chainService.getChainInfoByKey(toAsset.originChain);
290
- const recipientError = (0, _swap._validateSwapRecipient)(toAssetChain, params.recipient);
291
- if (recipientError) {
292
- return Promise.resolve([recipientError]);
293
- }
294
- return Promise.resolve([]);
295
- }
296
255
  async validateBridgeStep(receiver, fromToken, toToken, selectedFeeToken, toChainNativeToken, bnBridgeAmount, bnFromTokenBalance, bnBridgeFeeAmount, bnFeeTokenBalance, bnBridgeDeliveryFee) {
297
256
  const minBridgeAmountRequired = new _bignumber.default((0, _utils2._getTokenMinAmount)(toToken)).multipliedBy(_utils3.FEE_RATE_MULTIPLIER.high);
298
257
  const spendingAndFeePaymentValidation = (0, _logicValidation.validateSpendingAndFeePayment)(fromToken, selectedFeeToken, bnBridgeAmount, bnFromTokenBalance, bnBridgeFeeAmount, bnFeeTokenBalance);
@@ -313,12 +272,13 @@ class SwapBaseHandler {
313
272
 
314
273
  // By here, we know that the user is receiving a valid amount of toToken
315
274
  const toChainApi = this.chainService.getSubstrateApi(toToken.originChain);
275
+ const sufficientChain = this.chainService.value.sufficientChains;
316
276
  if (!toChainApi) {
317
277
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
318
278
  }
319
279
 
320
280
  // Only need to check if account is alive with the receiving toToken
321
- const isToTokenSufficient = await (0, _utils._isSufficientToken)(toToken, toChainApi);
281
+ const isToTokenSufficient = await (0, _utils._isSufficientToken)(toToken, toChainApi, sufficientChain);
322
282
  if (!isToTokenSufficient && !(0, _utils2._isNativeToken)(toToken)) {
323
283
  // sending token cannot keep account alive, must check with native token
324
284
  const toChainNativeTokenBalance = await this.balanceService.getTotalBalance(receiver, toToken.originChain, toChainNativeToken.slug, _KoniTypes.ExtrinsicType.TRANSFER_BALANCE);
@@ -343,7 +303,7 @@ class SwapBaseHandler {
343
303
  const atLeastStr = (0, _utils4.formatNumber)((0, _utils2._getTokenMinAmount)(receivingToken), (0, _utils2._getAssetDecimals)(receivingToken), _utils4.balanceFormatter, {
344
304
  maxNumberFormat: (0, _utils2._getAssetDecimals)(receivingToken) || 6
345
305
  });
346
- return [new _TransactionError.TransactionError(_swap2.SwapErrorType.NOT_MEET_MIN_SWAP, (0, _i18next.t)('You can\'t receive less than {{number}} {{symbol}}', {
306
+ return [new _TransactionError.TransactionError(_swap.SwapErrorType.NOT_MEET_MIN_SWAP, (0, _i18next.t)('You can\'t receive less than {{number}} {{symbol}}', {
347
307
  replace: {
348
308
  number: atLeastStr,
349
309
  symbol: (0, _utils2._getAssetSymbol)(receivingToken)
@@ -355,7 +315,7 @@ class SwapBaseHandler {
355
315
  const isEvmDestChain = (0, _utils2._isChainEvmCompatible)(swapToChain);
356
316
  if (isEvmAddress && !isEvmDestChain || !isEvmAddress && isEvmDestChain) {
357
317
  // todo: update this condition
358
- return [new _TransactionError.TransactionError(_swap2.SwapErrorType.INVALID_RECIPIENT)];
318
+ return [new _TransactionError.TransactionError(_swap.SwapErrorType.INVALID_RECIPIENT)];
359
319
  }
360
320
  }
361
321
  return [];
@@ -364,7 +324,7 @@ class SwapBaseHandler {
364
324
  const swapStepInfo = params.process.steps[swapIndex];
365
325
  const swapMetadata = swapStepInfo.metadata; // todo
366
326
  const swapFee = params.process.totalFee[swapIndex];
367
- if (!swapMetadata || !swapMetadata.destinationTokenInfo || !swapMetadata.originTokenInfo || !swapMetadata.sendingValue) {
327
+ if (!swapMetadata || !swapMetadata.destinationTokenInfo || !swapMetadata.originTokenInfo || !swapMetadata.sendingValue || !swapMetadata.expectedReceive) {
368
328
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
369
329
  }
370
330
 
@@ -373,32 +333,35 @@ class SwapBaseHandler {
373
333
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
374
334
  }
375
335
  if (params.selectedQuote.aliveUntil <= +Date.now()) {
376
- return [new _TransactionError.TransactionError(_swap2.SwapErrorType.QUOTE_TIMEOUT)];
336
+ return [new _TransactionError.TransactionError(_swap.SwapErrorType.QUOTE_TIMEOUT)];
377
337
  }
378
- const swapNetworkFee = swapFee.feeComponent.find(fee => fee.feeType === _swap2.SwapFeeType.NETWORK_FEE);
338
+ if (params.selectedQuote.toAmount !== swapMetadata.expectedReceive) {
339
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
340
+ }
341
+ const swapNetworkFee = swapFee.feeComponent.find(fee => fee.feeType === _swap.SwapFeeType.NETWORK_FEE);
379
342
  if (!swapNetworkFee) {
380
343
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
381
344
  }
382
345
  const swapToken = swapMetadata.originTokenInfo;
383
346
  const swapReceivingToken = swapMetadata.destinationTokenInfo;
384
- const bnSwapReceivingAmount = (0, _bignumber.default)(params.selectedQuote.toAmount);
347
+ const bnSwapReceivingAmount = (0, _bignumber.default)(swapMetadata.expectedReceive);
385
348
  const bnSwapValue = (0, _bignumber.default)(swapMetadata.sendingValue);
386
349
  const bnSwapFeeAmount = (0, _bignumber.default)(swapNetworkFee.amount);
387
350
  const swapFeeToken = this.chainService.getAssetBySlug(swapFee.selectedFeeToken || swapFee.defaultFeeToken);
388
351
  const swapToChain = this.chainService.getChainInfoByKey(swapMetadata.destinationTokenInfo.originChain);
389
- const [swapFeeTokenBalance, swapFromTokenBalance] = await Promise.all([this.balanceService.getTransferableBalance(params.address, swapFeeToken.originChain, swapFeeToken.slug, _KoniTypes.ExtrinsicType.SWAP), this.balanceService.getTransferableBalance(params.address, swapToken.originChain, swapToken.slug, _KoniTypes.ExtrinsicType.SWAP)]);
352
+ const [swapFeeTokenBalance, swapFromTokenBalance] = await Promise.all([this.balanceService.getTransferableBalance(swapMetadata.sender, swapFeeToken.originChain, swapFeeToken.slug, _KoniTypes.ExtrinsicType.SWAP), this.balanceService.getTransferableBalance(swapMetadata.sender, swapToken.originChain, swapToken.slug, _KoniTypes.ExtrinsicType.SWAP)]);
390
353
  const bnSwapFromTokenBalance = (0, _bignumber.default)(swapFromTokenBalance.value);
391
354
  const bnSwapFeeTokenBalance = (0, _bignumber.default)(swapFeeTokenBalance.value);
392
- return this.validateSwapStepV2(swapToChain, swapToken, swapReceivingToken, swapFeeToken, bnSwapValue, bnSwapReceivingAmount, bnSwapFromTokenBalance, bnSwapFeeAmount, bnSwapFeeTokenBalance, params.recipient);
355
+ return this.validateSwapStepV2(swapToChain, swapToken, swapReceivingToken, swapFeeToken, bnSwapValue, bnSwapReceivingAmount, bnSwapFromTokenBalance, bnSwapFeeAmount, bnSwapFeeTokenBalance, swapMetadata.receiver);
393
356
  }
394
357
  async validateXcmSwapProcess(params, swapIndex, xcmIndex) {
395
- var _currentFee$feeCompon2, _params$recipient2;
358
+ var _currentFee$feeCompon, _xcmMetadata$receiver;
396
359
  // Bridge
397
360
  const currentStep = params.process.steps[xcmIndex];
398
361
  const xcmMetadata = currentStep.metadata;
399
362
  const currentFee = params.process.totalFee[xcmIndex];
400
- const bridgeFeeAmount = (_currentFee$feeCompon2 = currentFee.feeComponent.find(fee => fee.feeType === _swap2.SwapFeeType.NETWORK_FEE)) === null || _currentFee$feeCompon2 === void 0 ? void 0 : _currentFee$feeCompon2.amount;
401
- if (!xcmMetadata || !xcmMetadata.destinationTokenInfo || !xcmMetadata.originTokenInfo || !xcmMetadata.sendingValue) {
363
+ const bridgeFeeAmount = (_currentFee$feeCompon = currentFee.feeComponent.find(fee => fee.feeType === _swap.SwapFeeType.NETWORK_FEE)) === null || _currentFee$feeCompon === void 0 ? void 0 : _currentFee$feeCompon.amount;
364
+ if (!xcmMetadata || !xcmMetadata.destinationTokenInfo || !xcmMetadata.originTokenInfo || !xcmMetadata.sendingValue || !xcmMetadata.expectedReceive) {
402
365
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
403
366
  }
404
367
  if (!bridgeFeeAmount) {
@@ -417,8 +380,8 @@ class SwapBaseHandler {
417
380
  const bridgeSelectedFeeToken = this.chainService.getAssetBySlug(currentFee.selectedFeeToken || currentFee.defaultFeeToken);
418
381
  const bnBridgeDeliveryFee = (0, _bignumber.default)(0); // todo
419
382
 
420
- const bridgeSender = (0, _utils4._reformatAddressWithChain)(params.address, this.chainService.getChainInfoByKey(bridgeFromToken.originChain));
421
- const bridgeReceiver = (0, _utils4._reformatAddressWithChain)((_params$recipient2 = params.recipient) !== null && _params$recipient2 !== void 0 ? _params$recipient2 : bridgeSender, this.chainService.getChainInfoByKey(bridgeToToken.originChain));
383
+ const bridgeSender = (0, _utils4._reformatAddressWithChain)(xcmMetadata.sender, this.chainService.getChainInfoByKey(bridgeFromToken.originChain));
384
+ const bridgeReceiver = (0, _utils4._reformatAddressWithChain)((_xcmMetadata$receiver = xcmMetadata.receiver) !== null && _xcmMetadata$receiver !== void 0 ? _xcmMetadata$receiver : bridgeSender, this.chainService.getChainInfoByKey(bridgeToToken.originChain));
422
385
  const [bridgeFromTokenBalance, bridgeFeeTokenBalance] = await Promise.all([this.balanceService.getTransferableBalance(bridgeSender, bridgeFromToken.originChain, bridgeFromToken.slug, _KoniTypes.ExtrinsicType.TRANSFER_XCM), this.balanceService.getTransferableBalance(bridgeSender, bridgeFromToken.originChain, bridgeSelectedFeeToken.slug, _KoniTypes.ExtrinsicType.TRANSFER_XCM)]);
423
386
 
424
387
  // Native token balance has already accounted for ED aka strict mode
@@ -433,7 +396,10 @@ class SwapBaseHandler {
433
396
  const swapStepInfo = params.process.steps[swapIndex];
434
397
  const swapMetadata = swapStepInfo.metadata; // todo
435
398
  const swapFee = params.process.totalFee[swapIndex];
436
- if (!swapMetadata || !swapMetadata.destinationTokenInfo || !swapMetadata.originTokenInfo || !swapMetadata.sendingValue) {
399
+ if (swapStepInfo.type !== _types.SwapStepType.SWAP) {
400
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
401
+ }
402
+ if (!swapMetadata || !swapMetadata.destinationTokenInfo || !swapMetadata.originTokenInfo || !swapMetadata.sendingValue || !swapMetadata.expectedReceive) {
437
403
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
438
404
  }
439
405
 
@@ -442,9 +408,9 @@ class SwapBaseHandler {
442
408
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
443
409
  }
444
410
  if (params.selectedQuote.aliveUntil <= +Date.now()) {
445
- return [new _TransactionError.TransactionError(_swap2.SwapErrorType.QUOTE_TIMEOUT)];
411
+ return [new _TransactionError.TransactionError(_swap.SwapErrorType.QUOTE_TIMEOUT)];
446
412
  }
447
- const swapNetworkFee = swapFee.feeComponent.find(fee => fee.feeType === _swap2.SwapFeeType.NETWORK_FEE);
413
+ const swapNetworkFee = swapFee.feeComponent.find(fee => fee.feeType === _swap.SwapFeeType.NETWORK_FEE);
448
414
  if (!swapNetworkFee) {
449
415
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
450
416
  }
@@ -463,17 +429,226 @@ class SwapBaseHandler {
463
429
  const atLeastString = (0, _utils4.formatNumber)((0, _utils2._getTokenMinAmount)(swapToken), (0, _utils2._getAssetDecimals)(swapToken), _utils4.balanceFormatter, {
464
430
  maxNumberFormat: (0, _utils2._getAssetDecimals)(swapToken) || 6
465
431
  });
466
- return [new _TransactionError.TransactionError(_swap2.SwapErrorType.NOT_MEET_MIN_SWAP, (0, _i18next.t)(`Swap amount too small. Increase to more than ${atLeastString} ${(0, _utils2._getAssetSymbol)(swapToken)} and try again`))];
432
+ return [new _TransactionError.TransactionError(_swap.SwapErrorType.NOT_MEET_MIN_SWAP, (0, _i18next.t)(`Swap amount too small. Increase to more than ${atLeastString} ${(0, _utils2._getAssetSymbol)(swapToken)} and try again`))];
433
+ }
434
+ const swapFeeToken = this.chainService.getAssetBySlug(swapFee.selectedFeeToken || swapFee.defaultFeeToken);
435
+ const swapToChain = this.chainService.getChainInfoByKey(swapMetadata.destinationTokenInfo.originChain);
436
+ const [swapFeeTokenBalance, swapFromTokenBalance] = await Promise.all([this.balanceService.getTransferableBalance(swapMetadata.sender, swapFeeToken.originChain, swapFeeToken.slug, _KoniTypes.ExtrinsicType.SWAP), this.balanceService.getTransferableBalance(swapMetadata.sender, swapToken.originChain, swapToken.slug, _KoniTypes.ExtrinsicType.SWAP)]);
437
+ const bnSwapFromTokenBalance = (0, _bignumber.default)(swapFromTokenBalance.value).plus(bnBridgeAmount);
438
+ const bnSwapFeeTokenBalance = (0, _bignumber.default)(swapFeeTokenBalance.value);
439
+ const swapStepValidation = this.validateSwapStepV2(swapToChain, swapToken, swapReceivingToken, swapFeeToken, bnSwapValue, bnSwapReceivingAmount, bnSwapFromTokenBalance, bnSwapFeeAmount, bnSwapFeeTokenBalance, swapMetadata.receiver);
440
+ if (swapStepValidation.length > 0) {
441
+ return swapStepValidation;
442
+ }
443
+ return [];
444
+ }
445
+ async validateSwapXcmProcess(params, swapIndex, xcmIndex) {
446
+ var _currentFee$feeCompon2, _xcmMetadata$receiver2;
447
+ // Swap
448
+ const swapStepInfo = params.process.steps[swapIndex];
449
+ const swapMetadata = swapStepInfo.metadata; // todo
450
+ const swapFee = params.process.totalFee[swapIndex];
451
+ if (!swapMetadata || !swapMetadata.destinationTokenInfo || !swapMetadata.originTokenInfo || !swapMetadata.sendingValue || !swapMetadata.expectedReceive) {
452
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
453
+ }
454
+
455
+ // Validate quote
456
+ if (!params.selectedQuote) {
457
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
458
+ }
459
+ if (params.selectedQuote.aliveUntil <= +Date.now()) {
460
+ return [new _TransactionError.TransactionError(_swap.SwapErrorType.QUOTE_TIMEOUT)];
461
+ }
462
+ const swapNetworkFee = swapFee.feeComponent.find(fee => fee.feeType === _swap.SwapFeeType.NETWORK_FEE);
463
+ if (!swapNetworkFee) {
464
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
465
+ }
466
+ const swapToken = swapMetadata.originTokenInfo;
467
+ const swapReceivingToken = swapMetadata.destinationTokenInfo;
468
+ const bnSwapReceivingAmount = (0, _bignumber.default)(swapMetadata.expectedReceive);
469
+ const bnSwapValue = (0, _bignumber.default)(swapMetadata.sendingValue);
470
+ const bnSwapFeeAmount = (0, _bignumber.default)(swapNetworkFee.amount);
471
+ if (bnSwapValue.lte((0, _utils2._getTokenMinAmount)(swapToken))) {
472
+ const atLeastString = (0, _utils4.formatNumber)((0, _utils2._getTokenMinAmount)(swapToken), (0, _utils2._getAssetDecimals)(swapToken), _utils4.balanceFormatter, {
473
+ maxNumberFormat: (0, _utils2._getAssetDecimals)(swapToken) || 6
474
+ });
475
+ return [new _TransactionError.TransactionError(_swap.SwapErrorType.NOT_MEET_MIN_SWAP, (0, _i18next.t)(`Swap amount too small. Increase to more than ${atLeastString} ${(0, _utils2._getAssetSymbol)(swapToken)} and try again`))];
476
+ }
477
+ const swapFeeToken = this.chainService.getAssetBySlug(swapFee.selectedFeeToken || swapFee.defaultFeeToken);
478
+ const swapToChain = this.chainService.getChainInfoByKey(swapMetadata.destinationTokenInfo.originChain);
479
+ const [swapFeeTokenBalance, swapFromTokenBalance] = await Promise.all([this.balanceService.getTransferableBalance(swapMetadata.sender, swapFeeToken.originChain, swapFeeToken.slug, _KoniTypes.ExtrinsicType.SWAP), this.balanceService.getTransferableBalance(swapMetadata.sender, swapToken.originChain, swapToken.slug, _KoniTypes.ExtrinsicType.SWAP)]);
480
+ const bnSwapFromTokenBalance = (0, _bignumber.default)(swapFromTokenBalance.value);
481
+ const bnSwapFeeTokenBalance = (0, _bignumber.default)(swapFeeTokenBalance.value);
482
+ const swapStepValidation = this.validateSwapStepV2(swapToChain, swapToken, swapReceivingToken, swapFeeToken, bnSwapValue, bnSwapReceivingAmount, bnSwapFromTokenBalance, bnSwapFeeAmount, bnSwapFeeTokenBalance, swapMetadata.receiver);
483
+ if (swapStepValidation.length > 0) {
484
+ return swapStepValidation;
485
+ }
486
+
487
+ // Bridge
488
+ const currentStep = params.process.steps[xcmIndex];
489
+ const xcmMetadata = currentStep.metadata;
490
+ const currentFee = params.process.totalFee[xcmIndex];
491
+ const bridgeFeeAmount = (_currentFee$feeCompon2 = currentFee.feeComponent.find(fee => fee.feeType === _swap.SwapFeeType.NETWORK_FEE)) === null || _currentFee$feeCompon2 === void 0 ? void 0 : _currentFee$feeCompon2.amount;
492
+ if (!xcmMetadata || !xcmMetadata.destinationTokenInfo || !xcmMetadata.originTokenInfo || !xcmMetadata.sendingValue || !xcmMetadata.expectedReceive) {
493
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
494
+ }
495
+ if (!bridgeFeeAmount) {
496
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
497
+ }
498
+ const bridgeFromToken = xcmMetadata.originTokenInfo;
499
+ const bridgeToToken = xcmMetadata.destinationTokenInfo;
500
+ const fromChain = this.chainService.getChainInfoByKey(bridgeFromToken.originChain);
501
+ const toChain = this.chainService.getChainInfoByKey(bridgeToToken.originChain);
502
+ if (swapReceivingToken.slug !== bridgeFromToken.slug) {
503
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
504
+ }
505
+ if ((0, _xcmParser._isSnowBridgeXcm)(fromChain, toChain)) {
506
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.UNSUPPORTED)];
507
+ }
508
+ const bnBridgeFeeAmount = (0, _bignumber.default)(bridgeFeeAmount);
509
+ const bnBridgeAmount = new _bignumber.default(xcmMetadata.sendingValue);
510
+ const bridgeToChainNativeToken = this.chainService.getNativeTokenInfo(bridgeToToken.originChain);
511
+ const bridgeSelectedFeeToken = this.chainService.getAssetBySlug(currentFee.selectedFeeToken || currentFee.defaultFeeToken);
512
+ const bnBridgeDeliveryFee = (0, _bignumber.default)(0); // todo
513
+
514
+ const bridgeSender = (0, _utils4._reformatAddressWithChain)(xcmMetadata.sender, this.chainService.getChainInfoByKey(bridgeFromToken.originChain));
515
+ const bridgeReceiver = (0, _utils4._reformatAddressWithChain)((_xcmMetadata$receiver2 = xcmMetadata.receiver) !== null && _xcmMetadata$receiver2 !== void 0 ? _xcmMetadata$receiver2 : bridgeSender, this.chainService.getChainInfoByKey(bridgeToToken.originChain));
516
+ const [bridgeFromTokenBalance, bridgeFeeTokenBalance] = await Promise.all([this.balanceService.getTransferableBalance(bridgeSender, bridgeFromToken.originChain, bridgeFromToken.slug, _KoniTypes.ExtrinsicType.TRANSFER_XCM), this.balanceService.getTransferableBalance(bridgeSender, bridgeFromToken.originChain, bridgeSelectedFeeToken.slug, _KoniTypes.ExtrinsicType.TRANSFER_XCM)]);
517
+
518
+ // Native token balance has already accounted for ED aka strict mode
519
+ const bnBridgeFromTokenBalance = new _bignumber.default(bridgeFromTokenBalance.value).plus(bnSwapReceivingAmount);
520
+ const bnBridgeFeeTokenBalance = new _bignumber.default(bridgeFeeTokenBalance.value);
521
+ const bridgeStepValidation = await this.validateBridgeStep(bridgeReceiver, bridgeFromToken, bridgeToToken, bridgeSelectedFeeToken, bridgeToChainNativeToken, bnBridgeAmount, bnBridgeFromTokenBalance, bnBridgeFeeAmount, bnBridgeFeeTokenBalance, bnBridgeDeliveryFee);
522
+ if (bridgeStepValidation.length > 0) {
523
+ return bridgeStepValidation;
524
+ }
525
+ return [];
526
+ }
527
+ async validateXcmSwapXcmProcess(params, swapIndex, xcmIndex, transitIndex) {
528
+ var _bridgeFee$feeCompone, _bridgeMetadata$recei, _transitTotalFee$feeC, _transitMetadata$rece;
529
+ // Bridge
530
+ const bridgeStep = params.process.steps[xcmIndex];
531
+ const bridgeMetadata = bridgeStep.metadata;
532
+ const bridgeFee = params.process.totalFee[xcmIndex];
533
+ const bridgeFeeAmount = (_bridgeFee$feeCompone = bridgeFee.feeComponent.find(fee => fee.feeType === _swap.SwapFeeType.NETWORK_FEE)) === null || _bridgeFee$feeCompone === void 0 ? void 0 : _bridgeFee$feeCompone.amount;
534
+ if (!bridgeMetadata || !bridgeMetadata.destinationTokenInfo || !bridgeMetadata.originTokenInfo || !bridgeMetadata.sendingValue || !bridgeMetadata.expectedReceive) {
535
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
536
+ }
537
+ if (!bridgeFeeAmount) {
538
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
539
+ }
540
+ const bridgeFromToken = bridgeMetadata.originTokenInfo;
541
+ const bridgeToToken = bridgeMetadata.destinationTokenInfo;
542
+ const fromChain = this.chainService.getChainInfoByKey(bridgeFromToken.originChain);
543
+ const toChain = this.chainService.getChainInfoByKey(bridgeToToken.originChain);
544
+ if ((0, _xcmParser._isSnowBridgeXcm)(fromChain, toChain)) {
545
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.UNSUPPORTED)];
546
+ }
547
+ const bnBridgeFeeAmount = (0, _bignumber.default)(bridgeFeeAmount);
548
+ const bnBridgeAmount = new _bignumber.default(bridgeMetadata.sendingValue);
549
+ const bridgeToChainNativeToken = this.chainService.getNativeTokenInfo(bridgeToToken.originChain);
550
+ const bridgeSelectedFeeToken = this.chainService.getAssetBySlug(bridgeFee.selectedFeeToken || bridgeFee.defaultFeeToken);
551
+ const bnBridgeDeliveryFee = (0, _bignumber.default)(0); // todo
552
+
553
+ const bridgeSender = (0, _utils4._reformatAddressWithChain)(bridgeMetadata.sender, this.chainService.getChainInfoByKey(bridgeFromToken.originChain));
554
+ const bridgeReceiver = (0, _utils4._reformatAddressWithChain)((_bridgeMetadata$recei = bridgeMetadata.receiver) !== null && _bridgeMetadata$recei !== void 0 ? _bridgeMetadata$recei : bridgeSender, this.chainService.getChainInfoByKey(bridgeToToken.originChain));
555
+ const [bridgeFromTokenBalance, bridgeFeeTokenBalance] = await Promise.all([this.balanceService.getTransferableBalance(bridgeSender, bridgeFromToken.originChain, bridgeFromToken.slug, _KoniTypes.ExtrinsicType.TRANSFER_XCM), this.balanceService.getTransferableBalance(bridgeSender, bridgeFromToken.originChain, bridgeSelectedFeeToken.slug, _KoniTypes.ExtrinsicType.TRANSFER_XCM)]);
556
+
557
+ // Native token balance has already accounted for ED aka strict mode
558
+ const bnBridgeFromTokenBalance = new _bignumber.default(bridgeFromTokenBalance.value);
559
+ const bnBridgeFeeTokenBalance = new _bignumber.default(bridgeFeeTokenBalance.value);
560
+ const bridgeStepValidation = await this.validateBridgeStep(bridgeReceiver, bridgeFromToken, bridgeToToken, bridgeSelectedFeeToken, bridgeToChainNativeToken, bnBridgeAmount, bnBridgeFromTokenBalance, bnBridgeFeeAmount, bnBridgeFeeTokenBalance, bnBridgeDeliveryFee);
561
+ if (bridgeStepValidation.length > 0) {
562
+ return bridgeStepValidation;
563
+ }
564
+
565
+ // Swap
566
+ const swapStepInfo = params.process.steps[swapIndex];
567
+ const swapMetadata = swapStepInfo.metadata; // todo
568
+ const swapFee = params.process.totalFee[swapIndex];
569
+ if (swapStepInfo.type !== _types.SwapStepType.SWAP) {
570
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
571
+ }
572
+ if (!swapMetadata || !swapMetadata.destinationTokenInfo || !swapMetadata.originTokenInfo || !swapMetadata.sendingValue || !swapMetadata.expectedReceive) {
573
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
574
+ }
575
+
576
+ // Validate quote
577
+ if (!params.selectedQuote) {
578
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
579
+ }
580
+ if (params.selectedQuote.aliveUntil <= +Date.now()) {
581
+ return [new _TransactionError.TransactionError(_swap.SwapErrorType.QUOTE_TIMEOUT)];
582
+ }
583
+ const swapNetworkFee = swapFee.feeComponent.find(fee => fee.feeType === _swap.SwapFeeType.NETWORK_FEE);
584
+ if (!swapNetworkFee) {
585
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
586
+ }
587
+ const swapToken = swapMetadata.originTokenInfo;
588
+ const swapReceivingToken = swapMetadata.destinationTokenInfo;
589
+ const bnSwapReceivingAmount = (0, _bignumber.default)(swapMetadata.expectedReceive);
590
+ if (swapToken.slug !== bridgeToToken.slug) {
591
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
592
+ }
593
+ const bnSwapValue = (0, _bignumber.default)(swapMetadata.sendingValue);
594
+ const bnSwapFeeAmount = (0, _bignumber.default)(swapNetworkFee.amount);
595
+ if (bnSwapValue.gt(bnBridgeAmount)) {
596
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
597
+ }
598
+ if (bnSwapValue.lte((0, _utils2._getTokenMinAmount)(swapToken))) {
599
+ const atLeastString = (0, _utils4.formatNumber)((0, _utils2._getTokenMinAmount)(swapToken), (0, _utils2._getAssetDecimals)(swapToken), _utils4.balanceFormatter, {
600
+ maxNumberFormat: (0, _utils2._getAssetDecimals)(swapToken) || 6
601
+ });
602
+ return [new _TransactionError.TransactionError(_swap.SwapErrorType.NOT_MEET_MIN_SWAP, (0, _i18next.t)(`Swap amount too small. Increase to more than ${atLeastString} ${(0, _utils2._getAssetSymbol)(swapToken)} and try again`))];
467
603
  }
468
604
  const swapFeeToken = this.chainService.getAssetBySlug(swapFee.selectedFeeToken || swapFee.defaultFeeToken);
469
605
  const swapToChain = this.chainService.getChainInfoByKey(swapMetadata.destinationTokenInfo.originChain);
470
- const [swapFeeTokenBalance, swapFromTokenBalance] = await Promise.all([this.balanceService.getTransferableBalance(params.address, swapFeeToken.originChain, swapFeeToken.slug, _KoniTypes.ExtrinsicType.SWAP), this.balanceService.getTransferableBalance(params.address, swapToken.originChain, swapToken.slug, _KoniTypes.ExtrinsicType.SWAP)]);
606
+ const [swapFeeTokenBalance, swapFromTokenBalance] = await Promise.all([this.balanceService.getTransferableBalance(swapMetadata.sender, swapFeeToken.originChain, swapFeeToken.slug, _KoniTypes.ExtrinsicType.SWAP), this.balanceService.getTransferableBalance(swapMetadata.sender, swapToken.originChain, swapToken.slug, _KoniTypes.ExtrinsicType.SWAP)]);
471
607
  const bnSwapFromTokenBalance = (0, _bignumber.default)(swapFromTokenBalance.value).plus(bnBridgeAmount);
472
608
  const bnSwapFeeTokenBalance = (0, _bignumber.default)(swapFeeTokenBalance.value);
473
- const swapStepValidation = this.validateSwapStepV2(swapToChain, swapToken, swapReceivingToken, swapFeeToken, bnSwapValue, bnSwapReceivingAmount, bnSwapFromTokenBalance, bnSwapFeeAmount, bnSwapFeeTokenBalance, params.recipient);
609
+ const swapStepValidation = this.validateSwapStepV2(swapToChain, swapToken, swapReceivingToken, swapFeeToken, bnSwapValue, bnSwapReceivingAmount, bnSwapFromTokenBalance, bnSwapFeeAmount, bnSwapFeeTokenBalance, swapMetadata.receiver);
474
610
  if (swapStepValidation.length > 0) {
475
611
  return swapStepValidation;
476
612
  }
613
+
614
+ // Bridge again
615
+ const transitStep = params.process.steps[transitIndex];
616
+ const transitMetadata = transitStep.metadata;
617
+ const transitTotalFee = params.process.totalFee[transitIndex];
618
+ const transitFee = (_transitTotalFee$feeC = transitTotalFee.feeComponent.find(fee => fee.feeType === _swap.SwapFeeType.NETWORK_FEE)) === null || _transitTotalFee$feeC === void 0 ? void 0 : _transitTotalFee$feeC.amount;
619
+ if (!transitMetadata || !transitMetadata.destinationTokenInfo || !transitMetadata.originTokenInfo || !transitMetadata.sendingValue || !transitMetadata.expectedReceive) {
620
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
621
+ }
622
+ if (!transitFee) {
623
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
624
+ }
625
+ const transitFromToken = transitMetadata.originTokenInfo;
626
+ const transitToToken = transitMetadata.destinationTokenInfo;
627
+ const fromTransitChain = this.chainService.getChainInfoByKey(transitFromToken.originChain);
628
+ const toTransitChain = this.chainService.getChainInfoByKey(transitToToken.originChain);
629
+ if (swapReceivingToken.slug !== transitFromToken.slug) {
630
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
631
+ }
632
+ if ((0, _xcmParser._isSnowBridgeXcm)(fromTransitChain, toTransitChain)) {
633
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.UNSUPPORTED)];
634
+ }
635
+ const bnTransitFeeAmount = (0, _bignumber.default)(transitFee);
636
+ const bnTransitAmount = new _bignumber.default(transitMetadata.sendingValue);
637
+ const transitToChainNativeToken = this.chainService.getNativeTokenInfo(transitToToken.originChain);
638
+ const transitSelectedFeeToken = this.chainService.getAssetBySlug(transitTotalFee.selectedFeeToken || transitTotalFee.defaultFeeToken);
639
+ const bnTransitDeliveryFee = (0, _bignumber.default)(0); // todo
640
+
641
+ const transitSender = (0, _utils4._reformatAddressWithChain)(transitMetadata.sender, this.chainService.getChainInfoByKey(transitFromToken.originChain));
642
+ const transitReceiver = (0, _utils4._reformatAddressWithChain)((_transitMetadata$rece = transitMetadata.receiver) !== null && _transitMetadata$rece !== void 0 ? _transitMetadata$rece : transitSender, this.chainService.getChainInfoByKey(transitToToken.originChain));
643
+ const [transitFromTokenBalance, transitFeeTokenBalance] = await Promise.all([this.balanceService.getTransferableBalance(transitSender, transitFromToken.originChain, transitFromToken.slug, _KoniTypes.ExtrinsicType.TRANSFER_XCM), this.balanceService.getTransferableBalance(transitSender, transitFromToken.originChain, transitSelectedFeeToken.slug, _KoniTypes.ExtrinsicType.TRANSFER_XCM)]);
644
+
645
+ // Native token balance has already accounted for ED aka strict mode
646
+ const bnTransitFromTokenBalance = new _bignumber.default(transitFromTokenBalance.value).plus(bnSwapReceivingAmount);
647
+ const bnTransitFeeTokenBalance = new _bignumber.default(transitFeeTokenBalance.value);
648
+ const transitStepValidation = await this.validateBridgeStep(transitReceiver, transitFromToken, transitToToken, transitSelectedFeeToken, transitToChainNativeToken, bnTransitAmount, bnTransitFromTokenBalance, bnTransitFeeAmount, bnTransitFeeTokenBalance, bnTransitDeliveryFee);
649
+ if (transitStepValidation.length > 0) {
650
+ return transitStepValidation;
651
+ }
477
652
  return [];
478
653
  }
479
654
  get name() {