@subwallet/extension-base 1.3.31-1 → 1.3.32-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 (127) hide show
  1. package/background/KoniTypes.d.ts +70 -3
  2. package/background/KoniTypes.js +14 -0
  3. package/background/errors/CardanoProviderError.d.ts +6 -0
  4. package/background/errors/CardanoProviderError.js +61 -0
  5. package/background/types.d.ts +2 -2
  6. package/cjs/background/KoniTypes.js +16 -1
  7. package/cjs/background/errors/CardanoProviderError.js +67 -0
  8. package/cjs/constants/index.js +4 -1
  9. package/cjs/core/logic-validation/request.js +50 -3
  10. package/cjs/koni/api/contract-handler/evm/web3.js +21 -0
  11. package/cjs/koni/api/staking/bonding/utils.js +24 -3
  12. package/cjs/koni/background/handlers/Extension.js +115 -107
  13. package/cjs/koni/background/handlers/State.js +228 -5
  14. package/cjs/koni/background/handlers/Tabs.js +277 -55
  15. package/cjs/packageInfo.js +1 -1
  16. package/cjs/page/cardano/cips/cip30.js +63 -0
  17. package/cjs/page/cardano/cips/index.js +20 -0
  18. package/cjs/page/cardano/index.js +41 -0
  19. package/cjs/page/{SubWalleEvmProvider.js → evm/index.js} +2 -2
  20. package/cjs/page/index.js +9 -4
  21. package/cjs/services/balance-service/transfer/xcm/acrossBridge/index.js +6 -2
  22. package/cjs/services/balance-service/transfer/xcm/index.js +2 -0
  23. package/cjs/services/chain-service/handler/CardanoApi.js +33 -0
  24. package/cjs/services/chain-service/index.js +31 -0
  25. package/cjs/services/chain-service/utils/patch.js +1 -1
  26. package/cjs/services/earning-service/handlers/liquid-staking/stella-swap.js +3 -3
  27. package/cjs/services/earning-service/handlers/native-staking/dtao.js +2 -2
  28. package/cjs/services/earning-service/handlers/native-staking/mythos.js +42 -8
  29. package/cjs/services/earning-service/handlers/native-staking/relay-chain.js +1 -1
  30. package/cjs/services/earning-service/handlers/native-staking/tao.js +13 -13
  31. package/cjs/services/earning-service/handlers/nomination-pool/index.js +1 -1
  32. package/cjs/services/migration-service/scripts/MigrateAuthUrls.js +1 -1
  33. package/cjs/services/request-service/constants.js +3 -1
  34. package/cjs/services/request-service/handler/AuthRequestHandler.js +38 -5
  35. package/cjs/services/request-service/handler/CardanoRequestHandler.js +45 -3
  36. package/cjs/services/request-service/helper/index.js +419 -1
  37. package/cjs/services/swap-service/handler/asset-hub/handler.js +1 -1
  38. package/cjs/services/swap-service/handler/base-handler.js +81 -21
  39. package/cjs/services/swap-service/handler/hydradx-handler.js +1 -1
  40. package/cjs/services/swap-service/handler/uniswap-handler.js +274 -45
  41. package/cjs/services/swap-service/index.js +33 -11
  42. package/cjs/services/swap-service/utils.js +15 -2
  43. package/cjs/utils/auth.js +2 -1
  44. package/cjs/utils/cardano.js +20 -0
  45. package/cjs/utils/index.js +4 -4
  46. package/constants/index.d.ts +1 -0
  47. package/constants/index.js +1 -0
  48. package/core/logic-validation/request.d.ts +6 -2
  49. package/core/logic-validation/request.js +51 -5
  50. package/koni/api/contract-handler/evm/web3.d.ts +2 -0
  51. package/koni/api/contract-handler/evm/web3.js +19 -0
  52. package/koni/api/staking/bonding/utils.d.ts +2 -1
  53. package/koni/api/staking/bonding/utils.js +23 -3
  54. package/koni/background/handlers/Extension.js +7 -2
  55. package/koni/background/handlers/State.d.ts +6 -1
  56. package/koni/background/handlers/State.js +223 -4
  57. package/koni/background/handlers/Tabs.d.ts +11 -1
  58. package/koni/background/handlers/Tabs.js +242 -19
  59. package/package.json +62 -42
  60. package/packageInfo.js +1 -1
  61. package/page/cardano/cips/cip30.d.ts +22 -0
  62. package/page/cardano/cips/cip30.js +55 -0
  63. package/page/cardano/cips/index.d.ts +3 -0
  64. package/page/cardano/cips/index.js +7 -0
  65. package/page/cardano/index.d.ts +13 -0
  66. package/page/cardano/index.js +34 -0
  67. package/page/{SubWalleEvmProvider.d.ts → evm/index.d.ts} +3 -2
  68. package/page/{SubWalleEvmProvider.js → evm/index.js} +1 -1
  69. package/page/index.d.ts +3 -2
  70. package/page/index.js +6 -2
  71. package/page/{Accounts.d.ts → substrate/Accounts.d.ts} +1 -1
  72. package/page/{Metadata.d.ts → substrate/Metadata.d.ts} +1 -1
  73. package/page/{PostMessageProvider.d.ts → substrate/PostMessageProvider.d.ts} +1 -1
  74. package/page/{Signer.d.ts → substrate/Signer.d.ts} +1 -1
  75. package/page/{Injected.d.ts → substrate/index.d.ts} +1 -1
  76. package/services/balance-service/helpers/subscribe/cardano/types.d.ts +14 -0
  77. package/services/balance-service/transfer/xcm/acrossBridge/index.d.ts +4 -0
  78. package/services/balance-service/transfer/xcm/acrossBridge/index.js +4 -1
  79. package/services/balance-service/transfer/xcm/index.js +2 -0
  80. package/services/chain-service/handler/CardanoApi.d.ts +3 -1
  81. package/services/chain-service/handler/CardanoApi.js +33 -0
  82. package/services/chain-service/index.d.ts +5 -1
  83. package/services/chain-service/index.js +32 -1
  84. package/services/chain-service/utils/patch.js +1 -1
  85. package/services/earning-service/handlers/liquid-staking/stella-swap.js +3 -3
  86. package/services/earning-service/handlers/native-staking/dtao.js +2 -2
  87. package/services/earning-service/handlers/native-staking/mythos.js +42 -8
  88. package/services/earning-service/handlers/native-staking/relay-chain.js +1 -1
  89. package/services/earning-service/handlers/native-staking/tao.js +14 -14
  90. package/services/earning-service/handlers/nomination-pool/index.js +1 -1
  91. package/services/migration-service/scripts/MigrateAuthUrls.js +1 -1
  92. package/services/request-service/constants.js +3 -1
  93. package/services/request-service/handler/AuthRequestHandler.js +40 -7
  94. package/services/request-service/handler/CardanoRequestHandler.d.ts +2 -0
  95. package/services/request-service/handler/CardanoRequestHandler.js +45 -3
  96. package/services/request-service/helper/index.d.ts +54 -0
  97. package/services/request-service/helper/index.js +406 -1
  98. package/services/request-service/types.d.ts +3 -1
  99. package/services/swap-service/handler/asset-hub/handler.js +1 -1
  100. package/services/swap-service/handler/base-handler.d.ts +3 -1
  101. package/services/swap-service/handler/base-handler.js +82 -22
  102. package/services/swap-service/handler/hydradx-handler.js +1 -1
  103. package/services/swap-service/handler/uniswap-handler.d.ts +5 -0
  104. package/services/swap-service/handler/uniswap-handler.js +275 -46
  105. package/services/swap-service/index.js +34 -12
  106. package/services/swap-service/utils.d.ts +3 -2
  107. package/services/swap-service/utils.js +13 -1
  108. package/types/swap/index.d.ts +1 -0
  109. package/types/transaction/process.d.ts +2 -0
  110. package/utils/auth.js +3 -2
  111. package/utils/cardano.d.ts +2 -0
  112. package/utils/cardano.js +12 -0
  113. package/utils/index.d.ts +1 -1
  114. package/utils/index.js +1 -1
  115. package/cjs/utils/canDerive.js +0 -12
  116. package/utils/canDerive.d.ts +0 -2
  117. package/utils/canDerive.js +0 -6
  118. /package/cjs/page/{Accounts.js → substrate/Accounts.js} +0 -0
  119. /package/cjs/page/{Metadata.js → substrate/Metadata.js} +0 -0
  120. /package/cjs/page/{PostMessageProvider.js → substrate/PostMessageProvider.js} +0 -0
  121. /package/cjs/page/{Signer.js → substrate/Signer.js} +0 -0
  122. /package/cjs/page/{Injected.js → substrate/index.js} +0 -0
  123. /package/page/{Accounts.js → substrate/Accounts.js} +0 -0
  124. /package/page/{Metadata.js → substrate/Metadata.js} +0 -0
  125. /package/page/{PostMessageProvider.js → substrate/PostMessageProvider.js} +0 -0
  126. /package/page/{Signer.js → substrate/Signer.js} +0 -0
  127. /package/page/{Injected.js → substrate/index.js} +0 -0
@@ -12,6 +12,7 @@ var _systemPallet = require("@subwallet/extension-base/core/substrate/system-pal
12
12
  var _xcmParser = require("@subwallet/extension-base/core/substrate/xcm-parser");
13
13
  var _utils = require("@subwallet/extension-base/core/utils");
14
14
  var _xcm = require("@subwallet/extension-base/services/balance-service/transfer/xcm");
15
+ var _acrossBridge = require("@subwallet/extension-base/services/balance-service/transfer/xcm/acrossBridge");
15
16
  var _utils2 = require("@subwallet/extension-base/services/chain-service/utils");
16
17
  var _utils3 = require("@subwallet/extension-base/services/swap-service/utils");
17
18
  var _types = require("@subwallet/extension-base/types");
@@ -22,6 +23,7 @@ var _getId = require("@subwallet/extension-base/utils/getId");
22
23
  var _bignumber = _interopRequireDefault(require("bignumber.js"));
23
24
  var _i18next = require("i18next");
24
25
  var _utilCrypto = require("@polkadot/util-crypto");
26
+ var _xcm2 = require("../../balance-service/transfer/xcm");
25
27
  // Copyright 2019-2022 @subwallet/extension-base
26
28
  // SPDX-License-Identifier: Apache-2.0
27
29
 
@@ -59,6 +61,10 @@ class SwapBaseHandler {
59
61
  }
60
62
  return result;
61
63
  } catch (e) {
64
+ const errorMessage = e.message;
65
+ if (errorMessage.toLowerCase().startsWith(_acrossBridge.AcrossErrorMsg.AMOUNT_TOO_LOW) || errorMessage.toLowerCase().startsWith(_acrossBridge.AcrossErrorMsg.AMOUNT_TOO_HIGH)) {
66
+ throw new Error(errorMessage);
67
+ }
62
68
  return result;
63
69
  }
64
70
  }
@@ -192,7 +198,16 @@ class SwapBaseHandler {
192
198
  return undefined;
193
199
  }
194
200
  }
195
- async handleBridgeStep(params) {
201
+ async handleBridgeStep(params, type) {
202
+ if (type === 'xcm') {
203
+ return this.handleBridgeSubstrate(params);
204
+ }
205
+ if (type === 'across') {
206
+ return this.handleBridgeAcross(params);
207
+ }
208
+ throw Error('Not support this type');
209
+ }
210
+ async handleBridgeSubstrate(params) {
196
211
  const briefXcmStep = params.process.steps[params.currentStep].metadata;
197
212
  if (!briefXcmStep || !briefXcmStep.originTokenInfo || !briefXcmStep.destinationTokenInfo || !briefXcmStep.sendingValue) {
198
213
  throw new Error('XCM metadata error');
@@ -237,6 +252,49 @@ class SwapBaseHandler {
237
252
  txData: xcmData
238
253
  };
239
254
  }
255
+ async handleBridgeAcross(params) {
256
+ const bridgeStep = params.process.steps[params.currentStep].metadata;
257
+ if (!bridgeStep || !bridgeStep.originTokenInfo || !bridgeStep.destinationTokenInfo || !bridgeStep.sendingValue) {
258
+ throw new Error('Bridge metadata error');
259
+ }
260
+ const originTokenInfo = bridgeStep.originTokenInfo;
261
+ const destinationTokenInfo = bridgeStep.destinationTokenInfo;
262
+ const originChain = this.chainService.getChainInfoByKey(originTokenInfo.originChain);
263
+ const destinationChain = this.chainService.getChainInfoByKey(destinationTokenInfo.originChain);
264
+ const evmApi = await this.chainService.getEvmApi(originTokenInfo.originChain).isReady;
265
+ const feeInfo = await this.feeService.subscribeChainFee((0, _getId.getId)(), originTokenInfo.originChain, 'evm');
266
+ const sendingValue = bridgeStep.sendingValue;
267
+ const sender = bridgeStep.sender;
268
+ const recipient = bridgeStep.receiver;
269
+ const tx = await (0, _xcm2.createAcrossBridgeExtrinsic)({
270
+ originTokenInfo,
271
+ destinationTokenInfo,
272
+ originChain,
273
+ destinationChain,
274
+ evmApi,
275
+ feeInfo,
276
+ sendingValue,
277
+ sender,
278
+ recipient
279
+ });
280
+ const txData = {
281
+ originNetworkKey: originTokenInfo.originChain,
282
+ destinationNetworkKey: destinationTokenInfo.originChain,
283
+ from: sender,
284
+ to: recipient,
285
+ value: sendingValue,
286
+ tokenSlug: originTokenInfo.slug,
287
+ showExtraWarning: true
288
+ };
289
+ return {
290
+ txChain: originTokenInfo.originChain,
291
+ extrinsic: tx,
292
+ transferNativeAmount: (0, _utils2._isNativeToken)(originTokenInfo) ? bridgeStep.sendingValue : '0',
293
+ extrinsicType: _KoniTypes.ExtrinsicType.TRANSFER_XCM,
294
+ chainType: _KoniTypes.ChainType.EVM,
295
+ txData: txData
296
+ };
297
+ }
240
298
  async validateSetFeeTokenStep(params, stepIndex) {
241
299
  if (!params.selectedQuote) {
242
300
  return Promise.resolve([new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)]);
@@ -269,27 +327,29 @@ class SwapBaseHandler {
269
327
  }
270
328
  }))];
271
329
  }
330
+ const isAcrossBridge = (0, _acrossBridge._isAcrossChainBridge)((0, _utils2._getAssetOriginChain)(fromToken), (0, _utils2._getAssetOriginChain)(toToken));
331
+ if (!isAcrossBridge) {
332
+ // By here, we know that the user is receiving a valid amount of toToken
333
+ const toChainApi = this.chainService.getSubstrateApi(toToken.originChain);
334
+ const sufficientChain = this.chainService.value.sufficientChains;
335
+ if (!toChainApi) {
336
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
337
+ }
272
338
 
273
- // By here, we know that the user is receiving a valid amount of toToken
274
- const toChainApi = this.chainService.getSubstrateApi(toToken.originChain);
275
- const sufficientChain = this.chainService.value.sufficientChains;
276
- if (!toChainApi) {
277
- return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
278
- }
279
-
280
- // Only need to check if account is alive with the receiving toToken
281
- const isToTokenSufficient = await (0, _utils._isSufficientToken)(toToken, toChainApi, sufficientChain);
282
- if (!isToTokenSufficient && !(0, _utils2._isNativeToken)(toToken)) {
283
- // sending token cannot keep account alive, must check with native token
284
- const toChainNativeTokenBalance = await this.balanceService.getTotalBalance(receiver, toToken.originChain, toChainNativeToken.slug, _KoniTypes.ExtrinsicType.TRANSFER_BALANCE);
285
- if (!(0, _systemPallet._isAccountActive)(toChainNativeTokenBalance.metadata)) {
286
- 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', {
287
- replace: {
288
- amount: toChainNativeTokenBalance.value,
289
- nativeSymbol: toChainNativeToken.symbol,
290
- localSymbol: toToken.symbol
291
- }
292
- }))];
339
+ // Only need to check if account is alive with the receiving toToken
340
+ const isToTokenSufficient = await (0, _utils._isSufficientToken)(toToken, toChainApi, sufficientChain);
341
+ if (!isToTokenSufficient && !(0, _utils2._isNativeToken)(toToken)) {
342
+ // sending token cannot keep account alive, must check with native token
343
+ const toChainNativeTokenBalance = await this.balanceService.getTotalBalance(receiver, toToken.originChain, toChainNativeToken.slug, _KoniTypes.ExtrinsicType.TRANSFER_BALANCE);
344
+ if (!(0, _systemPallet._isAccountActive)(toChainNativeTokenBalance.metadata)) {
345
+ 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', {
346
+ replace: {
347
+ amount: toChainNativeTokenBalance.value,
348
+ nativeSymbol: toChainNativeToken.symbol,
349
+ localSymbol: toToken.symbol
350
+ }
351
+ }))];
352
+ }
293
353
  }
294
354
  }
295
355
  return [];
@@ -286,7 +286,7 @@ class HydradxHandler {
286
286
  case _serviceBase.CommonStepType.DEFAULT:
287
287
  return Promise.reject(new _TransactionError.TransactionError(_types.BasicTxErrorType.UNSUPPORTED));
288
288
  case _serviceBase.CommonStepType.XCM:
289
- return this.swapBaseHandler.handleBridgeStep(params);
289
+ return this.swapBaseHandler.handleBridgeStep(params, 'xcm');
290
290
  case _serviceBase.CommonStepType.SET_FEE_TOKEN:
291
291
  return this.handleSetFeeStep(params);
292
292
  case _swap.SwapStepType.SWAP:
@@ -8,8 +8,12 @@ exports.UniswapHandler = 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 _web = require("@subwallet/extension-base/koni/api/contract-handler/evm/web3");
12
+ var _xcm = require("@subwallet/extension-base/services/balance-service/transfer/xcm");
13
+ var _acrossBridge = require("@subwallet/extension-base/services/balance-service/transfer/xcm/acrossBridge");
11
14
  var _types = require("@subwallet/extension-base/types");
12
15
  var _utils = require("@subwallet/extension-base/utils");
16
+ var _getId = require("@subwallet/extension-base/utils/getId");
13
17
  var _bignumber = _interopRequireDefault(require("bignumber.js"));
14
18
  var _utils2 = require("../../chain-service/utils");
15
19
  var _utils3 = require("../../fee-service/utils");
@@ -66,41 +70,121 @@ class UniswapHandler {
66
70
  return this.swapBaseHandler.providerInfo;
67
71
  }
68
72
  generateOptimalProcessV2(params) {
69
- return this.swapBaseHandler.generateOptimalProcessV2(params, [this.getApprovalStep.bind(this), this.getPermitStep.bind(this), this.getSubmitStep.bind(this)]);
73
+ const stepFuncList = [];
74
+ /**
75
+ * approve - permit - swap or
76
+ * approve - permit - swap - approve - bridge
77
+ */
78
+
79
+ params.path.forEach(step => {
80
+ if (step.action === _types.DynamicSwapType.SWAP) {
81
+ stepFuncList.push(...[this.getApprovalStep.bind(this), this.getPermitStep.bind(this), this.getSubmitStep.bind(this)]);
82
+ return;
83
+ }
84
+ if (step.action === _types.DynamicSwapType.BRIDGE) {
85
+ stepFuncList.push(...[this.getApprovalStep.bind(this), this.getBridgeStep.bind(this)]);
86
+ return;
87
+ }
88
+ throw new Error(`Error generating optimal process: Action ${step.action} is not supported`);
89
+ });
90
+ return this.swapBaseHandler.generateOptimalProcessV2(params, stepFuncList);
70
91
  }
71
92
  async getApprovalStep(params, stepIndex) {
72
- if (params.selectedQuote) {
73
- const walletAddress = params.request.address;
74
- const fromAmount = params.selectedQuote.fromAmount;
75
- const inputTokenInfo = this.chainService.getAssetBySlug(params.selectedQuote.pair.from);
76
- const {
77
- quote
78
- } = params.selectedQuote.metadata;
79
- const checkApprovalResponse = await fetchCheckApproval(walletAddress, fromAmount, quote);
80
- const approval = checkApprovalResponse.approval;
81
- if (approval) {
82
- let spender = '';
83
- try {
84
- const valueLength = 40;
85
- spender = approval.data.slice(-(valueLength * 2), -valueLength);
86
- } catch (e) {
87
- // Empty
88
- }
89
- const metadata = {
90
- tokenApprove: inputTokenInfo.slug,
91
- contractAddress: (0, _utils2._getContractAddressOfToken)(inputTokenInfo),
92
- spenderAddress: spender
93
- };
94
- const submitStep = {
95
- name: 'Approve token',
96
- type: _types.CommonStepType.TOKEN_APPROVAL,
97
- metadata: metadata
98
- };
99
- return Promise.resolve([submitStep, params.selectedQuote.feeInfo]);
100
- }
93
+ if (stepIndex === 0) {
94
+ return this.getApproveSwap(params);
95
+ }
96
+ if (stepIndex === 3) {
97
+ return this.getApproveBridge(params);
101
98
  }
102
99
  return Promise.resolve(undefined);
103
100
  }
101
+ async getApproveSwap(params) {
102
+ const selectedQuote = params.selectedQuote;
103
+ if (!selectedQuote) {
104
+ return Promise.resolve(undefined);
105
+ }
106
+ const quoteMetadata = selectedQuote.metadata.quote;
107
+ const sender = quoteMetadata.swapper;
108
+ const sendingValue = quoteMetadata.input.amount;
109
+ const fromTokenInfo = this.chainService.getAssetBySlug(selectedQuote.pair.from);
110
+ const checkApprovalResponse = await fetchCheckApproval(sender, sendingValue, quoteMetadata);
111
+ const approval = checkApprovalResponse.approval;
112
+ if (!approval) {
113
+ return Promise.resolve(undefined);
114
+ }
115
+ let spender = '';
116
+ try {
117
+ const valueLength = 40;
118
+ spender = approval.data.slice(-(valueLength * 2), -valueLength);
119
+ } catch (e) {
120
+ // Empty
121
+ }
122
+ const submitStep = {
123
+ name: 'Approve token for swap',
124
+ type: _types.CommonStepType.TOKEN_APPROVAL,
125
+ // @ts-ignore
126
+ metadata: {
127
+ tokenApprove: fromTokenInfo.slug,
128
+ contractAddress: (0, _utils2._getContractAddressOfToken)(fromTokenInfo),
129
+ spenderAddress: spender,
130
+ owner: sender,
131
+ amount: sendingValue,
132
+ isUniswapApprove: true
133
+ }
134
+ };
135
+ return Promise.resolve([submitStep, selectedQuote.feeInfo]); // todo: wrong feeInfo, please check
136
+ }
137
+
138
+ async getApproveBridge(params) {
139
+ const quote = params.selectedQuote;
140
+ if (!quote) {
141
+ return Promise.resolve(undefined);
142
+ }
143
+ const sendingAmount = quote.toAmount;
144
+ const senderAddress = params.request.address;
145
+ const fromTokenInfo = this.chainService.getAssetBySlug(quote.pair.to);
146
+ const fromChainInfo = this.chainService.getChainInfoByKey((0, _utils2._getAssetOriginChain)(fromTokenInfo));
147
+ const fromChainId = (0, _utils2._getEvmChainId)(fromChainInfo);
148
+ const evmApi = this.chainService.getEvmApi(fromChainInfo.slug);
149
+ const tokenContract = (0, _utils2._getContractAddressOfToken)(fromTokenInfo);
150
+ if ((0, _utils2._isNativeToken)(fromTokenInfo)) {
151
+ return Promise.resolve(undefined);
152
+ }
153
+ if (!fromChainId) {
154
+ throw Error('Error getting Evm chain Id');
155
+ }
156
+ const spokePoolAddress = _acrossBridge.SpokePoolMapping[fromChainId].SpokePool.address;
157
+ const allowance = await (0, _web.getERC20Allowance)(spokePoolAddress, senderAddress, tokenContract, evmApi);
158
+ if (allowance && (0, _bignumber.default)(allowance).gt(sendingAmount)) {
159
+ return Promise.resolve(undefined);
160
+ }
161
+ const tx = await (0, _web.getERC20SpendingApprovalTx)(spokePoolAddress, senderAddress, tokenContract, evmApi);
162
+ const evmFeeInfo = await this.feeService.subscribeChainFee((0, _getId.getId)(), fromTokenInfo.originChain, 'evm');
163
+ const estimatedFee = await (0, _web.estimateTxFee)(tx, evmApi, evmFeeInfo);
164
+ const nativeTokenSlug = (0, _utils2._getChainNativeTokenSlug)(fromChainInfo);
165
+ const feeInfo = {
166
+ feeComponent: [{
167
+ feeType: _types.SwapFeeType.NETWORK_FEE,
168
+ amount: estimatedFee,
169
+ tokenSlug: nativeTokenSlug
170
+ }],
171
+ defaultFeeToken: nativeTokenSlug,
172
+ feeOptions: [nativeTokenSlug]
173
+ };
174
+ const submitStep = {
175
+ name: 'Approve token for bridge',
176
+ type: _types.CommonStepType.TOKEN_APPROVAL,
177
+ // @ts-ignore
178
+ metadata: {
179
+ tokenApprove: fromTokenInfo.slug,
180
+ contractAddress: tokenContract,
181
+ spenderAddress: spokePoolAddress,
182
+ amount: sendingAmount,
183
+ owner: senderAddress
184
+ }
185
+ };
186
+ return Promise.resolve([submitStep, feeInfo]);
187
+ }
104
188
  async getPermitStep(params, stepIndex) {
105
189
  if (params.selectedQuote && params.selectedQuote.metadata.permitData) {
106
190
  const submitStep = {
@@ -123,11 +207,22 @@ class UniswapHandler {
123
207
  return Promise.resolve(undefined);
124
208
  }
125
209
  async getSubmitStep(params, stepIndex) {
126
- if (!params.selectedQuote) {
210
+ const {
211
+ path,
212
+ request,
213
+ selectedQuote
214
+ } = params;
215
+
216
+ // stepIndex is not corresponding index in path, because uniswap include approval and permit step
217
+ const stepData = path.find(action => action.action === _types.DynamicSwapType.SWAP);
218
+ if (!stepData || !stepData.pair) {
219
+ return Promise.resolve(undefined);
220
+ }
221
+ if (!selectedQuote) {
127
222
  return Promise.resolve(undefined);
128
223
  }
129
- const originTokenInfo = this.chainService.getAssetBySlug(params.selectedQuote.pair.from);
130
- const destinationTokenInfo = this.chainService.getAssetBySlug(params.selectedQuote.pair.to);
224
+ const originTokenInfo = this.chainService.getAssetBySlug(selectedQuote.pair.from);
225
+ const destinationTokenInfo = this.chainService.getAssetBySlug(selectedQuote.pair.to);
131
226
  const originChain = this.chainService.getChainInfoByKey(originTokenInfo.originChain);
132
227
  const destinationChain = this.chainService.getChainInfoByKey(destinationTokenInfo.originChain);
133
228
  const submitStep = {
@@ -135,16 +230,99 @@ class UniswapHandler {
135
230
  type: _types.SwapStepType.SWAP,
136
231
  // @ts-ignore
137
232
  metadata: {
138
- sendingValue: params.request.fromAmount.toString(),
139
- expectedReceive: params.selectedQuote.toAmount,
233
+ sendingValue: request.fromAmount.toString(),
234
+ expectedReceive: selectedQuote.toAmount,
140
235
  originTokenInfo,
141
236
  destinationTokenInfo,
142
- sender: (0, _utils._reformatAddressWithChain)(params.request.address, originChain),
143
- receiver: (0, _utils._reformatAddressWithChain)(params.request.recipient || params.request.address, destinationChain),
237
+ sender: (0, _utils._reformatAddressWithChain)(request.address, originChain),
238
+ receiver: (0, _utils._reformatAddressWithChain)(request.recipient || request.address, destinationChain),
144
239
  version: 2
145
240
  }
146
241
  };
147
- return Promise.resolve([submitStep, params.selectedQuote.feeInfo]);
242
+ return Promise.resolve([submitStep, selectedQuote.feeInfo]);
243
+ }
244
+ async getBridgeStep(params, stepIndex) {
245
+ const {
246
+ path,
247
+ request,
248
+ selectedQuote
249
+ } = params;
250
+
251
+ // stepIndex is not corresponding index in path, because uniswap include approval and permit step
252
+ const bridgePairInfo = path.find(action => action.action === _types.DynamicSwapType.BRIDGE);
253
+ if (!bridgePairInfo || !bridgePairInfo.pair) {
254
+ return Promise.resolve(undefined);
255
+ }
256
+ if (!selectedQuote) {
257
+ return Promise.resolve(undefined);
258
+ }
259
+ const fromTokenInfo = this.chainService.getAssetBySlug(bridgePairInfo.pair.from);
260
+ const toTokenInfo = this.chainService.getAssetBySlug(bridgePairInfo.pair.to);
261
+ const fromChainInfo = this.chainService.getChainInfoByKey(fromTokenInfo.originChain);
262
+ const toChainInfo = this.chainService.getChainInfoByKey(toTokenInfo.originChain);
263
+ if (!fromChainInfo || !toChainInfo || !fromChainInfo || !toChainInfo) {
264
+ throw Error('Token or chain not found');
265
+ }
266
+ const senderAddress = (0, _utils._reformatAddressWithChain)(request.address, fromChainInfo);
267
+ const receiverAddress = (0, _utils._reformatAddressWithChain)(request.recipient || request.address, toChainInfo);
268
+ const sendingValue = (0, _bignumber.default)(selectedQuote.toAmount).div(1.02).toFixed(0, 1);
269
+ try {
270
+ const evmApi = await this.chainService.getEvmApi(fromChainInfo.slug).isReady;
271
+ const feeInfo = await this.feeService.subscribeChainFee((0, _getId.getId)(), fromTokenInfo.originChain, 'evm');
272
+ const tx = await (0, _xcm.createAcrossBridgeExtrinsic)({
273
+ originTokenInfo: fromTokenInfo,
274
+ destinationTokenInfo: toTokenInfo,
275
+ originChain: fromChainInfo,
276
+ destinationChain: toChainInfo,
277
+ evmApi,
278
+ feeInfo,
279
+ // Mock sending value to get payment info
280
+ sendingValue,
281
+ sender: senderAddress,
282
+ recipient: receiverAddress
283
+ });
284
+
285
+ // // todo: wait until this ready to get destination fee. the real receiveAmount is deduce by this fee
286
+ // const acrossQuote = await getAcrossQuote({
287
+ // destinationChain: toChainInfo,
288
+ // destinationTokenInfo: toTokenInfo,
289
+ // originChain: fromChainInfo,
290
+ // originTokenInfo: fromTokenInfo,
291
+ // recipient: receiverAddress,
292
+ // sender: senderAddress,
293
+ // sendingValue,
294
+ // feeInfo
295
+ // });
296
+
297
+ const estimatedBridgeFee = await (0, _web.estimateTxFee)(tx, evmApi, feeInfo);
298
+ const expectedReceive = (0, _bignumber.default)(sendingValue).minus(estimatedBridgeFee).toFixed(0, 1);
299
+ const fee = {
300
+ feeComponent: [{
301
+ feeType: _types.SwapFeeType.NETWORK_FEE,
302
+ amount: estimatedBridgeFee,
303
+ tokenSlug: (0, _utils2._getChainNativeTokenSlug)(fromChainInfo)
304
+ }],
305
+ defaultFeeToken: (0, _utils2._getChainNativeTokenSlug)(fromChainInfo),
306
+ feeOptions: [(0, _utils2._getChainNativeTokenSlug)(fromChainInfo)]
307
+ };
308
+ const step = {
309
+ // @ts-ignore
310
+ metadata: {
311
+ sendingValue: sendingValue,
312
+ expectedReceive,
313
+ originTokenInfo: fromTokenInfo,
314
+ destinationTokenInfo: toTokenInfo,
315
+ receiver: receiverAddress,
316
+ sender: senderAddress
317
+ },
318
+ name: `Transfer ${fromTokenInfo.symbol} from ${fromChainInfo.name}`,
319
+ type: _types.CommonStepType.XCM
320
+ };
321
+ return [step, fee];
322
+ } catch (e) {
323
+ console.error('Error creating bridge step', e);
324
+ throw new Error(e.message);
325
+ }
148
326
  }
149
327
  async handleSwapProcess(params) {
150
328
  const {
@@ -157,6 +335,8 @@ class UniswapHandler {
157
335
  return Promise.reject(new _TransactionError.TransactionError(_types.BasicTxErrorType.UNSUPPORTED));
158
336
  case _types.CommonStepType.TOKEN_APPROVAL:
159
337
  return this.tokenApproveSpending(params);
338
+ case _types.CommonStepType.XCM:
339
+ return this.swapBaseHandler.handleBridgeStep(params, 'across');
160
340
  case _types.SwapStepType.SWAP:
161
341
  return this.handleSubmitStep(params);
162
342
  case _types.SwapStepType.PERMIT:
@@ -166,13 +346,29 @@ class UniswapHandler {
166
346
  }
167
347
  }
168
348
  async tokenApproveSpending(params) {
169
- const fromAsset = this.chainService.getAssetBySlug(params.quote.pair.from);
170
- const walletAddress = params.address;
171
- const fromAmount = params.quote.fromAmount;
349
+ const approveStep = params.process.steps[params.currentStep].metadata;
350
+ if (!approveStep || !approveStep.tokenApprove || !approveStep.contractAddress || !approveStep.spenderAddress) {
351
+ throw new Error('Approval spending metadata error');
352
+ }
353
+ if (approveStep.isUniswapApprove) {
354
+ return this.approveSpendingSwap(params, approveStep);
355
+ }
356
+ return this.approveSpendingBridge(approveStep);
357
+ }
358
+ async approveSpendingSwap(params, approveStep) {
359
+ const fromAsset = this.chainService.getAssetBySlug(approveStep.tokenApprove);
360
+ const sender = approveStep.owner;
361
+ const sendingValue = approveStep.amount;
362
+ if (!sender || !sendingValue) {
363
+ throw new Error('Sender or value is not found');
364
+ }
365
+
366
+ // todo: move quote param to metadata;
367
+
172
368
  const {
173
369
  quote
174
370
  } = params.quote.metadata;
175
- const checkApprovalResponse = await fetchCheckApproval(walletAddress, fromAmount, quote);
371
+ const checkApprovalResponse = await fetchCheckApproval(sender, sendingValue, quote);
176
372
  let transactionConfig = {};
177
373
  const approval = checkApprovalResponse.approval;
178
374
  if (approval) {
@@ -208,6 +404,34 @@ class UniswapHandler {
208
404
  chainType: _KoniTypes.ChainType.EVM
209
405
  });
210
406
  }
407
+ async approveSpendingBridge(approveStep) {
408
+ const fromAsset = this.chainService.getAssetBySlug(approveStep.tokenApprove);
409
+ const fromChain = (0, _utils2._getAssetOriginChain)(fromAsset);
410
+ const evmApi = this.chainService.getEvmApi(fromAsset.originChain);
411
+ const sender = approveStep.owner;
412
+ const sendingValue = approveStep.amount;
413
+ if (!sender) {
414
+ throw new Error('Sender or value is not found');
415
+ }
416
+ const spenderAddress = approveStep.spenderAddress;
417
+ const contractAddress = approveStep.contractAddress;
418
+ const transactionConfig = await (0, _web.getERC20SpendingApprovalTx)(spenderAddress, sender, contractAddress, evmApi);
419
+ const _data = {
420
+ spenderAddress: approveStep.spenderAddress,
421
+ contractAddress: approveStep.contractAddress,
422
+ amount: sendingValue,
423
+ owner: sender,
424
+ chain: fromChain
425
+ };
426
+ return Promise.resolve({
427
+ txChain: fromChain,
428
+ extrinsicType: _KoniTypes.ExtrinsicType.TOKEN_SPENDING_APPROVAL,
429
+ extrinsic: transactionConfig,
430
+ txData: _data,
431
+ transferNativeAmount: '0',
432
+ chainType: _KoniTypes.ChainType.EVM
433
+ });
434
+ }
211
435
  async handleSubmitStep(params) {
212
436
  const fromAsset = this.chainService.getAssetBySlug(params.quote.pair.from);
213
437
  const {
@@ -241,6 +465,8 @@ class UniswapHandler {
241
465
  const transactionResponse = await postTransactionResponse.json();
242
466
  extrinsic = transactionResponse.swap;
243
467
  } else if (routing === 'DUTCH_LIMIT' || routing === 'DUTCH_V2') {
468
+ // todo: update condition and add handle exception
469
+ // UniswapX, UniswapX_V2, and UniswapX_V3 are alternately referred to as DutchQuote, DutchQuoteV2, and DutchQuoteV3
244
470
  postTransactionResponse = await fetch(`${API_URL}/order`, {
245
471
  method: 'POST',
246
472
  headers: {
@@ -332,17 +558,20 @@ class UniswapHandler {
332
558
  const swapXcm = actionList === JSON.stringify([_types.DynamicSwapType.SWAP, _types.DynamicSwapType.BRIDGE]);
333
559
  const xcmSwap = actionList === JSON.stringify([_types.DynamicSwapType.BRIDGE, _types.DynamicSwapType.SWAP]);
334
560
  const xcmSwapXcm = actionList === JSON.stringify([_types.DynamicSwapType.BRIDGE, _types.DynamicSwapType.SWAP, _types.DynamicSwapType.BRIDGE]);
335
- const swapIndex = params.process.steps.findIndex(step => step.type === _types.SwapStepType.SWAP); // todo
336
-
561
+ const swapIndex = params.process.steps.findIndex(step => step.type === _types.SwapStepType.SWAP);
562
+ const bridgeIndex = params.process.steps.findIndex(step => step.type === _types.CommonStepType.XCM);
337
563
  if (swapIndex <= -1) {
338
564
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
339
565
  }
566
+ if (swapXcm && bridgeIndex <= -1) {
567
+ return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
568
+ }
340
569
  if (swap) {
341
570
  return this.swapBaseHandler.validateSwapOnlyProcess(params, swapIndex); // todo: create interface for input request
342
571
  }
343
572
 
344
573
  if (swapXcm) {
345
- return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
574
+ return this.swapBaseHandler.validateSwapXcmProcess(params, swapIndex, bridgeIndex);
346
575
  }
347
576
  if (xcmSwap) {
348
577
  return [new _TransactionError.TransactionError(_types.BasicTxErrorType.INTERNAL_ERROR)];
@@ -117,16 +117,22 @@ class SwapService {
117
117
  path,
118
118
  swapQuoteResponse
119
119
  } = await this.getLatestQuoteFromSwapRequest(request);
120
- const optimalProcess = await this.generateOptimalProcessV2({
121
- request,
122
- selectedQuote: swapQuoteResponse.optimalQuote,
123
- path
124
- });
125
- console.log('-------');
120
+ console.group('Swap Logger');
121
+ console.log('path', path);
122
+ console.log('swapQuoteResponse', swapQuoteResponse);
123
+ let optimalProcess;
124
+ try {
125
+ optimalProcess = await this.generateOptimalProcessV2({
126
+ request,
127
+ selectedQuote: swapQuoteResponse.optimalQuote,
128
+ path
129
+ });
130
+ } catch (e) {
131
+ throw new Error(e.message);
132
+ }
126
133
  console.log('optimalProcess', optimalProcess);
127
- console.log('-------');
128
- if (optimalProcess.steps.length - 1 < optimalProcess.path.length) {
129
- // minus the fill info step
134
+ console.groupEnd();
135
+ if (JSON.stringify((0, _utils2.processStepsToPathActions)(optimalProcess.steps)) !== JSON.stringify(optimalProcess.path.map(e => e.action))) {
130
136
  throw new Error('Swap pair is not found');
131
137
  }
132
138
  return {
@@ -142,7 +148,7 @@ class SwapService {
142
148
  pair
143
149
  } = request;
144
150
  // todo: control provider tighter
145
- const supportSwapChains = (0, _utils2.getSupportSwapChain)();
151
+ const supportSwapChains = (0, _utils2.getSupportedSwapChains)();
146
152
  const fromToken = this.chainService.getAssetBySlug(pair.from);
147
153
  const toToken = this.chainService.getAssetBySlug(pair.to);
148
154
  const fromChain = (0, _utils._getAssetOriginChain)(fromToken);
@@ -244,10 +250,26 @@ class SwapService {
244
250
  return [[], undefined];
245
251
  }
246
252
  async getLatestQuoteFromSwapRequest(request) {
247
- const [path, directSwapRequest] = this.getAvailablePath(request);
253
+ var _subwalletApiSdk$swap2;
254
+ const availablePath = await ((_subwalletApiSdk$swap2 = _subwalletApiSdk.default.swapApi) === null || _subwalletApiSdk$swap2 === void 0 ? void 0 : _subwalletApiSdk$swap2.findAvailablePath(request));
255
+ if (!availablePath) {
256
+ throw Error('No available path');
257
+ }
258
+ const {
259
+ path
260
+ } = availablePath;
261
+ const swapAction = path.find(step => step.action === _types3.DynamicSwapType.SWAP);
262
+ const directSwapRequest = swapAction ? {
263
+ ...request,
264
+ address: (0, _utils3._reformatAddressWithChain)(request.address, this.chainService.getChainInfoByKey((0, _utils._getAssetOriginChain)(this.chainService.getAssetBySlug(swapAction.pair.from)))),
265
+ pair: swapAction.pair
266
+ } : undefined;
248
267
  if (!directSwapRequest) {
249
268
  throw Error('Swap pair is not found');
250
269
  }
270
+ if (path.length > 1 && path.map(action => action.action).includes(_types3.DynamicSwapType.BRIDGE)) {
271
+ directSwapRequest.isCrossChain = true;
272
+ }
251
273
  const swapQuoteResponse = await this.getLatestDirectQuotes(directSwapRequest);
252
274
  return {
253
275
  path,
@@ -18,13 +18,14 @@ exports.getChainflipOptions = getChainflipOptions;
18
18
  exports.getChainflipSwap = getChainflipSwap;
19
19
  exports.getFirstAmountFromSteps = getFirstAmountFromSteps;
20
20
  exports.getLastAmountFromSteps = getLastAmountFromSteps;
21
- exports.getSupportSwapChain = getSupportSwapChain;
21
+ exports.getSupportedSwapChains = getSupportedSwapChains;
22
22
  exports.getSwapAltToken = getSwapAltToken;
23
23
  exports.getSwapAlternativeAsset = getSwapAlternativeAsset;
24
24
  exports.getSwapChainsFromPath = getSwapChainsFromPath;
25
25
  exports.getSwapStep = getSwapStep;
26
26
  exports.getTokenPairFromStep = getTokenPairFromStep;
27
27
  exports.isChainsHasSameProvider = isChainsHasSameProvider;
28
+ exports.processStepsToPathActions = processStepsToPathActions;
28
29
  var _chainList = require("@subwallet/chain-list");
29
30
  var _types = require("@subwallet/chain-list/types");
30
31
  var _utils = require("@subwallet/extension-base/services/chain-service/utils");
@@ -76,7 +77,7 @@ const FEE_RATE_MULTIPLIER = {
76
77
  high: 2
77
78
  };
78
79
  exports.FEE_RATE_MULTIPLIER = FEE_RATE_MULTIPLIER;
79
- function getSupportSwapChain() {
80
+ function getSupportedSwapChains() {
80
81
  return [...new Set(Object.values(_PROVIDER_TO_SUPPORTED_PAIR_MAP).flat())];
81
82
  }
82
83
  function getSwapAlternativeAsset(swapPair) {
@@ -270,5 +271,17 @@ function getSwapChainsFromPath(path) {
270
271
  });
271
272
  return swapChains;
272
273
  }
274
+ function processStepsToPathActions(steps) {
275
+ const path = [];
276
+ for (const step of steps) {
277
+ if (step.type === _types2.CommonStepType.XCM) {
278
+ path.push(_types2.DynamicSwapType.BRIDGE);
279
+ }
280
+ if (step.type === _types2.SwapStepType.SWAP) {
281
+ path.push(_types2.DynamicSwapType.SWAP);
282
+ }
283
+ }
284
+ return path;
285
+ }
273
286
  const DEFAULT_EXCESS_AMOUNT_WEIGHT = 1.04; // add 2%
274
287
  exports.DEFAULT_EXCESS_AMOUNT_WEIGHT = DEFAULT_EXCESS_AMOUNT_WEIGHT;