@subwallet/extension-base 1.3.29-1 → 1.3.30-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 (80) hide show
  1. package/background/KoniTypes.d.ts +4 -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/remind-notification-time.js +3 -3
  6. package/cjs/core/logic-validation/swap.js +63 -4
  7. package/cjs/core/utils.js +1 -1
  8. package/cjs/koni/background/handlers/Extension.js +5 -82
  9. package/cjs/packageInfo.js +1 -1
  10. package/cjs/services/balance-service/transfer/xcm/availBridge.js +6 -6
  11. package/cjs/services/earning-service/handlers/base.js +6 -3
  12. package/cjs/services/earning-service/handlers/native-staking/base.js +4 -1
  13. package/cjs/services/earning-service/handlers/native-staking/dtao.js +68 -50
  14. package/cjs/services/earning-service/handlers/native-staking/tao.js +12 -2
  15. package/cjs/services/earning-service/service.js +2 -1
  16. package/cjs/services/fee-service/utils/index.js +16 -4
  17. package/cjs/services/inapp-notification-service/index.js +19 -13
  18. package/cjs/services/swap-service/handler/asset-hub/handler.js +61 -314
  19. package/cjs/services/swap-service/handler/base-handler.js +393 -231
  20. package/cjs/services/swap-service/handler/chainflip-handler.js +18 -40
  21. package/cjs/services/swap-service/handler/hydradx-handler.js +77 -269
  22. package/cjs/services/swap-service/handler/simpleswap-handler.js +27 -48
  23. package/cjs/services/swap-service/handler/uniswap-handler.js +33 -54
  24. package/cjs/services/swap-service/index.js +154 -143
  25. package/cjs/services/swap-service/utils.js +107 -17
  26. package/cjs/services/transaction-service/index.js +1 -1
  27. package/cjs/types/swap/index.js +13 -1
  28. package/cjs/utils/swap.js +5 -1
  29. package/constants/blocked-actions.d.ts +1 -1
  30. package/constants/blocked-actions.js +1 -1
  31. package/constants/remind-notification-time.d.ts +1 -1
  32. package/constants/remind-notification-time.js +1 -1
  33. package/core/logic-validation/swap.d.ts +15 -0
  34. package/core/logic-validation/swap.js +60 -4
  35. package/core/utils.js +1 -1
  36. package/koni/background/handlers/Extension.d.ts +0 -1
  37. package/koni/background/handlers/Extension.js +6 -83
  38. package/package.json +6 -12
  39. package/packageInfo.js +1 -1
  40. package/services/balance-service/transfer/xcm/availBridge.js +6 -6
  41. package/services/base/types.d.ts +0 -4
  42. package/services/earning-service/handlers/base.d.ts +4 -3
  43. package/services/earning-service/handlers/base.js +6 -4
  44. package/services/earning-service/handlers/native-staking/base.js +4 -1
  45. package/services/earning-service/handlers/native-staking/dtao.d.ts +9 -6
  46. package/services/earning-service/handlers/native-staking/dtao.js +69 -48
  47. package/services/earning-service/handlers/native-staking/tao.js +12 -2
  48. package/services/earning-service/service.d.ts +2 -1
  49. package/services/earning-service/service.js +2 -1
  50. package/services/fee-service/utils/index.d.ts +1 -0
  51. package/services/fee-service/utils/index.js +14 -4
  52. package/services/inapp-notification-service/index.js +13 -7
  53. package/services/swap-service/handler/asset-hub/handler.d.ts +2 -9
  54. package/services/swap-service/handler/asset-hub/handler.js +64 -317
  55. package/services/swap-service/handler/base-handler.d.ts +6 -9
  56. package/services/swap-service/handler/base-handler.js +391 -229
  57. package/services/swap-service/handler/chainflip-handler.d.ts +2 -4
  58. package/services/swap-service/handler/chainflip-handler.js +15 -37
  59. package/services/swap-service/handler/hydradx-handler.d.ts +3 -10
  60. package/services/swap-service/handler/hydradx-handler.js +78 -270
  61. package/services/swap-service/handler/simpleswap-handler.d.ts +2 -4
  62. package/services/swap-service/handler/simpleswap-handler.js +24 -45
  63. package/services/swap-service/handler/uniswap-handler.d.ts +4 -6
  64. package/services/swap-service/handler/uniswap-handler.js +25 -46
  65. package/services/swap-service/index.d.ts +8 -14
  66. package/services/swap-service/index.js +141 -129
  67. package/services/swap-service/utils.d.ts +11 -3
  68. package/services/swap-service/utils.js +96 -15
  69. package/services/transaction-service/index.js +2 -2
  70. package/types/service-base.d.ts +2 -3
  71. package/types/swap/index.d.ts +25 -9
  72. package/types/swap/index.js +10 -0
  73. package/types/transaction/process.d.ts +19 -0
  74. package/types/yield/actions/join/submit.d.ts +4 -1
  75. package/types/yield/actions/others.d.ts +2 -0
  76. package/utils/swap.d.ts +3 -0
  77. package/utils/swap.js +3 -0
  78. package/cjs/services/swap-service/interface.js +0 -14
  79. package/services/swap-service/interface.d.ts +0 -9
  80. package/services/swap-service/interface.js +0 -8
@@ -4,7 +4,7 @@ import { BalanceService } from '@subwallet/extension-base/services/balance-servi
4
4
  import { ChainService } from '@subwallet/extension-base/services/chain-service';
5
5
  import FeeService from '@subwallet/extension-base/services/fee-service/service';
6
6
  import { SwapBaseInterface } from '@subwallet/extension-base/services/swap-service/handler/base-handler';
7
- import { BaseStepDetail, CommonOptimalSwapPath, CommonStepFeeInfo, OptimalSwapPathParams, OptimalSwapPathParamsV2, SwapProviderId, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types';
7
+ import { BaseStepDetail, CommonOptimalSwapPath, CommonStepFeeInfo, OptimalSwapPathParamsV2, SwapProviderId, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types';
8
8
  export declare const CHAINFLIP_BROKER_API: string;
9
9
  export declare class ChainflipSwapHandler implements SwapBaseInterface {
10
10
  private readonly isTestnet;
@@ -18,11 +18,9 @@ export declare class ChainflipSwapHandler implements SwapBaseInterface {
18
18
  get name(): string;
19
19
  get slug(): string;
20
20
  get intermediaryAssetSlug(): COMMON_ASSETS.USDC_ETHEREUM | COMMON_ASSETS.USDC_SEPOLIA;
21
- validateSwapProcess(params: ValidateSwapProcessParams): Promise<TransactionError[]>;
22
21
  handleSubmitStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
23
22
  handleSwapProcess(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
24
- getSubmitStep(params: OptimalSwapPathParams): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
25
- generateOptimalProcess(params: OptimalSwapPathParams): Promise<CommonOptimalSwapPath>;
23
+ getSubmitStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
26
24
  generateOptimalProcessV2(params: OptimalSwapPathParamsV2): Promise<CommonOptimalSwapPath>;
27
25
  validateSwapProcessV2(params: ValidateSwapProcessParams): Promise<TransactionError[]>;
28
26
  }
@@ -8,9 +8,8 @@ import { getERC20TransactionObject, getEVMTransactionObject } from '@subwallet/e
8
8
  import { createSubstrateExtrinsic } from '@subwallet/extension-base/services/balance-service/transfer/token';
9
9
  import { _getAssetSymbol, _getContractAddressOfToken, _isChainSubstrateCompatible, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
10
10
  import { SwapBaseHandler } from '@subwallet/extension-base/services/swap-service/handler/base-handler';
11
- import { DynamicSwapType } from '@subwallet/extension-base/services/swap-service/interface';
12
11
  import { getChainflipSwap } from '@subwallet/extension-base/services/swap-service/utils';
13
- import { BasicTxErrorType, CommonStepType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types';
12
+ import { BasicTxErrorType, CommonStepType, DynamicSwapType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types';
14
13
  import { _reformatAddressWithChain } from '@subwallet/extension-base/utils';
15
14
  import { getId } from '@subwallet/extension-base/utils/getId';
16
15
  import BigNumber from 'bignumber.js';
@@ -52,33 +51,6 @@ export class ChainflipSwapHandler {
52
51
  return INTERMEDIARY_MAINNET_ASSET_SLUG;
53
52
  }
54
53
  }
55
- async validateSwapProcess(params) {
56
- const amount = params.selectedQuote.fromAmount;
57
- const bnAmount = new BigNumber(amount);
58
- if (bnAmount.lte(0)) {
59
- return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')];
60
- }
61
- let isXcmOk = false;
62
- for (const [index, step] of params.process.steps.entries()) {
63
- const getErrors = async () => {
64
- switch (step.type) {
65
- case CommonStepType.DEFAULT:
66
- return Promise.resolve([]);
67
- case CommonStepType.TOKEN_APPROVAL:
68
- return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
69
- default:
70
- return this.swapBaseHandler.validateSwapStep(params, isXcmOk, index);
71
- }
72
- };
73
- const errors = await getErrors();
74
- if (errors.length) {
75
- return errors;
76
- } else if (step.type === CommonStepType.XCM) {
77
- isXcmOk = true;
78
- }
79
- }
80
- return [];
81
- }
82
54
  async handleSubmitStep(params) {
83
55
  const {
84
56
  address,
@@ -97,7 +69,7 @@ export class ChainflipSwapHandler {
97
69
  const toAssetId = _getAssetSymbol(toAsset);
98
70
  const minReceive = new BigNumber(quote.rate).times(1 - slippage).toString();
99
71
  const processMetadata = params.process.steps[params.currentStep].metadata;
100
- const quoteMetadata = params.quote.metadata;
72
+ const quoteMetadata = processMetadata;
101
73
  if (!processMetadata || !quoteMetadata) {
102
74
  throw new Error('Metadata for Chainflip not found');
103
75
  }
@@ -205,7 +177,7 @@ export class ChainflipSwapHandler {
205
177
  return this.handleSubmitStep(params);
206
178
  }
207
179
  }
208
- async getSubmitStep(params) {
180
+ async getSubmitStep(params, stepIndex) {
209
181
  var _params$selectedQuote;
210
182
  const metadata = (_params$selectedQuote = params.selectedQuote) === null || _params$selectedQuote === void 0 ? void 0 : _params$selectedQuote.metadata;
211
183
  if (!params.selectedQuote) {
@@ -214,22 +186,28 @@ export class ChainflipSwapHandler {
214
186
  if (!metadata || !metadata.srcChain || !metadata.destChain) {
215
187
  return Promise.resolve(undefined);
216
188
  }
189
+ const originTokenInfo = this.chainService.getAssetBySlug(params.selectedQuote.pair.from);
190
+ const destinationTokenInfo = this.chainService.getAssetBySlug(params.selectedQuote.pair.to);
191
+ const originChain = this.chainService.getChainInfoByKey(originTokenInfo.originChain);
192
+ const destinationChain = this.chainService.getChainInfoByKey(destinationTokenInfo.originChain);
217
193
  const submitStep = {
218
194
  name: 'Swap',
219
195
  type: SwapStepType.SWAP,
196
+ // @ts-ignore
220
197
  metadata: {
221
198
  sendingValue: params.request.fromAmount.toString(),
222
- originTokenInfo: this.chainService.getAssetBySlug(params.selectedQuote.pair.from),
223
- destinationTokenInfo: this.chainService.getAssetBySlug(params.selectedQuote.pair.to),
199
+ expectedReceive: params.selectedQuote.toAmount,
200
+ originTokenInfo,
201
+ destinationTokenInfo,
202
+ sender: _reformatAddressWithChain(params.request.address, originChain),
203
+ receiver: _reformatAddressWithChain(params.request.recipient || params.request.address, destinationChain),
224
204
  srcChain: metadata.srcChain,
225
- destChain: metadata.destChain
205
+ destChain: metadata.destChain,
206
+ version: 2
226
207
  }
227
208
  };
228
209
  return Promise.resolve([submitStep, params.selectedQuote.feeInfo]);
229
210
  }
230
- generateOptimalProcess(params) {
231
- return this.swapBaseHandler.generateOptimalProcess(params, [this.getSubmitStep.bind(this)]);
232
- }
233
211
  generateOptimalProcessV2(params) {
234
212
  return this.swapBaseHandler.generateOptimalProcessV2(params, [this.getSubmitStep.bind(this)]);
235
213
  }
@@ -5,10 +5,9 @@ import FeeService from '@subwallet/extension-base/services/fee-service/service';
5
5
  import { SwapBaseInterface } from '@subwallet/extension-base/services/swap-service/handler/base-handler';
6
6
  import { OptimalSwapPathParamsV2, ValidateSwapProcessParams } from '@subwallet/extension-base/types';
7
7
  import { BaseStepDetail, CommonOptimalSwapPath, CommonStepFeeInfo } from '@subwallet/extension-base/types/service-base';
8
- import { OptimalSwapPathParams, SwapProviderId, SwapSubmitParams, SwapSubmitStepData } from '@subwallet/extension-base/types/swap';
8
+ import { SwapProviderId, SwapSubmitParams, SwapSubmitStepData } from '@subwallet/extension-base/types/swap';
9
9
  export declare class HydradxHandler implements SwapBaseInterface {
10
10
  private swapBaseHandler;
11
- private tradeRouter;
12
11
  private readonly isTestnet;
13
12
  isReady: boolean;
14
13
  providerSlug: SwapProviderId;
@@ -20,18 +19,12 @@ export declare class HydradxHandler implements SwapBaseInterface {
20
19
  get providerInfo(): import("@subwallet/extension-base/types").SwapProvider;
21
20
  get name(): string;
22
21
  get slug(): string;
23
- getXcmStep(params: OptimalSwapPathParams): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
24
- getFeeOptionStep(params: OptimalSwapPathParams): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
25
- getSubmitStep(params: OptimalSwapPathParams): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
26
- getXcmStepV2(params: OptimalSwapPathParamsV2): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
27
- getSwapStepV2(params: OptimalSwapPathParamsV2): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
28
- generateOptimalProcess(params: OptimalSwapPathParams): Promise<CommonOptimalSwapPath>;
22
+ getFeeOptionStep(params: OptimalSwapPathParamsV2): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
23
+ getSubmitStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
29
24
  generateOptimalProcessV2(params: OptimalSwapPathParamsV2): Promise<CommonOptimalSwapPath>;
30
- handleXcmStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
31
25
  handleSetFeeStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
32
26
  handleSubmitStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
33
27
  handleSwapProcess(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
34
- validateSwapProcess(params: ValidateSwapProcessParams): Promise<TransactionError[]>;
35
28
  validateSwapProcessV2(params: ValidateSwapProcessParams): Promise<TransactionError[]>;
36
29
  get referralCode(): "WALLET" | "ASSETHUB";
37
30
  get referralAccount(): "7PCsCpkgsHdNaZhv79wCCQ5z97uxVbSeSCtDMUa1eZHKXy4a" | "7LCt6dFqtxzdKVB2648jWW9d85doiFfLSbZJDNAMVJNxh5rJ";
@@ -1,22 +1,19 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { PoolService, TradeRouter } from '@galacticcouncil/sdk';
5
4
  import { COMMON_CHAIN_SLUGS } from '@subwallet/chain-list';
6
5
  import { SwapError } from '@subwallet/extension-base/background/errors/SwapError';
7
6
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
8
7
  import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
9
- import { XCM_MIN_AMOUNT_RATIO } from '@subwallet/extension-base/constants';
10
- import { createXcmExtrinsic } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
11
- import { _getChainNativeTokenSlug, _getTokenMinAmount, _getTokenOnChainAssetId, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
8
+ import { _getTokenOnChainAssetId, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
12
9
  import { SwapBaseHandler } from '@subwallet/extension-base/services/swap-service/handler/base-handler';
13
- import { DynamicSwapType } from '@subwallet/extension-base/services/swap-service/interface';
14
- import { FEE_RATE_MULTIPLIER, getSwapAlternativeAsset } from '@subwallet/extension-base/services/swap-service/utils';
15
- import { BasicTxErrorType } from '@subwallet/extension-base/types';
10
+ import { DEFAULT_EXCESS_AMOUNT_WEIGHT } from '@subwallet/extension-base/services/swap-service/utils';
11
+ import { BasicTxErrorType, DynamicSwapType } from '@subwallet/extension-base/types';
16
12
  import { CommonStepType } from '@subwallet/extension-base/types/service-base';
17
13
  import { SwapErrorType, SwapFeeType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types/swap';
18
- import { getId } from '@subwallet/extension-base/utils/getId';
19
- import BigNumber from 'bignumber.js';
14
+ import { _reformatAddressWithChain } from '@subwallet/extension-base/utils';
15
+ import subwalletApiSdk from '@subwallet/subwallet-api-sdk';
16
+ import BigN from 'bignumber.js';
20
17
  import { isHex } from '@polkadot/util';
21
18
  const HYDRADX_SUBWALLET_REFERRAL_CODE = 'WALLET';
22
19
  const HYDRADX_SUBWALLET_REFERRAL_ACCOUNT = '7PCsCpkgsHdNaZhv79wCCQ5z97uxVbSeSCtDMUa1eZHKXy4a';
@@ -41,10 +38,6 @@ export class HydradxHandler {
41
38
  if (!chainState.active) {
42
39
  await this.chainService.enableChain(this.chain());
43
40
  }
44
- const substrateApi = this.chainService.getSubstrateApi(this.chain());
45
- await substrateApi.api.isReady;
46
- const poolService = new PoolService(substrateApi.api);
47
- this.tradeRouter = new TradeRouter(poolService);
48
41
  this.isReady = true;
49
42
  }
50
43
  chain = () => {
@@ -70,75 +63,6 @@ export class HydradxHandler {
70
63
  get slug() {
71
64
  return this.swapBaseHandler.slug;
72
65
  }
73
- async getXcmStep(params) {
74
- const bnAmount = new BigNumber(params.request.fromAmount);
75
- const fromAsset = this.chainService.getAssetBySlug(params.request.pair.from);
76
- const fromAssetBalance = await this.balanceService.getTransferableBalance(params.request.address, fromAsset.originChain, fromAsset.slug);
77
- const bnFromAssetBalance = new BigNumber(fromAssetBalance.value);
78
- if (bnFromAssetBalance.gte(bnAmount)) {
79
- return undefined; // enough balance, no need to xcm
80
- }
81
-
82
- const alternativeAssetSlug = getSwapAlternativeAsset(params.request.pair);
83
- if (!alternativeAssetSlug) {
84
- return undefined;
85
- }
86
- const alternativeAsset = this.chainService.getAssetBySlug(alternativeAssetSlug);
87
- const alternativeAssetBalance = await this.balanceService.getTransferableBalance(params.request.address, alternativeAsset.originChain, alternativeAsset.slug);
88
- const bnAlternativeAssetBalance = new BigNumber(alternativeAssetBalance.value);
89
- if (bnAlternativeAssetBalance.lte(0)) {
90
- return undefined;
91
- }
92
- try {
93
- const alternativeChainInfo = this.chainService.getChainInfoByKey(alternativeAsset.originChain);
94
- const destChainInfo = this.chainService.getChainInfoByKey(this.chain());
95
- const xcmOriginSubstrateApi = await this.chainService.getSubstrateApi(alternativeAsset.originChain).isReady;
96
- const id = getId();
97
- const feeInfo = await this.swapBaseHandler.feeService.subscribeChainFee(id, alternativeAsset.originChain, 'substrate');
98
- const xcmTransfer = await createXcmExtrinsic({
99
- originTokenInfo: alternativeAsset,
100
- destinationTokenInfo: fromAsset,
101
- // Mock sending value to get payment info
102
- sendingValue: bnAmount.toString(),
103
- recipient: params.request.address,
104
- substrateApi: xcmOriginSubstrateApi,
105
- sender: params.request.address,
106
- destinationChain: destChainInfo,
107
- originChain: alternativeChainInfo,
108
- feeInfo
109
- });
110
- const _xcmFeeInfo = await xcmTransfer.paymentInfo(params.request.address);
111
- const xcmFeeInfo = _xcmFeeInfo.toPrimitive();
112
- const fee = {
113
- feeComponent: [{
114
- feeType: SwapFeeType.NETWORK_FEE,
115
- amount: Math.round(xcmFeeInfo.partialFee * XCM_MIN_AMOUNT_RATIO).toString(),
116
- tokenSlug: _getChainNativeTokenSlug(alternativeChainInfo)
117
- }],
118
- defaultFeeToken: _getChainNativeTokenSlug(alternativeChainInfo),
119
- feeOptions: [_getChainNativeTokenSlug(alternativeChainInfo)]
120
- };
121
- let bnTransferAmount = bnAmount.minus(bnFromAssetBalance);
122
- if (_isNativeToken(alternativeAsset)) {
123
- const bnXcmFee = new BigNumber(fee.feeComponent[0].amount); // xcm fee is paid in native token but swap token is not always native token
124
-
125
- bnTransferAmount = bnTransferAmount.plus(bnXcmFee);
126
- }
127
- const step = {
128
- metadata: {
129
- sendingValue: bnTransferAmount.toString(),
130
- originTokenInfo: alternativeAsset,
131
- destinationTokenInfo: fromAsset
132
- },
133
- name: `Transfer ${alternativeAsset.symbol} from ${alternativeChainInfo.name}`,
134
- type: CommonStepType.XCM
135
- };
136
- return [step, fee];
137
- } catch (e) {
138
- console.error('Error creating xcm step', e);
139
- return undefined;
140
- }
141
- }
142
66
  async getFeeOptionStep(params) {
143
67
  if (!params.selectedQuote) {
144
68
  return Promise.resolve(undefined);
@@ -179,173 +103,94 @@ export class HydradxHandler {
179
103
  return undefined;
180
104
  }
181
105
  }
182
- async getSubmitStep(params) {
183
- if (params.selectedQuote) {
184
- const submitStep = {
185
- name: 'Swap',
186
- type: SwapStepType.SWAP
187
- };
188
- return Promise.resolve([submitStep, params.selectedQuote.feeInfo]);
189
- }
190
- return Promise.resolve(undefined);
191
- }
192
- async getXcmStepV2(params) {
193
- var _params$path$find;
194
- // todo: improve this function for Round 2
195
-
196
- 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;
197
- if (!xcmPairInfo) {
198
- return undefined;
199
- }
200
- const fromTokenInfo = this.chainService.getAssetBySlug(xcmPairInfo.from);
201
- const toTokenInfo = this.chainService.getAssetBySlug(xcmPairInfo.to);
202
- const fromChainInfo = this.chainService.getChainInfoByKey(fromTokenInfo.originChain);
203
- const toChainInfo = this.chainService.getChainInfoByKey(toTokenInfo.originChain);
204
- if (!fromChainInfo || !toChainInfo || !fromChainInfo || !toChainInfo) {
205
- throw Error('Token and chain not found');
206
- }
207
- try {
208
- const substrateApi = await this.chainService.getSubstrateApi(fromTokenInfo.originChain).isReady;
209
- const id = getId();
210
- 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)]);
211
- const xcmTransfer = await createXcmExtrinsic({
212
- originTokenInfo: fromTokenInfo,
213
- destinationTokenInfo: toTokenInfo,
214
- // Mock sending value to get payment info
215
- sendingValue: params.request.fromAmount,
216
- recipient: params.request.address,
217
- substrateApi: substrateApi,
218
- sender: params.request.address,
219
- originChain: fromChainInfo,
220
- destinationChain: toChainInfo,
221
- feeInfo
222
- });
223
- const _xcmFeeInfo = await xcmTransfer.paymentInfo(params.request.address);
224
- const xcmFeeInfo = _xcmFeeInfo.toPrimitive();
225
- const fee = {
226
- feeComponent: [{
227
- feeType: SwapFeeType.NETWORK_FEE,
228
- amount: Math.ceil(xcmFeeInfo.partialFee * FEE_RATE_MULTIPLIER.high).toString(),
229
- tokenSlug: _getChainNativeTokenSlug(fromChainInfo)
230
- }],
231
- defaultFeeToken: _getChainNativeTokenSlug(fromChainInfo),
232
- feeOptions: [_getChainNativeTokenSlug(fromChainInfo)]
233
- };
234
- let bnTransferAmount = new BigNumber(params.request.fromAmount);
235
-
236
- // todo: increase transfer amount when XCM local token
237
- if (_isNativeToken(fromTokenInfo)) {
238
- // xcm fee is paid in native token but swap token is not always native token
239
- // add amount of fee into sending value to ensure has enough token to swap
240
- const bnXcmFee = new BigNumber(fee.feeComponent[0].amount);
241
- bnTransferAmount = bnTransferAmount.plus(bnXcmFee);
242
- } else {
243
- bnTransferAmount = bnTransferAmount.plus(BigNumber(_getTokenMinAmount(toTokenInfo)).multipliedBy(FEE_RATE_MULTIPLIER.medium));
244
- }
245
- if (BigNumber(toTokenBalance.value).lte(0)) {
246
- bnTransferAmount = bnTransferAmount.plus(_getTokenMinAmount(toTokenInfo));
247
- }
248
- const step = {
249
- metadata: {
250
- sendingValue: bnTransferAmount.toString(),
251
- originTokenInfo: fromTokenInfo,
252
- destinationTokenInfo: toTokenInfo
253
- },
254
- name: `Transfer ${fromTokenInfo.symbol} from ${fromChainInfo.name}`,
255
- type: CommonStepType.XCM
256
- };
257
- return [step, fee];
258
- } catch (e) {
259
- console.error('Error creating xcm step', e);
260
- return undefined;
106
+ async getSubmitStep(params, stepIndex) {
107
+ var _params$selectedQuote;
108
+ const {
109
+ path,
110
+ request: {
111
+ fromAmount
112
+ },
113
+ selectedQuote
114
+ } = params;
115
+ const stepData = path[stepIndex];
116
+ if (stepData.action !== DynamicSwapType.SWAP) {
117
+ return Promise.resolve(undefined);
261
118
  }
262
- }
263
- async getSwapStepV2(params) {
264
- var _params$path$find2;
265
- 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;
266
- if (!swapPairInfo) {
119
+ if (!selectedQuote) {
267
120
  return Promise.resolve(undefined);
268
121
  }
269
- if (!params.selectedQuote) {
122
+ const swapPairInfo = stepData.pair;
123
+ if (!swapPairInfo || !selectedQuote) {
270
124
  return Promise.resolve(undefined);
271
125
  }
272
- const txHex = params.selectedQuote.metadata;
126
+ const originTokenInfo = this.chainService.getAssetBySlug(swapPairInfo.from);
127
+ const destinationTokenInfo = this.chainService.getAssetBySlug(swapPairInfo.to);
128
+ const originChain = this.chainService.getChainInfoByKey(originTokenInfo.originChain);
129
+ const destinationChain = this.chainService.getChainInfoByKey(destinationTokenInfo.originChain);
130
+ const sender = _reformatAddressWithChain(params.request.address, originChain);
131
+ let receiver = _reformatAddressWithChain(params.request.recipient || params.request.address, destinationChain);
132
+ const actionList = JSON.stringify(path.map(step => step.action));
133
+ const xcmSwapXcm = actionList === JSON.stringify([DynamicSwapType.BRIDGE, DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
134
+ const swapXcm = actionList === JSON.stringify([DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
135
+ const needModifyData = swapXcm || xcmSwapXcm;
136
+ let txHex = (_params$selectedQuote = params.selectedQuote) === null || _params$selectedQuote === void 0 ? void 0 : _params$selectedQuote.metadata;
137
+ let bnSendingValue = BigN(fromAmount);
138
+ let bnExpectedReceive = BigN(selectedQuote.toAmount);
139
+ if (needModifyData) {
140
+ var _subwalletApiSdk$swap;
141
+ // override info if xcm-swap-xcm
142
+ bnSendingValue = bnSendingValue.multipliedBy(DEFAULT_EXCESS_AMOUNT_WEIGHT);
143
+ bnExpectedReceive = bnExpectedReceive.multipliedBy(DEFAULT_EXCESS_AMOUNT_WEIGHT);
144
+ const quotes = await ((_subwalletApiSdk$swap = subwalletApiSdk.swapApi) === null || _subwalletApiSdk$swap === void 0 ? void 0 : _subwalletApiSdk$swap.fetchSwapQuoteData({
145
+ address: sender,
146
+ pair: {
147
+ from: swapPairInfo.from,
148
+ to: swapPairInfo.to,
149
+ slug: swapPairInfo.slug
150
+ },
151
+ fromAmount: bnSendingValue.toFixed(0, 1),
152
+ slippage: params.request.slippage
153
+ }));
154
+ const quoteAskResponse = quotes === null || quotes === void 0 ? void 0 : quotes.find(quote => quote.provider === this.providerSlug);
155
+ if (!quoteAskResponse || !quoteAskResponse.quote) {
156
+ return Promise.resolve(undefined);
157
+ }
158
+ const overrideQuote = quoteAskResponse.quote;
159
+ txHex = overrideQuote.metadata;
160
+ receiver = _reformatAddressWithChain(params.request.address, destinationChain);
161
+ }
273
162
  if (!txHex || !isHex(txHex)) {
274
163
  return Promise.resolve(undefined);
275
164
  }
276
- const metadata = {
277
- sendingValue: params.request.fromAmount.toString(),
278
- originTokenInfo: this.chainService.getAssetBySlug(swapPairInfo.from),
279
- destinationTokenInfo: this.chainService.getAssetBySlug(swapPairInfo.to),
280
- txHex
281
- };
282
165
  const submitStep = {
283
166
  name: 'Swap',
284
167
  type: SwapStepType.SWAP,
285
168
  // @ts-ignore
286
- metadata
169
+ metadata: {
170
+ sendingValue: bnSendingValue.toFixed(0, 1),
171
+ expectedReceive: bnExpectedReceive.toFixed(0, 1),
172
+ originTokenInfo,
173
+ destinationTokenInfo,
174
+ sender,
175
+ receiver,
176
+ txHex,
177
+ version: 2
178
+ }
287
179
  };
288
- return Promise.resolve([submitStep, params.selectedQuote.feeInfo]); // review fee
289
- }
290
-
291
- generateOptimalProcess(params) {
292
- return this.swapBaseHandler.generateOptimalProcess(params, [this.getXcmStep.bind(this),
293
- // this.getFeeOptionStep.bind(this),
294
- this.getSubmitStep.bind(this)]);
180
+ return Promise.resolve([submitStep, selectedQuote.feeInfo]);
295
181
  }
296
182
  generateOptimalProcessV2(params) {
297
183
  const stepFuncList = params.path.map(step => {
298
- if (step.action === DynamicSwapType.BRIDGE) {
299
- return this.getXcmStepV2.bind(this);
300
- }
301
184
  if (step.action === DynamicSwapType.SWAP) {
302
- return this.getSwapStepV2.bind(this);
185
+ return this.getSubmitStep.bind(this);
186
+ }
187
+ if (step.action === DynamicSwapType.BRIDGE) {
188
+ return this.swapBaseHandler.getBridgeStep.bind(this.swapBaseHandler);
303
189
  }
304
190
  throw new Error(`Error generating optimal process: Action ${step.action} is not supported`);
305
191
  });
306
192
  return this.swapBaseHandler.generateOptimalProcessV2(params, stepFuncList);
307
193
  }
308
- async handleXcmStep(params) {
309
- const briefXcmStep = params.process.steps[params.currentStep].metadata;
310
- if (!briefXcmStep || !briefXcmStep.originTokenInfo || !briefXcmStep.destinationTokenInfo || !briefXcmStep.sendingValue) {
311
- throw new Error('XCM metadata error');
312
- }
313
- const originAsset = briefXcmStep.originTokenInfo;
314
- const destinationAsset = briefXcmStep.destinationTokenInfo;
315
- const originChain = this.chainService.getChainInfoByKey(originAsset.originChain);
316
- const destinationChain = this.chainService.getChainInfoByKey(destinationAsset.originChain);
317
- const substrateApi = this.chainService.getSubstrateApi(originAsset.originChain);
318
- const chainApi = await substrateApi.isReady;
319
- const feeInfo = await this.swapBaseHandler.feeService.subscribeChainFee(getId(), originAsset.originChain, 'substrate');
320
- const xcmTransfer = await createXcmExtrinsic({
321
- originTokenInfo: originAsset,
322
- destinationTokenInfo: destinationAsset,
323
- sendingValue: briefXcmStep.sendingValue,
324
- recipient: params.address,
325
- substrateApi: chainApi,
326
- sender: params.address,
327
- destinationChain,
328
- originChain,
329
- feeInfo
330
- });
331
- const xcmData = {
332
- originNetworkKey: originAsset.originChain,
333
- destinationNetworkKey: destinationAsset.originChain,
334
- from: params.address,
335
- to: params.address,
336
- value: briefXcmStep.sendingValue,
337
- tokenSlug: originAsset.slug,
338
- showExtraWarning: true
339
- };
340
- return {
341
- txChain: originAsset.originChain,
342
- extrinsic: xcmTransfer,
343
- transferNativeAmount: _isNativeToken(originAsset) ? briefXcmStep.sendingValue : '0',
344
- extrinsicType: ExtrinsicType.TRANSFER_XCM,
345
- chainType: ChainType.SUBSTRATE,
346
- txData: xcmData
347
- };
348
- }
349
194
  async handleSetFeeStep(params) {
350
195
  var _swapFeeInfo$selected;
351
196
  const substrateApi = this.chainService.getSubstrateApi(this.chain());
@@ -372,7 +217,7 @@ export class HydradxHandler {
372
217
  }
373
218
  async handleSubmitStep(params) {
374
219
  const metadata = params.process.steps[params.currentStep].metadata;
375
- const txHex = params.quote.metadata;
220
+ const txHex = metadata.txHex;
376
221
  if (!txHex || !isHex(txHex)) {
377
222
  return new SwapError(SwapErrorType.UNKNOWN);
378
223
  }
@@ -380,7 +225,7 @@ export class HydradxHandler {
380
225
  throw new Error('Swap metadata error');
381
226
  }
382
227
  const fromAsset = metadata.originTokenInfo;
383
- if (!this.isReady || !this.tradeRouter) {
228
+ if (!this.isReady) {
384
229
  return new SwapError(SwapErrorType.UNKNOWN);
385
230
  }
386
231
  const substrateApi = this.chainService.getSubstrateApi(this.chain());
@@ -433,7 +278,7 @@ export class HydradxHandler {
433
278
  case CommonStepType.DEFAULT:
434
279
  return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
435
280
  case CommonStepType.XCM:
436
- return this.handleXcmStep(params);
281
+ return this.swapBaseHandler.handleBridgeStep(params);
437
282
  case CommonStepType.SET_FEE_TOKEN:
438
283
  return this.handleSetFeeStep(params);
439
284
  case SwapStepType.SWAP:
@@ -442,43 +287,6 @@ export class HydradxHandler {
442
287
  return this.handleSubmitStep(params);
443
288
  }
444
289
  }
445
- async validateSwapProcess(params) {
446
- const amount = params.selectedQuote.fromAmount;
447
- const bnAmount = new BigNumber(amount);
448
- if (bnAmount.lte(0)) {
449
- return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')];
450
- }
451
- const swapStep = params.process.steps.find(item => item.type === SwapStepType.SWAP);
452
- if (!swapStep) {
453
- return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR, 'Swap step not found')];
454
- }
455
- let isXcmOk = false;
456
- const currentStep = params.currentStep;
457
- for (const [index, step] of params.process.steps.entries()) {
458
- if (currentStep > index) {
459
- continue;
460
- }
461
- const getErrors = async () => {
462
- switch (step.type) {
463
- case CommonStepType.DEFAULT:
464
- return Promise.resolve([]);
465
- case CommonStepType.XCM:
466
- return this.swapBaseHandler.validateXcmStepV2(params, index);
467
- case CommonStepType.SET_FEE_TOKEN:
468
- return this.swapBaseHandler.validateSetFeeTokenStep(params, index);
469
- default:
470
- return this.swapBaseHandler.validateSwapStep(params, isXcmOk, index);
471
- }
472
- };
473
- const errors = await getErrors();
474
- if (errors.length) {
475
- return errors;
476
- } else if (step.type === CommonStepType.XCM) {
477
- isXcmOk = true;
478
- }
479
- }
480
- return [];
481
- }
482
290
  async validateSwapProcessV2(params) {
483
291
  // todo: recheck address and recipient format in params
484
292
  const {
@@ -488,7 +296,7 @@ export class HydradxHandler {
488
296
 
489
297
  // todo: validate path with optimalProcess
490
298
  // todo: review error message in case many step swap
491
- if (BigNumber(selectedQuote.fromAmount).lte(0)) {
299
+ if (BigN(selectedQuote.fromAmount).lte(0)) {
492
300
  return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')];
493
301
  }
494
302
  const actionList = JSON.stringify(process.path.map(step => step.action));
@@ -501,13 +309,13 @@ export class HydradxHandler {
501
309
  }
502
310
 
503
311
  if (swapXcm) {
504
- return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
312
+ return this.swapBaseHandler.validateSwapXcmProcess(params, 1, 2);
505
313
  }
506
314
  if (xcmSwap) {
507
315
  return this.swapBaseHandler.validateXcmSwapProcess(params, 2, 1);
508
316
  }
509
317
  if (xcmSwapXcm) {
510
- return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
318
+ return this.swapBaseHandler.validateXcmSwapXcmProcess(params, 2, 1, 3);
511
319
  }
512
320
  return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
513
321
  }
@@ -1,6 +1,6 @@
1
1
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
2
2
  import FeeService from '@subwallet/extension-base/services/fee-service/service';
3
- import { BaseStepDetail, CommonOptimalSwapPath, CommonStepFeeInfo, OptimalSwapPathParams, OptimalSwapPathParamsV2, SwapProviderId, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types';
3
+ import { BaseStepDetail, CommonOptimalSwapPath, CommonStepFeeInfo, OptimalSwapPathParamsV2, SwapProviderId, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types';
4
4
  import { BalanceService } from '../../balance-service';
5
5
  import { ChainService } from '../../chain-service';
6
6
  import { SwapBaseInterface } from './base-handler';
@@ -9,15 +9,13 @@ export declare class SimpleSwapHandler implements SwapBaseInterface {
9
9
  private swapBaseHandler;
10
10
  providerSlug: SwapProviderId;
11
11
  constructor(chainService: ChainService, balanceService: BalanceService, feeService: FeeService);
12
- validateSwapProcess(params: ValidateSwapProcessParams): Promise<TransactionError[]>;
13
12
  get chainService(): ChainService;
14
13
  get balanceService(): BalanceService;
15
14
  get providerInfo(): import("@subwallet/extension-base/types").SwapProvider;
16
15
  get name(): string;
17
16
  get slug(): string;
18
- generateOptimalProcess(params: OptimalSwapPathParams): Promise<CommonOptimalSwapPath>;
19
17
  generateOptimalProcessV2(params: OptimalSwapPathParamsV2): Promise<CommonOptimalSwapPath>;
20
- getSubmitStep(params: OptimalSwapPathParams): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
18
+ getSubmitStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
21
19
  handleSwapProcess(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
22
20
  handleSubmitStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
23
21
  validateSwapProcessV2(params: ValidateSwapProcessParams): Promise<TransactionError[]>;