@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
@@ -4,14 +4,10 @@
4
4
  import { SwapError } from '@subwallet/extension-base/background/errors/SwapError';
5
5
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
6
6
  import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
7
- import { XCM_MIN_AMOUNT_RATIO } from '@subwallet/extension-base/constants';
8
- import { _validateBalanceToSwapOnAssetHub, _validateSwapRecipient } from '@subwallet/extension-base/core/logic-validation/swap';
9
- import { createXcmExtrinsic } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
10
- import { _getChainNativeTokenSlug, _getTokenMinAmount, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
11
- import { DynamicSwapType } from '@subwallet/extension-base/services/swap-service/interface';
12
- import { FEE_RATE_MULTIPLIER, getSwapAlternativeAsset } from '@subwallet/extension-base/services/swap-service/utils';
13
- import { BasicTxErrorType, CommonStepType, SwapErrorType, SwapFeeType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types';
14
- import { getId } from '@subwallet/extension-base/utils/getId';
7
+ import { _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
8
+ import { DEFAULT_EXCESS_AMOUNT_WEIGHT, getAmountAfterSlippage } from '@subwallet/extension-base/services/swap-service/utils';
9
+ import { BasicTxErrorType, CommonStepType, DynamicSwapType, SwapErrorType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types';
10
+ import { _reformatAddressWithChain } from '@subwallet/extension-base/utils';
15
11
  import BigN from 'bignumber.js';
16
12
  import { SwapBaseHandler } from "../base-handler.js";
17
13
  import { AssetHubRouter } from "./router.js";
@@ -61,235 +57,70 @@ export class AssetHubSwapHandler {
61
57
  if (!chainState.active) {
62
58
  await this.chainService.enableChain(this.chain);
63
59
  }
64
- const substrateApi = this.chainService.getSubstrateApi(this.chain);
65
- await substrateApi.api.isReady;
66
60
  this.router = new AssetHubRouter(this.chain, this.chainService);
67
61
  this.isReady = true;
68
62
  }
69
- async getXcmStep(params) {
70
- const bnAmount = new BigN(params.request.fromAmount);
71
- const fromAsset = this.chainService.getAssetBySlug(params.request.pair.from);
72
- const fromAssetBalance = await this.balanceService.getTransferableBalance(params.request.address, fromAsset.originChain, fromAsset.slug);
73
- const bnFromAssetBalance = new BigN(fromAssetBalance.value);
74
- if (bnFromAssetBalance.gte(bnAmount)) {
75
- return undefined; // enough balance, no need to xcm
76
- }
77
-
78
- const alternativeAssetSlug = getSwapAlternativeAsset(params.request.pair);
79
- if (!alternativeAssetSlug) {
80
- return undefined;
81
- }
82
- const alternativeAsset = this.chainService.getAssetBySlug(alternativeAssetSlug);
83
- const alternativeAssetBalance = await this.balanceService.getTransferableBalance(params.request.address, alternativeAsset.originChain, alternativeAsset.slug);
84
- const bnAlternativeAssetBalance = new BigN(alternativeAssetBalance.value);
85
- if (bnAlternativeAssetBalance.lte(0)) {
86
- return undefined;
87
- }
88
- try {
89
- const alternativeChainInfo = this.chainService.getChainInfoByKey(alternativeAsset.originChain);
90
- const originalChainInfo = this.chainService.getChainInfoByKey(this.chain);
91
- const xcmOriginSubstrateApi = await this.chainService.getSubstrateApi(alternativeAsset.originChain).isReady;
92
- const id = getId();
93
- const feeInfo = await this.swapBaseHandler.feeService.subscribeChainFee(id, alternativeChainInfo.slug, 'substrate');
94
- const xcmTransfer = await createXcmExtrinsic({
95
- originTokenInfo: alternativeAsset,
96
- destinationTokenInfo: fromAsset,
97
- // Mock sending value to get payment info
98
- sendingValue: bnAmount.toString(),
99
- recipient: params.request.address,
100
- sender: params.request.address,
101
- feeInfo: feeInfo,
102
- substrateApi: xcmOriginSubstrateApi,
103
- destinationChain: originalChainInfo,
104
- originChain: alternativeChainInfo
105
- });
106
- const _xcmFeeInfo = await xcmTransfer.paymentInfo(params.request.address);
107
- const xcmFeeInfo = _xcmFeeInfo.toPrimitive();
108
- const fee = {
109
- feeComponent: [{
110
- feeType: SwapFeeType.NETWORK_FEE,
111
- amount: Math.round(xcmFeeInfo.partialFee * XCM_MIN_AMOUNT_RATIO).toString(),
112
- tokenSlug: _getChainNativeTokenSlug(alternativeChainInfo)
113
- }],
114
- defaultFeeToken: _getChainNativeTokenSlug(alternativeChainInfo),
115
- feeOptions: [_getChainNativeTokenSlug(alternativeChainInfo)]
116
- };
117
- let bnTransferAmount = bnAmount.minus(bnFromAssetBalance);
118
- if (_isNativeToken(alternativeAsset)) {
119
- const bnXcmFee = new BigN(fee.feeComponent[0].amount); // xcm fee is paid in native token but swap token is not always native token
120
-
121
- bnTransferAmount = bnTransferAmount.plus(bnXcmFee);
122
- }
123
- const step = {
124
- metadata: {
125
- sendingValue: bnTransferAmount.toString(),
126
- originTokenInfo: alternativeAsset,
127
- destinationTokenInfo: fromAsset
128
- },
129
- name: `Transfer ${alternativeAsset.symbol} from ${alternativeChainInfo.name}`,
130
- type: CommonStepType.XCM
131
- };
132
- return [step, fee];
133
- } catch (e) {
134
- console.error('Error creating xcm step', e);
135
- return undefined;
136
- }
137
- }
138
- async getSubmitStep(params) {
139
- if (params.selectedQuote) {
140
- const submitStep = {
141
- name: 'Swap',
142
- type: SwapStepType.SWAP
143
- };
144
- return Promise.resolve([submitStep, params.selectedQuote.feeInfo]);
145
- }
146
- return Promise.resolve(undefined);
147
- }
148
- async getXcmStepV2(params) {
149
- var _params$path$find;
150
- // todo: improve this function for Round 2
151
-
152
- const xcmPairInfo = (_params$path$find = params.path.find((step, i) => i === 0 && step.action === DynamicSwapType.BRIDGE)) === null || _params$path$find === void 0 ? void 0 : _params$path$find.pair;
153
- if (!xcmPairInfo) {
154
- return undefined;
155
- }
156
- const fromTokenInfo = this.chainService.getAssetBySlug(xcmPairInfo.from);
157
- const toTokenInfo = this.chainService.getAssetBySlug(xcmPairInfo.to);
158
- const fromChainInfo = this.chainService.getChainInfoByKey(fromTokenInfo.originChain);
159
- const toChainInfo = this.chainService.getChainInfoByKey(toTokenInfo.originChain);
160
- const substrateApi = await this.chainService.getSubstrateApi(fromTokenInfo.originChain).isReady;
161
- if (!fromChainInfo || !toChainInfo || !fromChainInfo || !toChainInfo) {
162
- throw Error('Token and chain not found');
163
- }
164
- try {
165
- const id = getId();
166
- const [feeInfo, toTokenBalance] = await Promise.all([this.swapBaseHandler.feeService.subscribeChainFee(id, fromTokenInfo.originChain, 'substrate'), this.balanceService.getTotalBalance(params.request.address, toTokenInfo.originChain, toTokenInfo.slug, ExtrinsicType.TRANSFER_BALANCE)]);
167
- const xcmTransfer = await createXcmExtrinsic({
168
- originTokenInfo: fromTokenInfo,
169
- destinationTokenInfo: toTokenInfo,
170
- // Mock sending value to get payment info
171
- sendingValue: params.request.fromAmount,
172
- recipient: params.request.address,
173
- substrateApi: substrateApi,
174
- sender: params.request.address,
175
- originChain: fromChainInfo,
176
- destinationChain: toChainInfo,
177
- feeInfo
178
- });
179
- const _xcmFeeInfo = await xcmTransfer.paymentInfo(params.request.address);
180
- const xcmFeeInfo = _xcmFeeInfo.toPrimitive();
181
- const fee = {
182
- feeComponent: [{
183
- feeType: SwapFeeType.NETWORK_FEE,
184
- amount: Math.ceil(xcmFeeInfo.partialFee * FEE_RATE_MULTIPLIER.high).toString(),
185
- tokenSlug: _getChainNativeTokenSlug(fromChainInfo)
186
- }],
187
- defaultFeeToken: _getChainNativeTokenSlug(fromChainInfo),
188
- feeOptions: [_getChainNativeTokenSlug(fromChainInfo)]
189
- };
190
- let bnTransferAmount = new BigN(params.request.fromAmount);
191
- if (_isNativeToken(fromTokenInfo)) {
192
- // xcm fee is paid in native token but swap token is not always native token
193
- // add amount of fee into sending value to ensure has enough token to swap
194
- const bnXcmFee = new BigN(fee.feeComponent[0].amount);
195
- bnTransferAmount = bnTransferAmount.plus(bnXcmFee);
196
- } else {
197
- bnTransferAmount = bnTransferAmount.plus(BigN(_getTokenMinAmount(toTokenInfo)).multipliedBy(FEE_RATE_MULTIPLIER.medium));
198
- }
199
- if (BigN(toTokenBalance.value).lte(0)) {
200
- bnTransferAmount = bnTransferAmount.plus(_getTokenMinAmount(toTokenInfo));
201
- }
202
- const step = {
203
- metadata: {
204
- sendingValue: bnTransferAmount.toString(),
205
- originTokenInfo: fromTokenInfo,
206
- destinationTokenInfo: toTokenInfo
207
- },
208
- name: `Transfer ${fromTokenInfo.symbol} from ${fromChainInfo.name}`,
209
- type: CommonStepType.XCM
210
- };
211
- return [step, fee];
212
- } catch (e) {
213
- console.error('Error creating xcm step', e);
214
- return undefined;
215
- }
216
- }
217
- async getSwapStepV2(params) {
218
- var _params$path$find2;
219
- const swapPairInfo = (_params$path$find2 = params.path.find(step => step.action === DynamicSwapType.SWAP)) === null || _params$path$find2 === void 0 ? void 0 : _params$path$find2.pair;
220
- if (!swapPairInfo) {
63
+ async getSubmitStep(params, stepIndex) {
64
+ const {
65
+ path,
66
+ request: {
67
+ fromAmount
68
+ },
69
+ selectedQuote
70
+ } = params;
71
+ const stepData = path[stepIndex];
72
+ if (stepData.action !== DynamicSwapType.SWAP) {
221
73
  return Promise.resolve(undefined);
222
74
  }
223
- if (params.selectedQuote) {
224
- const submitStep = {
225
- name: 'Swap',
226
- type: SwapStepType.SWAP,
227
- metadata: {
228
- sendingValue: params.request.fromAmount.toString(),
229
- originTokenInfo: this.chainService.getAssetBySlug(swapPairInfo.from),
230
- destinationTokenInfo: this.chainService.getAssetBySlug(swapPairInfo.to)
231
- }
232
- };
233
- return Promise.resolve([submitStep, params.selectedQuote.feeInfo]);
75
+ const swapPairInfo = stepData.pair;
76
+ if (!swapPairInfo || !selectedQuote) {
77
+ return Promise.resolve(undefined);
234
78
  }
235
- return Promise.resolve(undefined);
236
- }
237
- generateOptimalProcess(params) {
238
- return this.swapBaseHandler.generateOptimalProcess(params, [this.getXcmStep.bind(this), this.getSubmitStep.bind(this)]);
79
+ const originTokenInfo = this.chainService.getAssetBySlug(swapPairInfo.from);
80
+ const destinationTokenInfo = this.chainService.getAssetBySlug(swapPairInfo.to);
81
+ const originChain = this.chainService.getChainInfoByKey(originTokenInfo.originChain);
82
+ const destinationChain = this.chainService.getChainInfoByKey(destinationTokenInfo.originChain);
83
+ const actionList = JSON.stringify(path.map(step => step.action));
84
+ const xcmSwapXcm = actionList === JSON.stringify([DynamicSwapType.BRIDGE, DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
85
+ const swapXcm = actionList === JSON.stringify([DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
86
+ const needModifyData = swapXcm || xcmSwapXcm;
87
+ let bnSendingValue = BigN(fromAmount);
88
+ let bnExpectedReceive = BigN(selectedQuote.toAmount);
89
+ const sender = _reformatAddressWithChain(params.request.address, originChain);
90
+ let receiver = _reformatAddressWithChain(params.request.recipient || params.request.address, destinationChain);
91
+ if (needModifyData) {
92
+ bnSendingValue = bnSendingValue.multipliedBy(DEFAULT_EXCESS_AMOUNT_WEIGHT);
93
+ bnExpectedReceive = bnExpectedReceive.multipliedBy(DEFAULT_EXCESS_AMOUNT_WEIGHT);
94
+ receiver = _reformatAddressWithChain(params.request.address, destinationChain);
95
+ }
96
+ const submitStep = {
97
+ name: 'Swap',
98
+ type: SwapStepType.SWAP,
99
+ // @ts-ignore
100
+ metadata: {
101
+ sendingValue: bnSendingValue.toFixed(0, 1),
102
+ expectedReceive: bnExpectedReceive.toFixed(0, 1),
103
+ originTokenInfo,
104
+ destinationTokenInfo,
105
+ sender,
106
+ receiver,
107
+ version: 2
108
+ }
109
+ };
110
+ return Promise.resolve([submitStep, selectedQuote.feeInfo]);
239
111
  }
240
112
  generateOptimalProcessV2(params) {
241
113
  const stepFuncList = params.path.map(step => {
242
- if (step.action === DynamicSwapType.BRIDGE) {
243
- return this.getXcmStepV2.bind(this);
244
- }
245
114
  if (step.action === DynamicSwapType.SWAP) {
246
- return this.getSwapStepV2.bind(this);
115
+ return this.getSubmitStep.bind(this);
116
+ }
117
+ if (step.action === DynamicSwapType.BRIDGE) {
118
+ return this.swapBaseHandler.getBridgeStep.bind(this.swapBaseHandler);
247
119
  }
248
120
  throw new Error(`Error generating optimal process: Action ${step.action} is not supported`);
249
121
  });
250
122
  return this.swapBaseHandler.generateOptimalProcessV2(params, stepFuncList);
251
123
  }
252
- async handleXcmStep(params) {
253
- const briefXcmStep = params.process.steps[params.currentStep].metadata;
254
- if (!briefXcmStep || !briefXcmStep.originTokenInfo || !briefXcmStep.destinationTokenInfo || !briefXcmStep.sendingValue) {
255
- throw new Error('XCM metadata error');
256
- }
257
- const originAsset = briefXcmStep.originTokenInfo;
258
- const destinationAsset = briefXcmStep.destinationTokenInfo;
259
- const originChain = this.chainService.getChainInfoByKey(originAsset.originChain);
260
- const destinationChain = this.chainService.getChainInfoByKey(destinationAsset.originChain);
261
- const substrateApi = this.chainService.getSubstrateApi(originAsset.originChain);
262
- const chainApi = await substrateApi.isReady;
263
- const feeInfo = await this.swapBaseHandler.feeService.subscribeChainFee(getId(), originAsset.originChain, 'substrate');
264
- const xcmTransfer = await createXcmExtrinsic({
265
- originTokenInfo: originAsset,
266
- destinationTokenInfo: destinationAsset,
267
- sendingValue: briefXcmStep.sendingValue,
268
- recipient: params.address,
269
- substrateApi: chainApi,
270
- sender: params.address,
271
- destinationChain,
272
- originChain,
273
- feeInfo
274
- });
275
- const xcmData = {
276
- originNetworkKey: originAsset.originChain,
277
- destinationNetworkKey: destinationAsset.originChain,
278
- from: params.address,
279
- to: params.address,
280
- value: briefXcmStep.sendingValue,
281
- tokenSlug: originAsset.slug,
282
- showExtraWarning: true
283
- };
284
- return {
285
- txChain: originAsset.originChain,
286
- extrinsic: xcmTransfer,
287
- transferNativeAmount: _isNativeToken(originAsset) ? briefXcmStep.sendingValue : '0',
288
- extrinsicType: ExtrinsicType.TRANSFER_XCM,
289
- chainType: ChainType.SUBSTRATE,
290
- txData: xcmData
291
- };
292
- }
293
124
  async handleSubmitStep(params) {
294
125
  var _this$router;
295
126
  const metadata = params.process.steps[params.currentStep].metadata;
@@ -305,17 +136,11 @@ export class AssetHubSwapHandler {
305
136
  process: params.process
306
137
  };
307
138
  const paths = params.quote.route.path.map(slug => this.chainService.getAssetBySlug(slug));
308
- const {
309
- fromAmount,
310
- toAmount
311
- } = params.quote;
312
-
313
- // todo: move to gen process
314
- const minReceive = new BigN(1 - params.slippage).times(toAmount).integerValue(BigN.ROUND_DOWN);
315
- if (!params.address || !paths || !fromAmount || !minReceive) {
139
+ const minReceive = BigN(getAmountAfterSlippage(metadata.expectedReceive, params.slippage));
140
+ if (!params.address || !paths || !minReceive) {
316
141
  throw new SwapError(SwapErrorType.UNKNOWN);
317
142
  }
318
- const extrinsic = await ((_this$router = this.router) === null || _this$router === void 0 ? void 0 : _this$router.buildSwapExtrinsic(paths, params.address, fromAmount, minReceive.toString()));
143
+ const extrinsic = await ((_this$router = this.router) === null || _this$router === void 0 ? void 0 : _this$router.buildSwapExtrinsic(paths, params.address, metadata.sendingValue, minReceive.toString()));
319
144
  return {
320
145
  txChain: fromAsset.originChain,
321
146
  txData,
@@ -334,90 +159,13 @@ export class AssetHubSwapHandler {
334
159
  const type = process.steps[currentStep].type;
335
160
  switch (type) {
336
161
  case CommonStepType.XCM:
337
- return this.handleXcmStep(params);
162
+ return this.swapBaseHandler.handleBridgeStep(params);
338
163
  case SwapStepType.SWAP:
339
164
  return this.handleSubmitStep(params);
340
165
  default:
341
166
  return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
342
167
  }
343
168
  }
344
- async validateSwapStep(params, isXcmOk, stepIndex) {
345
- // check swap quote timestamp
346
- // check balance to pay transaction fee
347
- // check balance against spending amount
348
- if (!params.selectedQuote) {
349
- return Promise.resolve([new TransactionError(BasicTxErrorType.INTERNAL_ERROR)]);
350
- }
351
- const selectedQuote = params.selectedQuote;
352
- const currentTimestamp = +Date.now();
353
- if (selectedQuote.aliveUntil <= currentTimestamp) {
354
- return Promise.resolve([new TransactionError(SwapErrorType.QUOTE_TIMEOUT)]);
355
- }
356
- const stepFee = params.process.totalFee[stepIndex].feeComponent;
357
- const networkFee = stepFee.find(fee => fee.feeType === SwapFeeType.NETWORK_FEE);
358
- if (!networkFee) {
359
- return Promise.resolve([new TransactionError(BasicTxErrorType.INTERNAL_ERROR)]);
360
- }
361
- const fromAsset = this.chainService.getAssetBySlug(params.selectedQuote.pair.from);
362
- const feeTokenInfo = this.chainService.getAssetBySlug(networkFee.tokenSlug);
363
- const feeTokenChain = this.chainService.getChainInfoByKey(feeTokenInfo.originChain);
364
- const {
365
- fromAmount,
366
- minSwap
367
- } = params.selectedQuote;
368
- const [feeTokenBalance, fromAssetBalance] = await Promise.all([this.balanceService.getTransferableBalance(params.address, feeTokenInfo.originChain, feeTokenInfo.slug), this.balanceService.getTransferableBalance(params.address, fromAsset.originChain, fromAsset.slug)]);
369
- const balanceError = _validateBalanceToSwapOnAssetHub(fromAsset, feeTokenInfo, feeTokenChain, networkFee.amount, fromAssetBalance.value, feeTokenBalance.value, fromAmount, isXcmOk, minSwap);
370
- if (balanceError) {
371
- return Promise.resolve([balanceError]);
372
- }
373
- if (!params.recipient) {
374
- return Promise.resolve([]);
375
- }
376
- const toAsset = this.chainService.getAssetBySlug(params.selectedQuote.pair.to);
377
- const toAssetChain = this.chainService.getChainInfoByKey(toAsset.originChain);
378
- const recipientError = _validateSwapRecipient(toAssetChain, params.recipient);
379
- if (recipientError) {
380
- return Promise.resolve([recipientError]);
381
- }
382
- return Promise.resolve([]);
383
- }
384
- async validateSwapProcess(params) {
385
- const amount = params.selectedQuote.fromAmount;
386
- const bnAmount = new BigN(amount);
387
- if (bnAmount.lte(0)) {
388
- return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')];
389
- }
390
- const swapStep = params.process.steps.find(item => item.type === SwapStepType.SWAP);
391
- if (!swapStep) {
392
- return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR, 'Swap step not found')];
393
- }
394
- let isXcmOk = false;
395
- const currentStep = params.currentStep;
396
- for (const [index, step] of params.process.steps.entries()) {
397
- if (currentStep > index) {
398
- continue;
399
- }
400
- const getErrors = async () => {
401
- switch (step.type) {
402
- case CommonStepType.DEFAULT:
403
- return Promise.resolve([]);
404
- case CommonStepType.XCM:
405
- return this.swapBaseHandler.validateXcmStepV2(params, index);
406
- case SwapStepType.SWAP:
407
- return this.validateSwapStep(params, isXcmOk, index);
408
- default:
409
- return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
410
- }
411
- };
412
- const errors = await getErrors();
413
- if (errors.length) {
414
- return errors;
415
- } else if (step.type === CommonStepType.XCM) {
416
- isXcmOk = true;
417
- }
418
- }
419
- return [];
420
- }
421
169
  async validateSwapProcessV2(params) {
422
170
  // todo: recheck address and recipient format in params
423
171
  const {
@@ -430,24 +178,23 @@ export class AssetHubSwapHandler {
430
178
  if (BigN(selectedQuote.fromAmount).lte(0)) {
431
179
  return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')];
432
180
  }
433
- const actionList = process.steps.map(step => step.type);
434
- const [firstStep, secondStep, thirdStep, fourthStep, fifthStep] = actionList;
435
- const swap = firstStep === CommonStepType.DEFAULT && secondStep === SwapStepType.SWAP && !thirdStep;
436
- const swapXcm = firstStep === CommonStepType.DEFAULT && secondStep === SwapStepType.SWAP && thirdStep === CommonStepType.XCM && !fourthStep;
437
- const xcmSwap = firstStep === CommonStepType.DEFAULT && secondStep === CommonStepType.XCM && thirdStep === SwapStepType.SWAP && !fourthStep;
438
- const xcmSwapXcm = firstStep === CommonStepType.DEFAULT && secondStep === CommonStepType.XCM && thirdStep === SwapStepType.SWAP && fourthStep === CommonStepType.XCM && !fifthStep;
181
+ const actionList = JSON.stringify(process.path.map(step => step.action));
182
+ const swap = actionList === JSON.stringify([DynamicSwapType.SWAP]);
183
+ const swapXcm = actionList === JSON.stringify([DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
184
+ const xcmSwap = actionList === JSON.stringify([DynamicSwapType.BRIDGE, DynamicSwapType.SWAP]);
185
+ const xcmSwapXcm = actionList === JSON.stringify([DynamicSwapType.BRIDGE, DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
439
186
  if (swap) {
440
187
  return this.swapBaseHandler.validateSwapOnlyProcess(params, 1); // todo: create interface for input request
441
188
  }
442
189
 
443
190
  if (swapXcm) {
444
- return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
191
+ return this.swapBaseHandler.validateSwapXcmProcess(params, 1, 2);
445
192
  }
446
193
  if (xcmSwap) {
447
194
  return this.swapBaseHandler.validateXcmSwapProcess(params, 2, 1);
448
195
  }
449
196
  if (xcmSwapXcm) {
450
- return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
197
+ return this.swapBaseHandler.validateXcmSwapXcmProcess(params, 2, 1, 3);
451
198
  }
452
199
  return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
453
200
  }
@@ -4,13 +4,11 @@ import { ChainService } from '@subwallet/extension-base/services/chain-service';
4
4
  import FeeService from '@subwallet/extension-base/services/fee-service/service';
5
5
  import { GenSwapStepFuncV2, OptimalSwapPathParamsV2 } from '@subwallet/extension-base/types';
6
6
  import { BaseStepDetail, CommonOptimalSwapPath, CommonStepFeeInfo } from '@subwallet/extension-base/types/service-base';
7
- import { GenSwapStepFunc, OptimalSwapPathParams, SwapProvider, SwapProviderId, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types/swap';
7
+ import { SwapProvider, SwapProviderId, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types/swap';
8
8
  export interface SwapBaseInterface {
9
9
  providerSlug: SwapProviderId;
10
- generateOptimalProcess: (params: OptimalSwapPathParams) => Promise<CommonOptimalSwapPath>;
11
10
  generateOptimalProcessV2: (params: OptimalSwapPathParamsV2) => Promise<CommonOptimalSwapPath>;
12
- getSubmitStep: (params: OptimalSwapPathParams) => Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
13
- validateSwapProcess: (params: ValidateSwapProcessParams) => Promise<TransactionError[]>;
11
+ getSubmitStep: (params: OptimalSwapPathParamsV2, stepIndex: number) => Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
14
12
  validateSwapProcessV2: (params: ValidateSwapProcessParams) => Promise<TransactionError[]>;
15
13
  handleSwapProcess: (params: SwapSubmitParams) => Promise<SwapSubmitStepData>;
16
14
  handleSubmitStep: (params: SwapSubmitParams) => Promise<SwapSubmitStepData>;
@@ -31,17 +29,16 @@ export declare class SwapBaseHandler {
31
29
  balanceService: BalanceService;
32
30
  feeService: FeeService;
33
31
  constructor({ balanceService, chainService, feeService, providerName, providerSlug }: SwapBaseHandlerInitParams);
34
- generateOptimalProcess(params: OptimalSwapPathParams, genStepFuncList: GenSwapStepFunc[]): Promise<CommonOptimalSwapPath>;
35
32
  generateOptimalProcessV2(params: OptimalSwapPathParamsV2, genStepFuncList: GenSwapStepFuncV2[]): Promise<CommonOptimalSwapPath>;
36
- validateXcmStep(params: ValidateSwapProcessParams, stepIndex: number): Promise<TransactionError[]>;
37
- validateXcmStepV2(params: ValidateSwapProcessParams, stepIndex: number): Promise<TransactionError[]>;
38
- validateTokenApproveStep(params: ValidateSwapProcessParams, stepIndex: number): Promise<TransactionError[]>;
33
+ getBridgeStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
34
+ handleBridgeStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
39
35
  validateSetFeeTokenStep(params: ValidateSwapProcessParams, stepIndex: number): Promise<TransactionError[]>;
40
- validateSwapStep(params: ValidateSwapProcessParams, isXcmOk: boolean, stepIndex: number): Promise<TransactionError[]>;
41
36
  private validateBridgeStep;
42
37
  private validateSwapStepV2;
43
38
  validateSwapOnlyProcess(params: ValidateSwapProcessParams, swapIndex: number): Promise<TransactionError[]>;
44
39
  validateXcmSwapProcess(params: ValidateSwapProcessParams, swapIndex: number, xcmIndex: number): Promise<TransactionError[]>;
40
+ validateSwapXcmProcess(params: ValidateSwapProcessParams, swapIndex: number, xcmIndex: number): Promise<TransactionError[]>;
41
+ validateXcmSwapXcmProcess(params: ValidateSwapProcessParams, swapIndex: number, xcmIndex: number, transitIndex: number): Promise<TransactionError[]>;
45
42
  get name(): string;
46
43
  get slug(): string;
47
44
  get providerInfo(): SwapProvider;