@subwallet/extension-base 1.3.25-0 → 1.3.27-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 (54) hide show
  1. package/background/KoniTypes.d.ts +4 -3
  2. package/background/warnings/TransactionWarning.d.ts +2 -0
  3. package/background/warnings/TransactionWarning.js +16 -1
  4. package/cjs/background/warnings/TransactionWarning.js +15 -0
  5. package/cjs/core/logic-validation/index.js +32 -1
  6. package/cjs/core/utils.js +25 -3
  7. package/cjs/koni/background/handlers/Extension.js +86 -94
  8. package/cjs/packageInfo.js +1 -1
  9. package/cjs/services/chain-service/constants.js +1 -1
  10. package/cjs/services/swap-service/handler/asset-hub/handler.js +182 -40
  11. package/cjs/services/swap-service/handler/asset-hub/utils.js +3 -0
  12. package/cjs/services/swap-service/handler/base-handler.js +326 -12
  13. package/cjs/services/swap-service/handler/chainflip-handler.js +80 -16
  14. package/cjs/services/swap-service/handler/hydradx-handler.js +174 -30
  15. package/cjs/services/swap-service/handler/simpleswap-handler.js +50 -1
  16. package/cjs/services/swap-service/handler/uniswap-handler.js +47 -1
  17. package/cjs/services/swap-service/index.js +191 -27
  18. package/cjs/services/swap-service/interface.js +14 -0
  19. package/cjs/services/swap-service/utils.js +81 -5
  20. package/cjs/services/transaction-service/utils.js +3 -3
  21. package/core/logic-validation/index.d.ts +4 -0
  22. package/core/logic-validation/index.js +22 -1
  23. package/core/utils.d.ts +3 -0
  24. package/core/utils.js +22 -2
  25. package/koni/background/handlers/Extension.d.ts +2 -2
  26. package/koni/background/handlers/Extension.js +20 -28
  27. package/package.json +12 -7
  28. package/packageInfo.js +1 -1
  29. package/services/balance-service/helpers/process.d.ts +3 -3
  30. package/services/balance-service/index.d.ts +2 -3
  31. package/services/chain-service/constants.js +1 -1
  32. package/services/swap-service/handler/asset-hub/handler.d.ts +6 -3
  33. package/services/swap-service/handler/asset-hub/handler.js +170 -28
  34. package/services/swap-service/handler/asset-hub/utils.js +3 -0
  35. package/services/swap-service/handler/base-handler.d.ts +12 -3
  36. package/services/swap-service/handler/base-handler.js +329 -15
  37. package/services/swap-service/handler/chainflip-handler.d.ts +4 -3
  38. package/services/swap-service/handler/chainflip-handler.js +74 -10
  39. package/services/swap-service/handler/hydradx-handler.d.ts +8 -3
  40. package/services/swap-service/handler/hydradx-handler.js +176 -32
  41. package/services/swap-service/handler/simpleswap-handler.d.ts +4 -2
  42. package/services/swap-service/handler/simpleswap-handler.js +50 -1
  43. package/services/swap-service/handler/uniswap-handler.d.ts +4 -2
  44. package/services/swap-service/handler/uniswap-handler.js +47 -1
  45. package/services/swap-service/index.d.ts +15 -5
  46. package/services/swap-service/index.js +182 -18
  47. package/services/swap-service/interface.d.ts +9 -0
  48. package/services/swap-service/interface.js +8 -0
  49. package/services/swap-service/utils.d.ts +9 -1
  50. package/services/swap-service/utils.js +74 -4
  51. package/services/transaction-service/utils.js +3 -3
  52. package/types/service-base.d.ts +6 -2
  53. package/types/swap/index.d.ts +34 -6
  54. package/types/transaction/process.d.ts +0 -6
@@ -4,14 +4,15 @@
4
4
  import { SwapError } from '@subwallet/extension-base/background/errors/SwapError';
5
5
  import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
6
6
  import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
7
+ import { _getAssetOriginChain, _getChainSubstrateAddressPrefix } from '@subwallet/extension-base/services/chain-service/utils';
7
8
  import { AssetHubSwapHandler } from '@subwallet/extension-base/services/swap-service/handler/asset-hub';
8
9
  import { ChainflipSwapHandler } from '@subwallet/extension-base/services/swap-service/handler/chainflip-handler';
9
10
  import { HydradxHandler } from '@subwallet/extension-base/services/swap-service/handler/hydradx-handler';
10
- import { _PROVIDER_TO_SUPPORTED_PAIR_MAP, getSwapAltToken, SWAP_QUOTE_TIMEOUT_MAP } from '@subwallet/extension-base/services/swap-service/utils';
11
+ import { _PROVIDER_TO_SUPPORTED_PAIR_MAP, findXcmDestination, getBridgeStep, getSwapAltToken, getSwapStep, isChainsHasSameProvider, SWAP_QUOTE_TIMEOUT_MAP } from '@subwallet/extension-base/services/swap-service/utils';
11
12
  import { BasicTxErrorType } from '@subwallet/extension-base/types';
12
13
  import { DEFAULT_FIRST_STEP, MOCK_STEP_FEE } from '@subwallet/extension-base/types/service-base';
13
14
  import { _SUPPORTED_SWAP_PROVIDERS, SwapErrorType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types/swap';
14
- import { createPromiseHandler } from '@subwallet/extension-base/utils';
15
+ import { createPromiseHandler, reformatAddress } from '@subwallet/extension-base/utils';
15
16
  import subwalletApiSdk from '@subwallet/subwallet-api-sdk';
16
17
  import { BehaviorSubject } from 'rxjs';
17
18
  import { SimpleSwapHandler } from "./handler/simpleswap-handler.js";
@@ -63,7 +64,8 @@ export class SwapService {
63
64
  getDefaultProcess(params) {
64
65
  const result = {
65
66
  totalFee: [MOCK_STEP_FEE],
66
- steps: [DEFAULT_FIRST_STEP]
67
+ steps: [DEFAULT_FIRST_STEP],
68
+ path: []
67
69
  };
68
70
  result.totalFee.push({
69
71
  feeComponent: [],
@@ -77,6 +79,33 @@ export class SwapService {
77
79
  });
78
80
  return result;
79
81
  }
82
+ getDefaultProcessV2(params) {
83
+ const result = {
84
+ totalFee: [MOCK_STEP_FEE],
85
+ steps: [DEFAULT_FIRST_STEP],
86
+ path: []
87
+ };
88
+ const swapPairInfo = params.path[0].pair; // todo: improve for Round 2
89
+
90
+ result.totalFee.push({
91
+ feeComponent: [],
92
+ feeOptions: [params.request.pair.from],
93
+ defaultFeeToken: params.request.pair.from
94
+ });
95
+ result.steps.push({
96
+ id: result.steps.length,
97
+ name: 'Swap',
98
+ type: SwapStepType.SWAP,
99
+ metadata: {
100
+ sendingValue: params.request.fromAmount.toString(),
101
+ originTokenInfo: this.chainService.getAssetBySlug(swapPairInfo.from),
102
+ destinationTokenInfo: this.chainService.getAssetBySlug(swapPairInfo.to)
103
+ }
104
+ });
105
+ return result;
106
+ }
107
+
108
+ // deprecated
80
109
  async generateOptimalProcess(params) {
81
110
  if (!params.selectedQuote) {
82
111
  return this.getDefaultProcess(params);
@@ -91,24 +120,153 @@ export class SwapService {
91
120
  }
92
121
  }
93
122
  }
123
+ async generateOptimalProcessV2(params) {
124
+ if (!params.selectedQuote) {
125
+ return this.getDefaultProcessV2(params);
126
+ } else {
127
+ var _params$request$curre2;
128
+ const providerId = ((_params$request$curre2 = params.request.currentQuote) === null || _params$request$curre2 === void 0 ? void 0 : _params$request$curre2.id) || params.selectedQuote.provider.id;
129
+ const handler = this.handlers[providerId];
130
+ if (handler) {
131
+ return handler.generateOptimalProcessV2(params);
132
+ } else {
133
+ return this.getDefaultProcessV2(params);
134
+ }
135
+ }
136
+ }
137
+ async generateOptimalProcessWithoutPath(params) {
138
+ var _params$request$curre3;
139
+ if (!params.selectedQuote || params.path.length > 0) {
140
+ return this.getDefaultProcessV2(params);
141
+ }
142
+ const [path, directSwapRequest] = this.getAvailablePath(params.request);
143
+ if (!directSwapRequest) {
144
+ return this.getDefaultProcessV2(params);
145
+ }
146
+ params.path = path;
147
+ const providerId = ((_params$request$curre3 = params.request.currentQuote) === null || _params$request$curre3 === void 0 ? void 0 : _params$request$curre3.id) || params.selectedQuote.provider.id;
148
+ const handler = this.handlers[providerId];
149
+ if (handler) {
150
+ return handler.generateOptimalProcessV2(params);
151
+ } else {
152
+ return this.getDefaultProcessV2(params);
153
+ }
154
+ }
155
+
156
+ // deprecated
157
+ // eslint-disable-next-line @typescript-eslint/require-await
94
158
  async handleSwapRequest(request) {
95
- /*
96
- * 1. Ask swap quotes from providers
97
- * 2. Select the best quote
98
- * 3. Generate optimal process for that quote
159
+ /*
160
+ * 1. Ask swap quotes from providers
161
+ * 2. Select the best quote
162
+ * 3. Generate optimal process for that quote
99
163
  * */
100
- const swapQuoteResponse = await this.getLatestQuotes(request);
101
- const optimalProcess = await this.generateOptimalProcess({
164
+
165
+ // const swapQuoteResponse = await this.getLatestDirectQuotes(request);
166
+
167
+ // const optimalProcess = await this.generateOptimalProcess({
168
+ // request,
169
+ // selectedQuote: swapQuoteResponse.optimalQuote
170
+ // });
171
+
172
+ return {
173
+ // @ts-ignore
174
+ process: null,
175
+ // @ts-ignore
176
+ quote: null
177
+ };
178
+ }
179
+ async handleSwapRequestV2(request) {
180
+ /*
181
+ * 1. Find available path
182
+ * 2. Ask swap quotes from providers
183
+ * 3. Select the best quote
184
+ * 4. Generate optimal process for that quote
185
+ * */
186
+
187
+ // todo: path will become a list of path in Round 2
188
+ // const [path, directSwapRequest] = this.getAvailablePath(request);
189
+ //
190
+ // if (!directSwapRequest) {
191
+ // throw Error('Swap pair not found');
192
+ // }
193
+
194
+ // const swapQuoteResponse = await this.getLatestDirectQuotes(directSwapRequest);
195
+ const {
196
+ path,
197
+ swapQuoteResponse
198
+ } = await this.getLatestQuoteFromSwapRequest(request);
199
+ const optimalProcess = await this.generateOptimalProcessV2({
102
200
  request,
103
- selectedQuote: swapQuoteResponse.optimalQuote
201
+ selectedQuote: swapQuoteResponse.optimalQuote,
202
+ path
104
203
  });
105
204
  return {
106
205
  process: optimalProcess,
107
206
  quote: swapQuoteResponse
108
207
  };
109
208
  }
110
- async getLatestQuotes(request) {
111
- request.pair.metadata = this.getSwapPairMetadata(request.pair.slug); // todo: improve this
209
+ getAvailablePath(request) {
210
+ const {
211
+ pair
212
+ } = request;
213
+ // todo: control provider tighter
214
+ const allSupportedChainsBySwapProvider = [...new Set(Object.values(_PROVIDER_TO_SUPPORTED_PAIR_MAP).flat())];
215
+ const fromToken = this.chainService.getAssetBySlug(pair.from);
216
+ const toToken = this.chainService.getAssetBySlug(pair.to);
217
+ const fromChain = _getAssetOriginChain(fromToken);
218
+ const toChain = _getAssetOriginChain(toToken);
219
+ const toChainInfo = this.chainService.getChainInfoByKey(toChain);
220
+ const process = [];
221
+ if (!fromToken || !toToken) {
222
+ throw Error('Token not found');
223
+ }
224
+ if (!fromChain || !toChain) {
225
+ throw Error('Token metadata error');
226
+ }
227
+
228
+ // SWAP: 2 tokens in the same chain and chain has dex
229
+ if (isChainsHasSameProvider(fromChain, toChain)) {
230
+ // there's a dex that can support direct swapping
231
+ const swapStep = getSwapStep(fromToken.slug, toToken.slug);
232
+ process.push(swapStep);
233
+ return [process, {
234
+ ...request,
235
+ pair: swapStep.pair
236
+ }];
237
+ }
238
+
239
+ // BRIDGE -> SWAP: Try to find a token in dest chain that can bridge from fromToken
240
+ const bridgeDestination = findXcmDestination(this.chainService.getAssetRefMap(), fromToken, toChain);
241
+ if (bridgeDestination && allSupportedChainsBySwapProvider.includes(toChain)) {
242
+ const bridgeStep = getBridgeStep(fromToken.slug, bridgeDestination);
243
+ const swapStep = getSwapStep(bridgeDestination, toToken.slug);
244
+ process.push(bridgeStep);
245
+ process.push(swapStep);
246
+ return [process, {
247
+ ...request,
248
+ address: reformatAddress(request.address, _getChainSubstrateAddressPrefix(toChainInfo)),
249
+ pair: swapStep.pair
250
+ }];
251
+ }
252
+
253
+ // todo: improve to support SWAP -> BRIDGE and BRIDGE -> SWAP -> BRIDGE
254
+
255
+ return [[], undefined];
256
+ }
257
+ async getLatestQuoteFromSwapRequest(request) {
258
+ const [path, directSwapRequest] = this.getAvailablePath(request);
259
+ if (!directSwapRequest) {
260
+ throw Error('Swap pair not found');
261
+ }
262
+ const swapQuoteResponse = await this.getLatestDirectQuotes(directSwapRequest);
263
+ return {
264
+ path,
265
+ swapQuoteResponse
266
+ };
267
+ }
268
+ async getLatestDirectQuotes(request) {
269
+ // request.pair.metadata = this.getSwapPairMetadata(request.pair.slug); // deprecated
112
270
  const quoteAskResponses = await this.askProvidersForQuote(request);
113
271
 
114
272
  // todo: handle error to return back to UI
@@ -129,7 +287,7 @@ export class SwapService {
129
287
  selectedQuote = availableQuotes.find(quote => {
130
288
  var _request$currentQuote;
131
289
  return quote.provider.id === ((_request$currentQuote = request.currentQuote) === null || _request$currentQuote === void 0 ? void 0 : _request$currentQuote.id);
132
- }) || availableQuotes[0];
290
+ }) || availableQuotes[0]; // todo: choose best quote based on rate
133
291
  aliveUntil = ((_selectedQuote = selectedQuote) === null || _selectedQuote === void 0 ? void 0 : _selectedQuote.aliveUntil) || +Date.now() + SWAP_QUOTE_TIMEOUT_MAP.default;
134
292
  }
135
293
  return {
@@ -235,15 +393,20 @@ export class SwapService {
235
393
  };
236
394
  });
237
395
  }
238
- getSwapPairMetadata(slug) {
239
- var _this$getSwapPairs$fi;
240
- return (_this$getSwapPairs$fi = this.getSwapPairs().find(pair => pair.slug === slug)) === null || _this$getSwapPairs$fi === void 0 ? void 0 : _this$getSwapPairs$fi.metadata;
241
- }
396
+
397
+ // private getSwapPairMetadata (slug: string): Record<string, any> | undefined {
398
+ // return this.getSwapPairs().find((pair) => pair.slug === slug)?.metadata;
399
+ // }
400
+
242
401
  async validateSwapProcess(params) {
243
402
  const providerId = params.selectedQuote.provider.id;
244
403
  const handler = this.handlers[providerId];
404
+ if (params.currentStep > 1) {
405
+ // only validate from the first step
406
+ return [];
407
+ }
245
408
  if (handler) {
246
- return handler.validateSwapProcess(params);
409
+ return handler.validateSwapProcessV2(params);
247
410
  } else {
248
411
  return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
249
412
  }
@@ -254,6 +417,7 @@ export class SwapService {
254
417
  // todo: do better to handle error generating steps
255
418
  return Promise.reject(new TransactionError(BasicTxErrorType.INTERNAL_ERROR, 'Please check your network and try again'));
256
419
  }
420
+ console.log('handling swap process: ', params.process);
257
421
  if (handler) {
258
422
  return handler.handleSwapProcess(params);
259
423
  } else {
@@ -0,0 +1,9 @@
1
+ import { ActionPair } from '@subwallet/extension-base/types';
2
+ export declare enum DynamicSwapType {
3
+ SWAP = "SWAP",
4
+ BRIDGE = "BRIDGE"
5
+ }
6
+ export interface DynamicSwapAction {
7
+ action: DynamicSwapType;
8
+ pair: ActionPair;
9
+ }
@@ -0,0 +1,8 @@
1
+ // Copyright 2019-2022 @subwallet/extension-base
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export let DynamicSwapType;
5
+ (function (DynamicSwapType) {
6
+ DynamicSwapType["SWAP"] = "SWAP";
7
+ DynamicSwapType["BRIDGE"] = "BRIDGE";
8
+ })(DynamicSwapType || (DynamicSwapType = {}));
@@ -1,4 +1,6 @@
1
- import { _ChainAsset } from '@subwallet/chain-list/types';
1
+ import { _AssetRef, _ChainAsset } from '@subwallet/chain-list/types';
2
+ import { DynamicSwapAction } from '@subwallet/extension-base/services/swap-service/interface';
3
+ import { CommonStepDetail } from '@subwallet/extension-base/types';
2
4
  import { SwapPair } from '@subwallet/extension-base/types/swap';
3
5
  export declare const CHAIN_FLIP_TESTNET_EXPLORER = "https://blocks-perseverance.chainflip.io";
4
6
  export declare const CHAIN_FLIP_MAINNET_EXPLORER = "https://scan.chainflip.io";
@@ -6,6 +8,7 @@ export declare const SIMPLE_SWAP_EXPLORER = "https://simpleswap.io";
6
8
  export declare const SIMPLE_SWAP_SUPPORTED_TESTNET_ASSET_MAPPING: Record<string, string>;
7
9
  export declare const SWAP_QUOTE_TIMEOUT_MAP: Record<string, number>;
8
10
  export declare const _PROVIDER_TO_SUPPORTED_PAIR_MAP: Record<string, string[]>;
11
+ export declare const FEE_RATE_MULTIPLIER: Record<string, number>;
9
12
  export declare function getSwapAlternativeAsset(swapPair: SwapPair): string | undefined;
10
13
  export declare function getSwapAltToken(chainAsset: _ChainAsset): string | undefined;
11
14
  export declare function calculateSwapRate(fromAmount: string, toAmount: string, fromAsset: _ChainAsset, toAsset: _ChainAsset): number;
@@ -23,3 +26,8 @@ export declare function getChainflipBroker(isTestnet: boolean): {
23
26
  url: string;
24
27
  };
25
28
  export declare function getChainflipSwap(isTestnet: boolean): string;
29
+ export declare function getBridgeStep(from: string, to: string): DynamicSwapAction;
30
+ export declare function getSwapStep(from: string, to: string): DynamicSwapAction;
31
+ export declare function findXcmDestination(assetRefMap: Record<string, _AssetRef>, chainAsset: _ChainAsset, destChain: string): string | undefined;
32
+ export declare function isChainsHasSameProvider(fromChain: string, toChain: string): boolean;
33
+ export declare function getTokenPairFromStep(steps: CommonStepDetail[]): SwapPair | undefined;
@@ -2,8 +2,11 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
4
  import { COMMON_ASSETS, COMMON_CHAIN_SLUGS } from '@subwallet/chain-list';
5
+ import { _AssetRefPath } from '@subwallet/chain-list/types';
5
6
  import { _getAssetDecimals } from '@subwallet/extension-base/services/chain-service/utils';
6
7
  import { CHAINFLIP_BROKER_API } from '@subwallet/extension-base/services/swap-service/handler/chainflip-handler';
8
+ import { DynamicSwapType } from '@subwallet/extension-base/services/swap-service/interface';
9
+ import { CommonStepType } from '@subwallet/extension-base/types';
7
10
  import { SwapProviderId } from '@subwallet/extension-base/types/swap';
8
11
  import BigN from 'bignumber.js';
9
12
  export const CHAIN_FLIP_TESTNET_EXPLORER = 'https://blocks-perseverance.chainflip.io';
@@ -24,14 +27,21 @@ export const SWAP_QUOTE_TIMEOUT_MAP = {
24
27
  };
25
28
  export const _PROVIDER_TO_SUPPORTED_PAIR_MAP = {
26
29
  [SwapProviderId.HYDRADX_MAINNET]: [COMMON_CHAIN_SLUGS.HYDRADX],
27
- [SwapProviderId.HYDRADX_TESTNET]: [COMMON_CHAIN_SLUGS.HYDRADX_TESTNET],
28
30
  [SwapProviderId.CHAIN_FLIP_MAINNET]: [COMMON_CHAIN_SLUGS.POLKADOT, COMMON_CHAIN_SLUGS.ETHEREUM, COMMON_CHAIN_SLUGS.ARBITRUM],
29
- [SwapProviderId.CHAIN_FLIP_TESTNET]: [COMMON_CHAIN_SLUGS.CHAINFLIP_POLKADOT, COMMON_CHAIN_SLUGS.ETHEREUM_SEPOLIA],
30
31
  [SwapProviderId.POLKADOT_ASSET_HUB]: [COMMON_CHAIN_SLUGS.POLKADOT_ASSET_HUB],
31
32
  [SwapProviderId.KUSAMA_ASSET_HUB]: [COMMON_CHAIN_SLUGS.KUSAMA_ASSET_HUB],
33
+ [SwapProviderId.SIMPLE_SWAP]: ['bittensor', COMMON_CHAIN_SLUGS.ETHEREUM, COMMON_CHAIN_SLUGS.POLKADOT],
34
+ [SwapProviderId.UNISWAP]: [COMMON_CHAIN_SLUGS.ETHEREUM, COMMON_CHAIN_SLUGS.ARBITRUM],
35
+ // testnet
36
+ [SwapProviderId.CHAIN_FLIP_TESTNET]: [COMMON_CHAIN_SLUGS.CHAINFLIP_POLKADOT, COMMON_CHAIN_SLUGS.ETHEREUM_SEPOLIA],
37
+ [SwapProviderId.HYDRADX_TESTNET]: [COMMON_CHAIN_SLUGS.HYDRADX_TESTNET],
32
38
  [SwapProviderId.ROCOCO_ASSET_HUB]: [COMMON_CHAIN_SLUGS.ROCOCO_ASSET_HUB],
33
- [SwapProviderId.WESTEND_ASSET_HUB]: ['westend_assethub'],
34
- [SwapProviderId.SIMPLE_SWAP]: ['bittensor', COMMON_CHAIN_SLUGS.ETHEREUM, COMMON_CHAIN_SLUGS.POLKADOT]
39
+ [SwapProviderId.WESTEND_ASSET_HUB]: ['westend_assethub']
40
+ };
41
+ export const FEE_RATE_MULTIPLIER = {
42
+ default: 1,
43
+ medium: 1.2,
44
+ high: 2
35
45
  };
36
46
  export function getSwapAlternativeAsset(swapPair) {
37
47
  var _swapPair$metadata;
@@ -85,4 +95,64 @@ export function getChainflipSwap(isTestnet) {
85
95
  } else {
86
96
  return `https://chainflip-broker.io/swap?apikey=${CHAINFLIP_BROKER_API}`;
87
97
  }
98
+ }
99
+ export function getBridgeStep(from, to) {
100
+ return {
101
+ action: DynamicSwapType.BRIDGE,
102
+ pair: {
103
+ slug: `${from}___${to}`,
104
+ from,
105
+ to
106
+ }
107
+ };
108
+ }
109
+ export function getSwapStep(from, to) {
110
+ return {
111
+ action: DynamicSwapType.SWAP,
112
+ pair: {
113
+ slug: `${from}___${to}`,
114
+ from,
115
+ to
116
+ }
117
+ };
118
+ }
119
+ export function findXcmDestination(assetRefMap, chainAsset, destChain) {
120
+ const foundAssetRef = Object.values(assetRefMap).find(assetRef => assetRef.srcAsset === chainAsset.slug && assetRef.destChain === destChain && assetRef.path === _AssetRefPath.XCM);
121
+ if (foundAssetRef) {
122
+ return foundAssetRef.destAsset;
123
+ }
124
+ return undefined;
125
+ }
126
+ export function isChainsHasSameProvider(fromChain, toChain) {
127
+ // todo: a provider may support multiple chains but not cross-chain swaps
128
+ for (const group of Object.values(_PROVIDER_TO_SUPPORTED_PAIR_MAP)) {
129
+ if (group.includes(fromChain) && group.includes(toChain)) {
130
+ return true;
131
+ }
132
+ }
133
+ return false;
134
+ }
135
+ export function getTokenPairFromStep(steps) {
136
+ const mainSteps = steps.filter(step => step.type !== CommonStepType.DEFAULT);
137
+ if (!mainSteps.length) {
138
+ return undefined;
139
+ }
140
+ if (mainSteps.length === 1) {
141
+ const metadata = mainSteps[0].metadata; // todo: temp for round 1, the exact interface is handle in round 2
142
+
143
+ return {
144
+ from: metadata.originTokenInfo.slug,
145
+ to: metadata.destinationTokenInfo.slug,
146
+ slug: `${metadata.originTokenInfo.slug}___${metadata.destinationTokenInfo.slug}`
147
+ };
148
+ }
149
+ const firstStep = mainSteps[0];
150
+ const lastStep = mainSteps[mainSteps.length - 1];
151
+ const firstMetadata = firstStep.metadata;
152
+ const lastMetadata = lastStep.metadata;
153
+ return {
154
+ from: firstMetadata.originTokenInfo.slug,
155
+ to: lastMetadata.destinationTokenInfo.slug,
156
+ slug: `${firstMetadata.originTokenInfo.slug}___${lastMetadata.destinationTokenInfo.slug}`
157
+ };
88
158
  }
@@ -42,6 +42,9 @@ function getBlockExplorerAccountRoute(explorerLink) {
42
42
  if (explorerLink.includes('astral.autonomys')) {
43
43
  return 'accounts';
44
44
  }
45
+ if (explorerLink.includes('taostats.io')) {
46
+ return 'account';
47
+ }
45
48
  return 'address';
46
49
  }
47
50
  function getBlockExplorerTxRoute(chainInfo) {
@@ -66,9 +69,6 @@ export function getExplorerLink(chainInfo, value, type) {
66
69
  return `${explorerLink}${explorerLink.endsWith('/') ? '' : '/'}${route}/${value}`;
67
70
  }
68
71
  if (explorerLink && isHex(hexAddPrefix(value))) {
69
- if (chainInfo.slug === 'bittensor') {
70
- return undefined;
71
- }
72
72
  const route = getBlockExplorerTxRoute(chainInfo);
73
73
  if (chainInfo.slug === 'tangle') {
74
74
  return `${explorerLink}${explorerLink.endsWith('/') ? '' : '/'}extrinsic/${value}${route}/${value}`;
@@ -1,7 +1,8 @@
1
+ import { DynamicSwapAction } from '@subwallet/extension-base/services/swap-service/interface';
1
2
  import { OptimalSwapPathParams, SwapFeeType, SwapStepType } from '@subwallet/extension-base/types/swap';
2
3
  import { OptimalYieldPath, OptimalYieldPathParams, YieldStepType } from '@subwallet/extension-base/types/yield';
3
4
  export declare type OptimalProcessParams = OptimalYieldPathParams | OptimalSwapPathParams;
4
- export declare type OptimalProcessResult = OptimalYieldPath | CommonOptimalPath;
5
+ export declare type OptimalProcessResult = OptimalYieldPath | CommonOptimalSwapPath;
5
6
  export declare enum CommonStepType {
6
7
  DEFAULT = "DEFAULT",
7
8
  XCM = "XCM",
@@ -30,7 +31,10 @@ export interface CommonStepFeeInfo {
30
31
  export interface CommonStepDetail extends BaseStepDetail {
31
32
  id: number;
32
33
  }
33
- export interface CommonOptimalPath {
34
+ export interface CommonOptimalSwapPath extends CommonOptimalTransferPath {
35
+ path: DynamicSwapAction[];
36
+ }
37
+ export interface CommonOptimalTransferPath {
34
38
  totalFee: CommonStepFeeInfo[];
35
39
  steps: CommonStepDetail[];
36
40
  }
@@ -1,7 +1,8 @@
1
- import { _ChainInfo } from '@subwallet/chain-list/types';
1
+ import { _ChainAsset, _ChainInfo } from '@subwallet/chain-list/types';
2
2
  import { SwapError } from '@subwallet/extension-base/background/errors/SwapError';
3
3
  import { AmountData, ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
4
- import { BaseStepDetail, BaseStepType, CommonOptimalPath, CommonStepFeeInfo } from '@subwallet/extension-base/types/service-base';
4
+ import { DynamicSwapAction } from '@subwallet/extension-base/services/swap-service/interface';
5
+ import { BaseStepDetail, BaseStepType, CommonOptimalSwapPath, CommonStepFeeInfo } from '@subwallet/extension-base/types/service-base';
5
6
  import BigN from 'bignumber.js';
6
7
  import { BaseProcessRequestSign, TransactionData } from '../transaction';
7
8
  export declare type SwapRate = number;
@@ -11,6 +12,11 @@ export interface SwapPair {
11
12
  to: string;
12
13
  metadata?: Record<string, any>;
13
14
  }
15
+ export interface ActionPair {
16
+ slug: string;
17
+ from: string;
18
+ to: string;
19
+ }
14
20
  export interface SwapQuote {
15
21
  pair: SwapPair;
16
22
  fromAmount: string;
@@ -77,7 +83,7 @@ export interface SwapBaseTxData {
77
83
  address: string;
78
84
  slippage: number;
79
85
  recipient?: string;
80
- process: CommonOptimalPath;
86
+ process: CommonOptimalSwapPath;
81
87
  }
82
88
  export interface ChainflipSwapTxData extends SwapBaseTxData {
83
89
  depositChannelId: string;
@@ -91,6 +97,7 @@ export interface HydradxSwapTxData extends SwapBaseTxData {
91
97
  txHex: string;
92
98
  }
93
99
  export declare type GenSwapStepFunc = (params: OptimalSwapPathParams) => Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
100
+ export declare type GenSwapStepFuncV2 = (params: OptimalSwapPathParamsV2) => Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
94
101
  export interface ChainflipPreValidationMetadata {
95
102
  minSwap: AmountData;
96
103
  maxSwap?: AmountData;
@@ -125,7 +132,7 @@ export interface SwapRequest {
125
132
  currentQuote?: SwapProvider;
126
133
  }
127
134
  export interface SwapRequestResult {
128
- process: CommonOptimalPath;
135
+ process: CommonOptimalSwapPath;
129
136
  quote: SwapQuoteResponse;
130
137
  }
131
138
  export interface SwapQuoteResponse {
@@ -135,7 +142,7 @@ export interface SwapQuoteResponse {
135
142
  error?: SwapError;
136
143
  }
137
144
  export interface SwapSubmitParams extends BaseProcessRequestSign {
138
- process: CommonOptimalPath;
145
+ process: CommonOptimalSwapPath;
139
146
  currentStep: number;
140
147
  quote: SwapQuote;
141
148
  address: string;
@@ -156,6 +163,11 @@ export interface OptimalSwapPathParams {
156
163
  request: SwapRequest;
157
164
  selectedQuote?: SwapQuote;
158
165
  }
166
+ export interface OptimalSwapPathParamsV2 {
167
+ request: SwapRequest;
168
+ selectedQuote?: SwapQuote;
169
+ path: DynamicSwapAction[];
170
+ }
159
171
  export interface SwapEarlyValidation {
160
172
  error?: SwapErrorType;
161
173
  metadata?: ChainflipPreValidationMetadata | HydradxPreValidationMetadata | AssetHubPreValidationMetadata;
@@ -165,9 +177,10 @@ export interface AssetHubSwapEarlyValidation extends SwapEarlyValidation {
165
177
  }
166
178
  export interface ValidateSwapProcessParams {
167
179
  address: string;
168
- process: CommonOptimalPath;
180
+ process: CommonOptimalSwapPath;
169
181
  selectedQuote: SwapQuote;
170
182
  recipient?: string;
183
+ currentStep: number;
171
184
  }
172
185
  export interface SlippageType {
173
186
  slippage: BigN;
@@ -179,3 +192,18 @@ export interface PermitSwapData {
179
192
  }
180
193
  export declare const CHAINFLIP_SLIPPAGE = 0.02;
181
194
  export declare const SIMPLE_SWAP_SLIPPAGE = 0.05;
195
+ export interface BaseSwapStepMetadata {
196
+ sendingValue: string;
197
+ originTokenInfo: _ChainAsset;
198
+ destinationTokenInfo: _ChainAsset;
199
+ }
200
+ export interface BriefXCMStep extends BaseSwapStepMetadata {
201
+ expectedReceive?: string;
202
+ }
203
+ export interface HydrationSwapStepMetadata extends BaseSwapStepMetadata {
204
+ txHex: `0x${string}`;
205
+ }
206
+ export interface ChainFlipSwapStepMetadata extends BaseSwapStepMetadata {
207
+ srcChain: string;
208
+ destChain: string;
209
+ }
@@ -1,4 +1,3 @@
1
- import { _ChainAsset } from '@subwallet/chain-list/types';
2
1
  import { TransactionEventResponse } from '@subwallet/extension-base/services/transaction-service/types';
3
2
  import { CommonStepDetail, CommonStepFeeInfo } from '../service-base';
4
3
  import { SwapPair, SwapProvider, SwapRate, SwapRoute, SwapSubmitParams } from '../swap';
@@ -52,11 +51,6 @@ export interface BriefProcessStep {
52
51
  processId: string;
53
52
  stepId: number;
54
53
  }
55
- export interface BriefXCMStep {
56
- sendingValue: string;
57
- originTokenInfo: _ChainAsset;
58
- destinationTokenInfo: _ChainAsset;
59
- }
60
54
  export interface BriefSwapStep {
61
55
  pair: SwapPair;
62
56
  fromAmount: string;