@subwallet/extension-base 1.3.39-0 → 1.3.40-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 (29) hide show
  1. package/cjs/koni/background/handlers/Extension.js +79 -69
  2. package/cjs/packageInfo.js +1 -1
  3. package/cjs/services/balance-service/transfer/xcm/index.js +19 -28
  4. package/cjs/services/balance-service/transfer/xcm/utils.js +47 -49
  5. package/cjs/services/chain-service/constants.js +2 -2
  6. package/cjs/services/chain-service/index.js +4 -0
  7. package/cjs/services/chain-service/utils/patch.js +1 -1
  8. package/cjs/services/earning-service/handlers/special.js +28 -36
  9. package/cjs/services/swap-service/handler/base-handler.js +58 -53
  10. package/cjs/services/swap-service/handler/kyber-handler.js +44 -28
  11. package/cjs/services/swap-service/handler/simpleswap-handler.js +79 -40
  12. package/cjs/services/swap-service/utils.js +2 -0
  13. package/cjs/utils/fee/transfer.js +41 -33
  14. package/koni/background/handlers/Extension.js +15 -5
  15. package/package.json +7 -7
  16. package/packageInfo.js +1 -1
  17. package/services/balance-service/transfer/xcm/index.d.ts +1 -2
  18. package/services/balance-service/transfer/xcm/index.js +16 -25
  19. package/services/balance-service/transfer/xcm/utils.d.ts +36 -6
  20. package/services/balance-service/transfer/xcm/utils.js +46 -48
  21. package/services/chain-service/constants.js +2 -2
  22. package/services/chain-service/index.js +4 -0
  23. package/services/chain-service/utils/patch.js +1 -1
  24. package/services/earning-service/handlers/special.js +12 -20
  25. package/services/swap-service/handler/base-handler.js +11 -6
  26. package/services/swap-service/handler/kyber-handler.js +44 -28
  27. package/services/swap-service/handler/simpleswap-handler.js +80 -41
  28. package/services/swap-service/utils.js +2 -0
  29. package/utils/fee/transfer.js +11 -3
@@ -1,13 +1,12 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { XCM_MIN_AMOUNT_RATIO } from '@subwallet/extension-base/constants';
5
4
  import { _isAcrossBridgeXcm, _isPolygonBridgeXcm, _isPosBridgeXcm, _isSnowBridgeXcm } from '@subwallet/extension-base/core/substrate/xcm-parser';
6
5
  import { getAvailBridgeExtrinsicFromAvail, getAvailBridgeTxFromEth } from '@subwallet/extension-base/services/balance-service/transfer/xcm/availBridge';
7
6
  import { getExtrinsicByPolkadotXcmPallet } from '@subwallet/extension-base/services/balance-service/transfer/xcm/polkadotXcm';
8
7
  import { _createPolygonBridgeL1toL2Extrinsic, _createPolygonBridgeL2toL1Extrinsic } from '@subwallet/extension-base/services/balance-service/transfer/xcm/polygonBridge';
9
8
  import { getSnowBridgeEvmTransfer } from '@subwallet/extension-base/services/balance-service/transfer/xcm/snowBridge';
10
- import { buildXcm, dryRunXcmV2, isChainNotSupportDryRun, isChainNotSupportPolkadotApi } from '@subwallet/extension-base/services/balance-service/transfer/xcm/utils';
9
+ import { buildXcm, dryRunXcm, isChainNotSupportDryRun, isChainNotSupportPolkadotApi } from '@subwallet/extension-base/services/balance-service/transfer/xcm/utils';
11
10
  import { getExtrinsicByXcmPalletPallet } from '@subwallet/extension-base/services/balance-service/transfer/xcm/xcmPallet';
12
11
  import { getExtrinsicByXtokensPallet } from '@subwallet/extension-base/services/balance-service/transfer/xcm/xTokens';
13
12
  import { _XCM_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants';
@@ -39,6 +38,8 @@ export const createSnowBridgeExtrinsic = async ({
39
38
  }
40
39
  return getSnowBridgeEvmTransfer(originTokenInfo, originChain, destinationChain, sender, recipient, sendingValue, evmApi, feeInfo, feeCustom, feeOption);
41
40
  };
41
+
42
+ // deprecated
42
43
  export const createXcmExtrinsic = async ({
43
44
  destinationChain,
44
45
  originChain,
@@ -121,37 +122,27 @@ export const createXcmExtrinsicV2 = async request => {
121
122
  return await buildXcm(request);
122
123
  } catch (e) {
123
124
  console.log('createXcmExtrinsicV2 error: ', e);
124
- const errorMessage = e instanceof Error ? e.message : 'Unknown error occurred';
125
- if (isChainNotSupportPolkadotApi(errorMessage)) {
126
- return createXcmExtrinsic(request);
127
- }
128
125
  return undefined;
129
126
  }
130
127
  };
131
128
  export const dryRunXcmExtrinsicV2 = async request => {
132
129
  try {
133
- return await dryRunXcmV2(request);
134
- } catch (e) {
135
- const errorMessage = e instanceof Error ? e.message : 'Unknown error occurred';
136
- if (isChainNotSupportDryRun(errorMessage) || isChainNotSupportPolkadotApi(errorMessage)) {
137
- const xcmTransfer = await createXcmExtrinsicV2(request);
138
- if (!xcmTransfer) {
139
- return {
140
- success: false
141
- };
130
+ const dryRunResult = await dryRunXcm(request);
131
+ const originDryRunResult = dryRunResult.origin;
132
+ if (originDryRunResult.success) {
133
+ const destinationDryRunResult = dryRunResult.destination;
134
+ if (destinationDryRunResult.success) {
135
+ return true;
142
136
  }
143
- const _xcmFeeInfo = await xcmTransfer.paymentInfo(request.sender);
144
- const xcmFeeInfo = _xcmFeeInfo.toPrimitive();
145
137
 
146
- // skip dry run in this case
147
- return {
148
- success: true,
149
- fee: Math.round(xcmFeeInfo.partialFee * XCM_MIN_AMOUNT_RATIO).toString()
150
- };
138
+ // pass dry-run in these cases
139
+ return isChainNotSupportDryRun(destinationDryRunResult.failureReason) || isChainNotSupportPolkadotApi(destinationDryRunResult.failureReason);
151
140
  }
152
- return {
153
- success: false
154
- };
141
+
142
+ // pass dry-run in these cases
143
+ return isChainNotSupportDryRun(originDryRunResult.failureReason) || isChainNotSupportPolkadotApi(originDryRunResult.failureReason);
144
+ } catch (e) {
145
+ return false;
155
146
  }
156
147
  };
157
148
  export const createAcrossBridgeExtrinsic = async ({
@@ -1,14 +1,44 @@
1
- import { _ChainInfo } from '@subwallet/chain-list/types';
1
+ import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import { CreateXcmExtrinsicProps } from '@subwallet/extension-base/services/balance-service/transfer/xcm/index';
3
3
  import { SubmittableExtrinsic } from '@polkadot/api/types';
4
- export interface DryRunInfo {
5
- success: boolean;
6
- fee?: string;
4
+ export declare type DryRunNodeFailure = {
5
+ success: false;
6
+ failureReason: string;
7
+ };
8
+ export declare type DryRunNodeSuccess = {
9
+ success: true;
10
+ fee: string;
11
+ forwardedXcms: any;
12
+ };
13
+ export declare type DryRunNodeResult = DryRunNodeSuccess | DryRunNodeFailure;
14
+ export declare type DryRunResult = {
15
+ origin: DryRunNodeResult;
16
+ destination?: DryRunNodeResult;
17
+ };
18
+ interface GetXcmFeeRequest {
19
+ sender: string;
20
+ recipient: string;
21
+ value: string;
22
+ fromChainInfo: _ChainInfo;
23
+ toChainInfo: _ChainInfo;
24
+ fromTokenInfo: _ChainAsset;
7
25
  }
26
+ export declare type XcmFeeType = 'dryRun' | 'paymentInfo';
27
+ export interface XcmFeeDetail {
28
+ fee: string;
29
+ currency: string;
30
+ feeType: XcmFeeType;
31
+ dryRunError?: string;
32
+ }
33
+ export declare type GetXcmFeeResult = {
34
+ origin: XcmFeeDetail;
35
+ destination: XcmFeeDetail;
36
+ };
8
37
  export declare function buildXcm(request: CreateXcmExtrinsicProps): Promise<SubmittableExtrinsic<"promise", import("@polkadot/types/types").ISubmittableResult>>;
9
- export declare function dryRunXcm(request: CreateXcmExtrinsicProps): Promise<DryRunInfo>;
10
- export declare function dryRunXcmV2(request: CreateXcmExtrinsicProps): Promise<DryRunInfo>;
38
+ export declare function dryRunXcm(request: CreateXcmExtrinsicProps): Promise<DryRunResult>;
39
+ export declare function estimateXcmFee(request: GetXcmFeeRequest): Promise<GetXcmFeeResult | undefined>;
11
40
  export declare function isChainNotSupportPolkadotApi(str: string): boolean;
12
41
  export declare function isChainNotSupportDryRun(str: string): boolean;
13
42
  export declare const STABLE_XCM_VERSION = 3;
14
43
  export declare function isUseTeleportProtocol(originChainInfo: _ChainInfo, destChainInfo: _ChainInfo, tokenSlug?: string): boolean;
44
+ export {};
@@ -1,14 +1,13 @@
1
1
  // Copyright 2019-2022 @subwallet/extension-base
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
- import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
5
4
  import { fetchParaSpellChainMap } from '@subwallet/extension-base/constants/paraspell-chain-map';
6
- import { BasicTxErrorType } from '@subwallet/extension-base/types';
7
5
  import { assert, compactToU8a, isHex, u8aConcat, u8aEq } from '@polkadot/util';
8
- const paraSpellEndpoint = 'https://api.lightspell.xyz';
6
+ const paraSpellEndpoint = 'https://api.lightspell.xyz/v3';
9
7
  const paraSpellApi = {
10
8
  buildXcm: `${paraSpellEndpoint}/x-transfer`,
11
- dryRunXcm: `${paraSpellEndpoint}/dry-run`
9
+ dryRunXcm: `${paraSpellEndpoint}/dry-run`,
10
+ feeXcm: `${paraSpellEndpoint}/xcm-fee`
12
11
  };
13
12
  const paraSpellKey = process.env.PARASPELL_API_KEY || '';
14
13
  function txHexToSubmittableExtrinsic(api, hex) {
@@ -73,7 +72,7 @@ export async function buildXcm(request) {
73
72
  substrateApi
74
73
  } = request;
75
74
  if (!substrateApi) {
76
- return Promise.reject(new Error('Substrate API is not available'));
75
+ throw new Error('Substrate API is not available');
77
76
  }
78
77
  const psAssetType = (_originTokenInfo$meta = originTokenInfo.metadata) === null || _originTokenInfo$meta === void 0 ? void 0 : _originTokenInfo$meta.paraSpellAssetType;
79
78
  const psAssetValue = (_originTokenInfo$meta2 = originTokenInfo.metadata) === null || _originTokenInfo$meta2 === void 0 ? void 0 : _originTokenInfo$meta2.paraSpellValue;
@@ -104,8 +103,6 @@ export async function buildXcm(request) {
104
103
  const chainApi = await substrateApi.isReady;
105
104
  return txHexToSubmittableExtrinsic(chainApi.api, extrinsicHex);
106
105
  }
107
-
108
- // dry run can fail due to sender address & amount token
109
106
  export async function dryRunXcm(request) {
110
107
  var _originTokenInfo$meta3, _originTokenInfo$meta4;
111
108
  const {
@@ -120,60 +117,60 @@ export async function dryRunXcm(request) {
120
117
  const psAssetType = (_originTokenInfo$meta3 = originTokenInfo.metadata) === null || _originTokenInfo$meta3 === void 0 ? void 0 : _originTokenInfo$meta3.paraSpellAssetType;
121
118
  const psAssetValue = (_originTokenInfo$meta4 = originTokenInfo.metadata) === null || _originTokenInfo$meta4 === void 0 ? void 0 : _originTokenInfo$meta4.paraSpellValue;
122
119
  if (!psAssetType || !psAssetValue) {
123
- throw new Error('Token is not support XCM at this time'); // todo: content
120
+ throw new Error('Token is not support XCM at this time');
124
121
  }
125
-
126
- let dryRunInfo;
127
- try {
128
- const bodyData = {
129
- senderAddress: sender,
130
- address: recipient,
131
- from: paraSpellChainMap[originChain.slug],
132
- to: paraSpellChainMap[destinationChain.slug],
133
- currency: createParaSpellCurrency(psAssetType, psAssetValue, sendingValue)
134
- };
135
- const response = await fetch(paraSpellApi.dryRunXcm, {
136
- method: 'POST',
137
- body: JSON.stringify(bodyData),
138
- headers: {
139
- 'Content-Type': 'application/json',
140
- Accept: 'application/json',
141
- 'X-API-KEY': paraSpellKey
122
+ const bodyData = {
123
+ senderAddress: sender,
124
+ address: recipient,
125
+ from: paraSpellChainMap[originChain.slug],
126
+ to: paraSpellChainMap[destinationChain.slug],
127
+ currency: createParaSpellCurrency(psAssetType, psAssetValue, sendingValue)
128
+ };
129
+ const response = await fetch(paraSpellApi.dryRunXcm, {
130
+ method: 'POST',
131
+ body: JSON.stringify(bodyData),
132
+ headers: {
133
+ 'Content-Type': 'application/json',
134
+ Accept: 'application/json',
135
+ 'X-API-KEY': paraSpellKey
136
+ }
137
+ });
138
+ if (!response.ok) {
139
+ const error = await response.json();
140
+ return {
141
+ origin: {
142
+ success: false,
143
+ failureReason: error.message
142
144
  }
143
- });
144
- dryRunInfo = await response.json();
145
- } catch (e) {
146
- console.error('Unable to dry run', e);
147
- }
148
- if (!dryRunInfo || !dryRunInfo.success) {
149
- throw new TransactionError(BasicTxErrorType.UNABLE_TO_SEND, 'Unable to perform transaction. Select another token or destination chain and try again');
145
+ };
150
146
  }
151
- return dryRunInfo;
147
+ return await response.json();
152
148
  }
153
- export async function dryRunXcmV2(request) {
154
- var _originTokenInfo$meta5, _originTokenInfo$meta6;
149
+ export async function estimateXcmFee(request) {
150
+ var _fromTokenInfo$metada, _fromTokenInfo$metada2;
155
151
  const {
156
- destinationChain,
157
- originChain,
158
- originTokenInfo,
152
+ fromChainInfo,
153
+ fromTokenInfo,
159
154
  recipient,
160
155
  sender,
161
- sendingValue
156
+ toChainInfo,
157
+ value
162
158
  } = request;
163
159
  const paraSpellChainMap = await fetchParaSpellChainMap();
164
- const psAssetType = (_originTokenInfo$meta5 = originTokenInfo.metadata) === null || _originTokenInfo$meta5 === void 0 ? void 0 : _originTokenInfo$meta5.paraSpellAssetType;
165
- const psAssetValue = (_originTokenInfo$meta6 = originTokenInfo.metadata) === null || _originTokenInfo$meta6 === void 0 ? void 0 : _originTokenInfo$meta6.paraSpellValue;
160
+ const psAssetType = (_fromTokenInfo$metada = fromTokenInfo.metadata) === null || _fromTokenInfo$metada === void 0 ? void 0 : _fromTokenInfo$metada.paraSpellAssetType;
161
+ const psAssetValue = (_fromTokenInfo$metada2 = fromTokenInfo.metadata) === null || _fromTokenInfo$metada2 === void 0 ? void 0 : _fromTokenInfo$metada2.paraSpellValue;
166
162
  if (!psAssetType || !psAssetValue) {
167
- throw new Error('Token is not support XCM at this time');
163
+ console.error('Lack of paraspell metadata');
164
+ return undefined;
168
165
  }
169
166
  const bodyData = {
170
167
  senderAddress: sender,
171
168
  address: recipient,
172
- from: paraSpellChainMap[originChain.slug],
173
- to: paraSpellChainMap[destinationChain.slug],
174
- currency: createParaSpellCurrency(psAssetType, psAssetValue, sendingValue)
169
+ from: paraSpellChainMap[fromChainInfo.slug],
170
+ to: paraSpellChainMap[toChainInfo.slug],
171
+ currency: createParaSpellCurrency(psAssetType, psAssetValue, value)
175
172
  };
176
- const response = await fetch(paraSpellApi.dryRunXcm, {
173
+ const response = await fetch(paraSpellApi.feeXcm, {
177
174
  method: 'POST',
178
175
  body: JSON.stringify(bodyData),
179
176
  headers: {
@@ -183,13 +180,14 @@ export async function dryRunXcmV2(request) {
183
180
  }
184
181
  });
185
182
  if (!response.ok) {
186
- const error = await response.json();
187
- throw new Error(error.message);
183
+ console.error('Failed to request estimate fee');
184
+ return undefined;
188
185
  }
189
186
  return await response.json();
190
187
  }
191
188
  function createParaSpellCurrency(assetType, assetValue, amount) {
192
189
  // todo: handle complex conditions for asset has same symbol in a chain: Id, Multi-location, ...
190
+ // todo: or update all asset to use multi-location
193
191
  return {
194
192
  [assetType]: assetValue,
195
193
  amount
@@ -29,7 +29,7 @@ export const _BALANCE_CHAIN_GROUP = {
29
29
  kintsugi: ['kintsugi', 'interlay', 'kintsugi_test', 'mangatax_para'],
30
30
  genshiro: ['genshiro_testnet', 'genshiro'],
31
31
  equilibrium_parachain: ['equilibrium_parachain'],
32
- bifrost: ['bifrost', 'acala', 'karura', 'acala_testnet', 'pioneer', 'bitcountry', 'bifrost_dot', 'hydradx_main', 'hydradx_rococo', 'pendulum', 'amplitude', 'continuum_network', 'truth_network'],
32
+ bifrost: ['bifrost', 'acala', 'karura', 'acala_testnet', 'pioneer', 'bitcountry', 'bifrost_dot', 'hydradx_main', 'hydradx_rococo', 'pendulum', 'amplitude', 'continuum_network', 'truth_network', 'jamton'],
33
33
  statemine: ['statemine', 'astar', 'shiden', 'statemint', 'moonbeam', 'moonbase', 'moonriver', 'crabParachain', 'darwinia2', 'parallel', 'calamari', 'manta_network', 'rococo_assethub', 'liberlandTest', 'liberland', 'dentnet', 'pangolin', 'crust', 'phala', 'shibuya', 'dbcchain', 'westend_assethub'],
34
34
  kusama: ['kusama', 'kintsugi', 'kintsugi_test', 'interlay', 'acala', 'statemint', 'karura', 'bifrost'],
35
35
  // perhaps there are some runtime updates
@@ -258,7 +258,7 @@ export const _TRANSFER_CHAIN_GROUP = {
258
258
  riochain: ['riochain'],
259
259
  sora_substrate: ['sora_substrate'],
260
260
  avail: ['kate', 'goldberg_testnet'],
261
- pendulum: ['pendulum', 'amplitude', 'amplitude_test', 'hydradx_main', 'bifrost', 'bifrost_dot'],
261
+ pendulum: ['pendulum', 'amplitude', 'amplitude_test', 'hydradx_main', 'bifrost', 'bifrost_dot', 'jamton'],
262
262
  centrifuge: ['centrifuge'],
263
263
  disable_transfer: ['crab', 'pangolin']
264
264
  };
@@ -1233,6 +1233,10 @@ export class ChainService {
1233
1233
  deprecated = true;
1234
1234
  break;
1235
1235
  }
1236
+ if (defaultChainAsset.slug === storedAssetInfo.slug) {
1237
+ duplicated = true;
1238
+ break;
1239
+ }
1236
1240
  }
1237
1241
  if (!duplicated && !deprecated) {
1238
1242
  mergedAssetRegistry[storedAssetInfo.slug] = storedAssetInfo;
@@ -5,7 +5,7 @@ const PRODUCTION_BRANCHES = ['master', 'webapp', 'webapp-dev'];
5
5
  const branchName = process.env.BRANCH_NAME || 'subwallet-dev';
6
6
  const fetchDomain = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'https://chain-list-assets.subwallet.app' : 'https://dev.sw-chain-list-assets.pages.dev';
7
7
  const fetchFile = PRODUCTION_BRANCHES.indexOf(branchName) > -1 ? 'list.json' : 'preview.json';
8
- const ChainListVersion = '0.2.104'; // update this when build chainlist
8
+ const ChainListVersion = '0.2.105'; // update this when build chainlist
9
9
 
10
10
  // todo: move this interface to chainlist
11
11
 
@@ -5,7 +5,8 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
5
5
  import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
6
6
  import { ALL_ACCOUNT_KEY, XCM_FEE_RATIO, XCM_MIN_AMOUNT_RATIO } from '@subwallet/extension-base/constants';
7
7
  import { YIELD_POOL_STAT_REFRESH_INTERVAL } from '@subwallet/extension-base/koni/api/yield/helper/utils';
8
- import { createXcmExtrinsicV2, dryRunXcmExtrinsicV2 } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
8
+ import { createXcmExtrinsicV2 } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
9
+ import { estimateXcmFee } from '@subwallet/extension-base/services/balance-service/transfer/xcm/utils';
9
10
  import { _getAssetDecimals, _getAssetExistentialDeposit, _getAssetName, _getAssetSymbol, _getChainNativeTokenSlug, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
10
11
  import { BasicTxErrorType, YieldStepType, YieldValidationStatus } from '@subwallet/extension-base/types';
11
12
  import { createPromiseHandler, formatNumber } from '@subwallet/extension-base/utils';
@@ -217,29 +218,20 @@ export default class BaseSpecialStakingPoolHandler extends BasePoolHandler {
217
218
  const altChainInfo = this.state.getChainInfo(altInputTokenInfo.originChain);
218
219
  const symbol = altInputTokenInfo.symbol;
219
220
  const networkName = altChainInfo.name;
220
- const xcmOriginSubstrateApi = await this.state.getSubstrateApi(altInputTokenInfo.originChain).isReady;
221
- const id = getId();
222
- const feeInfo = await this.state.feeService.subscribeChainFee(id, altChainInfo.slug, 'substrate');
223
- const xcmRequest = {
224
- sender: address,
225
- originTokenInfo: altInputTokenInfo,
226
- destinationTokenInfo: inputTokenInfo,
227
- sendingValue: bnAmount.toString(),
228
- recipient: address,
229
- destinationChain: this.chainInfo,
230
- originChain: altChainInfo,
231
- substrateApi: xcmOriginSubstrateApi,
232
- feeInfo
233
- };
234
221
 
235
222
  // TODO: calculate fee for destination chain
236
- let xcmFee;
237
- const xcmFeeByDryRun = await dryRunXcmExtrinsicV2(xcmRequest);
238
- if (xcmFeeByDryRun.fee) {
239
- xcmFee = BigN(xcmFeeByDryRun.fee).multipliedBy(XCM_MIN_AMOUNT_RATIO).toFixed(0, 1);
240
- } else {
223
+ const xcmFeeInfo = await estimateXcmFee({
224
+ fromChainInfo: altChainInfo,
225
+ fromTokenInfo: altInputTokenInfo,
226
+ toChainInfo: this.chainInfo,
227
+ recipient: address,
228
+ sender: address,
229
+ value: bnAmount.toString()
230
+ });
231
+ if (!xcmFeeInfo) {
241
232
  throw new Error('Error estimating XCM fee');
242
233
  }
234
+ const xcmFee = BigN(xcmFeeInfo.origin.fee).multipliedBy(XCM_MIN_AMOUNT_RATIO).toFixed(0, 1);
243
235
  const fee = {
244
236
  slug: altInputTokenSlug,
245
237
  amount: xcmFee
@@ -7,8 +7,9 @@ import { validateSpendingAndFeePayment } from '@subwallet/extension-base/core/lo
7
7
  import { _isAccountActive } from '@subwallet/extension-base/core/substrate/system-pallet';
8
8
  import { _isAcrossBridgeXcm, _isSnowBridgeXcm, _isXcmWithinSameConsensus } from '@subwallet/extension-base/core/substrate/xcm-parser';
9
9
  import { _isSufficientToken } from '@subwallet/extension-base/core/utils';
10
- import { createXcmExtrinsicV2, dryRunXcmExtrinsicV2 } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
10
+ import { createXcmExtrinsicV2 } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
11
11
  import { _isAcrossChainBridge, AcrossErrorMsg } from '@subwallet/extension-base/services/balance-service/transfer/xcm/acrossBridge';
12
+ import { estimateXcmFee } from '@subwallet/extension-base/services/balance-service/transfer/xcm/utils';
12
13
  import { _getAssetDecimals, _getAssetOriginChain, _getAssetSymbol, _getChainNativeTokenSlug, _getTokenMinAmount, _isChainEvmCompatible, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
13
14
  import { DEFAULT_EXCESS_AMOUNT_WEIGHT, FEE_RATE_MULTIPLIER } from '@subwallet/extension-base/services/swap-service/utils';
14
15
  import { BasicTxErrorType, SwapStepType, TransferTxErrorType } from '@subwallet/extension-base/types';
@@ -121,11 +122,15 @@ export class SwapBaseHandler {
121
122
  };
122
123
 
123
124
  // TODO: calculate fee for destination chain
124
- const bridgeFeeByDryRun = await dryRunXcmExtrinsicV2(xcmRequest);
125
- if (!bridgeFeeByDryRun.fee) {
126
- return undefined;
127
- }
128
- const estimatedBridgeFee = BigN(bridgeFeeByDryRun.fee).multipliedBy(FEE_RATE_MULTIPLIER.medium).toFixed(0, 1);
125
+ const xcmFeeInfo = await estimateXcmFee({
126
+ fromChainInfo: xcmRequest.originChain,
127
+ fromTokenInfo: xcmRequest.originTokenInfo,
128
+ toChainInfo: xcmRequest.destinationChain,
129
+ recipient: xcmRequest.recipient,
130
+ sender: xcmRequest.sender,
131
+ value: xcmRequest.sendingValue
132
+ });
133
+ const estimatedBridgeFee = BigN((xcmFeeInfo === null || xcmFeeInfo === void 0 ? void 0 : xcmFeeInfo.origin.fee) || '0').multipliedBy(FEE_RATE_MULTIPLIER.medium).toFixed(0, 1);
129
134
  const fee = {
130
135
  feeComponent: [{
131
136
  feeType: SwapFeeType.NETWORK_FEE,
@@ -14,44 +14,59 @@ import { calculateGasFeeParams } from "../../fee-service/utils/index.js";
14
14
  import { SwapBaseHandler } from "./base-handler.js";
15
15
  export const KYBER_CLIENT_ID = process.env.KYBER_CLIENT_ID || '';
16
16
  const kyberUrl = 'https://aggregator-api.kyberswap.com';
17
- async function buildTxForSwap(params, chain) {
17
+ async function buildTxForKyberSwap(params, chain) {
18
18
  const {
19
19
  recipient,
20
20
  sender,
21
21
  slippageTolerance
22
22
  } = params;
23
23
  let routeSummary = params.routeSummary;
24
+ console.log('routeSummary1', routeSummary);
24
25
  if (!routeSummary || !routeSummary.tokenIn || !routeSummary.tokenOut || !routeSummary.amountIn) {
25
- const queryParams = new URLSearchParams({
26
- tokenIn: routeSummary.tokenIn,
27
- tokenOut: routeSummary.tokenOut,
28
- amountIn: routeSummary.amountIn,
29
- gasInclude: 'true'
30
- });
31
- const url = `${kyberUrl}/${chain}/api/v1/routes?${queryParams.toString()}`;
32
- try {
33
- var _routeData$data;
34
- const res = await fetch(url, {
35
- method: 'GET',
36
- headers: {
37
- 'Content-Type': 'application/json',
38
- 'x-client-id': KYBER_CLIENT_ID,
39
- accept: 'application/json'
40
- }
41
- });
42
- const routeData = await res.json();
43
- if (!routeData.success || !((_routeData$data = routeData.data) !== null && _routeData$data !== void 0 && _routeData$data.routeSummary)) {
44
- return {
45
- error: new TransactionError(BasicTxErrorType.INTERNAL_ERROR, routeData.message)
46
- };
26
+ return {
27
+ error: new TransactionError(BasicTxErrorType.INTERNAL_ERROR, 'Invalid Route Summary')
28
+ };
29
+ }
30
+ const {
31
+ amountIn,
32
+ tokenIn,
33
+ tokenOut
34
+ } = routeSummary;
35
+ const queryParams = new URLSearchParams({
36
+ tokenIn,
37
+ tokenOut,
38
+ amountIn,
39
+ gasInclude: 'true'
40
+ });
41
+ const url = `${kyberUrl}/${chain}/api/v1/routes?${queryParams.toString()}`;
42
+ try {
43
+ var _routeData$data;
44
+ const res = await fetch(url, {
45
+ method: 'GET',
46
+ headers: {
47
+ 'Content-Type': 'application/json',
48
+ 'x-client-id': KYBER_CLIENT_ID,
49
+ accept: 'application/json'
47
50
  }
48
- routeSummary = routeData.data.routeSummary;
49
- } catch (error) {
50
- console.error('Error:', error);
51
+ });
52
+ if (!res.ok) {
53
+ const errorText = await res.text();
54
+ return {
55
+ error: new TransactionError(BasicTxErrorType.INTERNAL_ERROR, `Fetch Kyber routes failed: ${errorText}`)
56
+ };
57
+ }
58
+ const routeData = await res.json();
59
+ if (!((_routeData$data = routeData.data) !== null && _routeData$data !== void 0 && _routeData$data.routeSummary)) {
51
60
  return {
52
- error: new TransactionError(BasicTxErrorType.INTERNAL_ERROR)
61
+ error: new TransactionError(BasicTxErrorType.INTERNAL_ERROR, routeData.message)
53
62
  };
54
63
  }
64
+ routeSummary = routeData.data.routeSummary;
65
+ } catch (error) {
66
+ console.error('Error:', error);
67
+ return {
68
+ error: new TransactionError(BasicTxErrorType.INTERNAL_ERROR, 'Unable to build Kyber swap transaction')
69
+ };
55
70
  }
56
71
  const body = {
57
72
  routeSummary,
@@ -61,6 +76,7 @@ async function buildTxForSwap(params, chain) {
61
76
  ignoreCappedSlippage: true,
62
77
  enableGasEstimation: true
63
78
  };
79
+ console.log('routeSummary2', routeSummary);
64
80
  try {
65
81
  const res = await fetch(`${kyberUrl}/${chain}/api/v1/route/build`, {
66
82
  method: 'POST',
@@ -272,7 +288,7 @@ export class KyberHandler {
272
288
  const recipient = _reformatAddressWithChain((_params$recipient = params.recipient) !== null && _params$recipient !== void 0 ? _params$recipient : sender, toChainInfo);
273
289
  const metadata = params.quote.metadata;
274
290
  const slippageTolerance = params.slippage * 10000;
275
- const rawTx = await buildTxForSwap({
291
+ const rawTx = await buildTxForKyberSwap({
276
292
  routeSummary: metadata.routeSummary,
277
293
  sender: params.address,
278
294
  recipient,