@subwallet/extension-base 1.3.29-1 → 1.3.31-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/background/KoniTypes.d.ts +16 -4
- package/background/errors/SwapError.js +1 -1
- package/cjs/background/errors/SwapError.js +1 -1
- package/cjs/constants/blocked-actions.js +2 -2
- package/cjs/constants/paraspell-chain-map.js +13 -0
- package/cjs/constants/remind-notification-time.js +3 -3
- package/cjs/core/logic-validation/swap.js +63 -4
- package/cjs/core/logic-validation/transfer.js +13 -1
- package/cjs/core/substrate/xcm-parser.js +5 -1
- package/cjs/core/utils.js +36 -15
- package/cjs/koni/background/handlers/Extension.js +141 -172
- package/cjs/koni/background/handlers/State.js +8 -1
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/helpers/process.js +27 -0
- package/cjs/services/balance-service/index.js +9 -0
- package/cjs/services/balance-service/transfer/xcm/acrossBridge/index.js +229 -0
- package/cjs/services/balance-service/transfer/xcm/availBridge.js +6 -6
- package/cjs/services/balance-service/transfer/xcm/index.js +96 -7
- package/cjs/services/balance-service/transfer/xcm/utils.js +213 -0
- package/cjs/services/chain-service/constants.js +2 -4
- package/cjs/services/chain-service/index.js +71 -17
- package/cjs/services/chain-service/utils/patch.js +1 -1
- package/cjs/services/earning-service/handlers/base.js +6 -3
- package/cjs/services/earning-service/handlers/native-staking/base.js +4 -1
- package/cjs/services/earning-service/handlers/native-staking/dtao.js +68 -50
- package/cjs/services/earning-service/handlers/native-staking/tao.js +12 -2
- package/cjs/services/earning-service/handlers/special.js +18 -9
- package/cjs/services/earning-service/service.js +2 -1
- package/cjs/services/fee-service/utils/index.js +16 -4
- package/cjs/services/inapp-notification-service/index.js +19 -13
- package/cjs/services/keyring-service/context/handlers/Ledger.js +1 -1
- package/cjs/services/keyring-service/context/state.js +3 -0
- package/cjs/services/migration-service/scripts/DisableZeroBalanceTokens.js +60 -0
- package/cjs/services/migration-service/scripts/EnableChain.js +1 -1
- package/cjs/services/migration-service/scripts/index.js +3 -2
- package/cjs/services/swap-service/handler/asset-hub/handler.js +61 -314
- package/cjs/services/swap-service/handler/base-handler.js +406 -231
- package/cjs/services/swap-service/handler/chainflip-handler.js +18 -40
- package/cjs/services/swap-service/handler/hydradx-handler.js +77 -269
- package/cjs/services/swap-service/handler/simpleswap-handler.js +27 -48
- package/cjs/services/swap-service/handler/uniswap-handler.js +33 -54
- package/cjs/services/swap-service/index.js +154 -143
- package/cjs/services/swap-service/utils.js +107 -17
- package/cjs/services/transaction-service/index.js +1 -1
- package/cjs/services/transaction-service/utils.js +38 -14
- package/cjs/types/swap/index.js +13 -1
- package/cjs/utils/fee/transfer.js +52 -28
- package/cjs/utils/staticData/index.js +7 -2
- package/cjs/utils/swap.js +5 -1
- package/constants/blocked-actions.d.ts +1 -1
- package/constants/blocked-actions.js +1 -1
- package/constants/paraspell-chain-map.d.ts +1 -0
- package/constants/paraspell-chain-map.js +7 -0
- package/constants/remind-notification-time.d.ts +1 -1
- package/constants/remind-notification-time.js +1 -1
- package/core/logic-validation/swap.d.ts +15 -0
- package/core/logic-validation/swap.js +60 -4
- package/core/logic-validation/transfer.d.ts +1 -0
- package/core/logic-validation/transfer.js +12 -1
- package/core/substrate/xcm-parser.d.ts +1 -0
- package/core/substrate/xcm-parser.js +4 -1
- package/core/utils.d.ts +2 -2
- package/core/utils.js +36 -15
- package/koni/background/handlers/Extension.d.ts +1 -1
- package/koni/background/handlers/Extension.js +66 -98
- package/koni/background/handlers/State.d.ts +1 -0
- package/koni/background/handlers/State.js +7 -1
- package/package.json +23 -13
- package/packageInfo.js +1 -1
- package/services/balance-service/helpers/process.d.ts +2 -1
- package/services/balance-service/helpers/process.js +26 -0
- package/services/balance-service/index.js +11 -2
- package/services/balance-service/transfer/xcm/acrossBridge/index.d.ts +15 -0
- package/services/balance-service/transfer/xcm/acrossBridge/index.js +216 -0
- package/services/balance-service/transfer/xcm/availBridge.js +6 -6
- package/services/balance-service/transfer/xcm/index.d.ts +5 -1
- package/services/balance-service/transfer/xcm/index.js +85 -1
- package/services/balance-service/transfer/xcm/utils.d.ts +11 -0
- package/services/balance-service/transfer/xcm/utils.js +208 -0
- package/services/base/types.d.ts +0 -4
- package/services/chain-service/constants.d.ts +0 -1
- package/services/chain-service/constants.js +1 -2
- package/services/chain-service/index.d.ts +9 -2
- package/services/chain-service/index.js +72 -18
- package/services/chain-service/utils/patch.js +1 -1
- package/services/earning-service/handlers/base.d.ts +4 -3
- package/services/earning-service/handlers/base.js +6 -4
- package/services/earning-service/handlers/native-staking/base.js +4 -1
- package/services/earning-service/handlers/native-staking/dtao.d.ts +9 -6
- package/services/earning-service/handlers/native-staking/dtao.js +69 -48
- package/services/earning-service/handlers/native-staking/tao.js +12 -2
- package/services/earning-service/handlers/special.js +19 -10
- package/services/earning-service/service.d.ts +2 -1
- package/services/earning-service/service.js +2 -1
- package/services/fee-service/utils/index.d.ts +1 -0
- package/services/fee-service/utils/index.js +14 -4
- package/services/inapp-notification-service/index.js +13 -7
- package/services/keyring-service/context/handlers/Ledger.js +1 -1
- package/services/keyring-service/context/state.d.ts +1 -0
- package/services/keyring-service/context/state.js +3 -0
- package/services/migration-service/scripts/DisableZeroBalanceTokens.d.ts +4 -0
- package/services/migration-service/scripts/DisableZeroBalanceTokens.js +51 -0
- package/services/migration-service/scripts/EnableChain.js +1 -1
- package/services/migration-service/scripts/index.js +3 -2
- package/services/swap-service/handler/asset-hub/handler.d.ts +2 -9
- package/services/swap-service/handler/asset-hub/handler.js +64 -317
- package/services/swap-service/handler/base-handler.d.ts +6 -9
- package/services/swap-service/handler/base-handler.js +405 -230
- package/services/swap-service/handler/chainflip-handler.d.ts +2 -4
- package/services/swap-service/handler/chainflip-handler.js +15 -37
- package/services/swap-service/handler/hydradx-handler.d.ts +3 -10
- package/services/swap-service/handler/hydradx-handler.js +78 -270
- package/services/swap-service/handler/simpleswap-handler.d.ts +2 -4
- package/services/swap-service/handler/simpleswap-handler.js +24 -45
- package/services/swap-service/handler/uniswap-handler.d.ts +4 -6
- package/services/swap-service/handler/uniswap-handler.js +25 -46
- package/services/swap-service/index.d.ts +8 -14
- package/services/swap-service/index.js +141 -129
- package/services/swap-service/utils.d.ts +11 -3
- package/services/swap-service/utils.js +96 -15
- package/services/transaction-service/index.js +2 -2
- package/services/transaction-service/types.d.ts +3 -2
- package/services/transaction-service/utils.d.ts +1 -0
- package/services/transaction-service/utils.js +38 -15
- package/types/balance/transfer.d.ts +1 -0
- package/types/service-base.d.ts +2 -3
- package/types/swap/index.d.ts +25 -9
- package/types/swap/index.js +10 -0
- package/types/transaction/process.d.ts +19 -0
- package/types/transaction/request.d.ts +7 -0
- package/types/yield/actions/join/submit.d.ts +4 -1
- package/types/yield/actions/others.d.ts +2 -0
- package/utils/fee/transfer.d.ts +1 -0
- package/utils/fee/transfer.js +54 -30
- package/utils/staticData/index.d.ts +4 -1
- package/utils/staticData/index.js +5 -1
- package/utils/staticData/paraSpellChainMap.json +1 -0
- package/utils/swap.d.ts +3 -0
- package/utils/swap.js +3 -0
- package/cjs/services/swap-service/interface.js +0 -14
- package/services/swap-service/interface.d.ts +0 -9
- package/services/swap-service/interface.js +0 -8
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import { COMMON_CHAIN_SLUGS } from '@subwallet/chain-list';
|
|
5
|
+
import { _AssetRefPath } from '@subwallet/chain-list/types';
|
|
4
6
|
import { SwapError } from '@subwallet/extension-base/background/errors/SwapError';
|
|
5
7
|
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
8
|
+
import { ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
9
|
+
import { fetchBlockedConfigObjects, fetchLatestBlockedActionsAndFeatures, getPassConfigId } from '@subwallet/extension-base/constants';
|
|
6
10
|
import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
|
|
7
11
|
import { _getAssetOriginChain, _getChainSubstrateAddressPrefix } from '@subwallet/extension-base/services/chain-service/utils';
|
|
8
12
|
import { AssetHubSwapHandler } from '@subwallet/extension-base/services/swap-service/handler/asset-hub';
|
|
9
13
|
import { ChainflipSwapHandler } from '@subwallet/extension-base/services/swap-service/handler/chainflip-handler';
|
|
10
14
|
import { HydradxHandler } from '@subwallet/extension-base/services/swap-service/handler/hydradx-handler';
|
|
11
|
-
import {
|
|
12
|
-
import { BasicTxErrorType } from '@subwallet/extension-base/types';
|
|
15
|
+
import { findAllBridgeDestinations, findBridgeTransitDestination, findSwapTransitDestination, getBridgeStep, getSupportSwapChain, getSwapAltToken, getSwapStep, getTokenPairFromStep, isChainsHasSameProvider, SWAP_QUOTE_TIMEOUT_MAP } from '@subwallet/extension-base/services/swap-service/utils';
|
|
16
|
+
import { BasicTxErrorType, DynamicSwapType } from '@subwallet/extension-base/types';
|
|
13
17
|
import { DEFAULT_FIRST_STEP, MOCK_STEP_FEE } from '@subwallet/extension-base/types/service-base';
|
|
14
18
|
import { _SUPPORTED_SWAP_PROVIDERS, SwapErrorType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types/swap';
|
|
15
|
-
import { createPromiseHandler, reformatAddress } from '@subwallet/extension-base/utils';
|
|
19
|
+
import { _reformatAddressWithChain, createPromiseHandler, reformatAddress } from '@subwallet/extension-base/utils';
|
|
16
20
|
import subwalletApiSdk from '@subwallet/subwallet-api-sdk';
|
|
21
|
+
import BigN from 'bignumber.js';
|
|
22
|
+
import { t } from 'i18next';
|
|
17
23
|
import { BehaviorSubject } from 'rxjs';
|
|
18
24
|
import { SimpleSwapHandler } from "./handler/simpleswap-handler.js";
|
|
19
25
|
import { UniswapHandler } from "./handler/uniswap-handler.js";
|
|
20
|
-
export const _isChainSupportedByProvider = (providerSlug, chain) => {
|
|
21
|
-
const supportedChains = _PROVIDER_TO_SUPPORTED_PAIR_MAP[providerSlug];
|
|
22
|
-
return supportedChains ? supportedChains.includes(chain) : false;
|
|
23
|
-
};
|
|
24
26
|
export class SwapService {
|
|
25
27
|
swapPairSubject = new BehaviorSubject([]);
|
|
26
28
|
handlers = {};
|
|
@@ -35,13 +37,6 @@ export class SwapService {
|
|
|
35
37
|
async askProvidersForQuote(request) {
|
|
36
38
|
var _subwalletApiSdk$swap;
|
|
37
39
|
const availableQuotes = [];
|
|
38
|
-
await Promise.all(Object.values(this.handlers).map(async handler => {
|
|
39
|
-
// temporary solution to reduce number of requests to providers, will work as long as there's only 1 provider for 1 chain
|
|
40
|
-
|
|
41
|
-
if (handler.init && handler.isReady === false) {
|
|
42
|
-
await handler.init();
|
|
43
|
-
}
|
|
44
|
-
}));
|
|
45
40
|
const quotes = await ((_subwalletApiSdk$swap = subwalletApiSdk.swapApi) === null || _subwalletApiSdk$swap === void 0 ? void 0 : _subwalletApiSdk$swap.fetchSwapQuoteData(request));
|
|
46
41
|
if (Array.isArray(quotes)) {
|
|
47
42
|
quotes.forEach(quoteData => {
|
|
@@ -61,32 +56,17 @@ export class SwapService {
|
|
|
61
56
|
}
|
|
62
57
|
return availableQuotes;
|
|
63
58
|
}
|
|
64
|
-
getDefaultProcess(params) {
|
|
65
|
-
const result = {
|
|
66
|
-
totalFee: [MOCK_STEP_FEE],
|
|
67
|
-
steps: [DEFAULT_FIRST_STEP],
|
|
68
|
-
path: []
|
|
69
|
-
};
|
|
70
|
-
result.totalFee.push({
|
|
71
|
-
feeComponent: [],
|
|
72
|
-
feeOptions: [params.request.pair.from],
|
|
73
|
-
defaultFeeToken: params.request.pair.from
|
|
74
|
-
});
|
|
75
|
-
result.steps.push({
|
|
76
|
-
id: result.steps.length,
|
|
77
|
-
name: 'Swap',
|
|
78
|
-
type: SwapStepType.SWAP
|
|
79
|
-
});
|
|
80
|
-
return result;
|
|
81
|
-
}
|
|
82
59
|
getDefaultProcessV2(params) {
|
|
83
60
|
const result = {
|
|
84
61
|
totalFee: [MOCK_STEP_FEE],
|
|
85
62
|
steps: [DEFAULT_FIRST_STEP],
|
|
86
63
|
path: []
|
|
87
64
|
};
|
|
88
|
-
const swapPairInfo = params.path
|
|
89
|
-
|
|
65
|
+
const swapPairInfo = params.path.find(action => action.action === DynamicSwapType.SWAP);
|
|
66
|
+
if (!swapPairInfo) {
|
|
67
|
+
console.error('Swap pair is not found');
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
90
70
|
result.totalFee.push({
|
|
91
71
|
feeComponent: [],
|
|
92
72
|
feeOptions: [params.request.pair.from],
|
|
@@ -98,34 +78,18 @@ export class SwapService {
|
|
|
98
78
|
type: SwapStepType.SWAP,
|
|
99
79
|
metadata: {
|
|
100
80
|
sendingValue: params.request.fromAmount.toString(),
|
|
101
|
-
originTokenInfo: this.chainService.getAssetBySlug(swapPairInfo.from),
|
|
102
|
-
destinationTokenInfo: this.chainService.getAssetBySlug(swapPairInfo.to)
|
|
81
|
+
originTokenInfo: this.chainService.getAssetBySlug(swapPairInfo.pair.from),
|
|
82
|
+
destinationTokenInfo: this.chainService.getAssetBySlug(swapPairInfo.pair.to)
|
|
103
83
|
}
|
|
104
84
|
});
|
|
105
85
|
return result;
|
|
106
86
|
}
|
|
107
|
-
|
|
108
|
-
// deprecated
|
|
109
|
-
async generateOptimalProcess(params) {
|
|
110
|
-
if (!params.selectedQuote) {
|
|
111
|
-
return this.getDefaultProcess(params);
|
|
112
|
-
} else {
|
|
113
|
-
var _params$request$curre;
|
|
114
|
-
const providerId = ((_params$request$curre = params.request.currentQuote) === null || _params$request$curre === void 0 ? void 0 : _params$request$curre.id) || params.selectedQuote.provider.id;
|
|
115
|
-
const handler = this.handlers[providerId];
|
|
116
|
-
if (handler) {
|
|
117
|
-
return handler.generateOptimalProcess(params);
|
|
118
|
-
} else {
|
|
119
|
-
return this.getDefaultProcess(params);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
87
|
async generateOptimalProcessV2(params) {
|
|
124
88
|
if (!params.selectedQuote) {
|
|
125
89
|
return this.getDefaultProcessV2(params);
|
|
126
90
|
} else {
|
|
127
|
-
var _params$request$
|
|
128
|
-
const providerId = ((_params$request$
|
|
91
|
+
var _params$request$curre;
|
|
92
|
+
const providerId = ((_params$request$curre = params.request.currentQuote) === null || _params$request$curre === void 0 ? void 0 : _params$request$curre.id) || params.selectedQuote.provider.id;
|
|
129
93
|
const handler = this.handlers[providerId];
|
|
130
94
|
if (handler) {
|
|
131
95
|
return handler.generateOptimalProcessV2(params);
|
|
@@ -134,48 +98,6 @@ export class SwapService {
|
|
|
134
98
|
}
|
|
135
99
|
}
|
|
136
100
|
}
|
|
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
|
|
158
|
-
async handleSwapRequest(request) {
|
|
159
|
-
/*
|
|
160
|
-
* 1. Ask swap quotes from providers
|
|
161
|
-
* 2. Select the best quote
|
|
162
|
-
* 3. Generate optimal process for that quote
|
|
163
|
-
* */
|
|
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
101
|
async handleSwapRequestV2(request) {
|
|
180
102
|
/*
|
|
181
103
|
* 1. Find available path
|
|
@@ -184,14 +106,6 @@ export class SwapService {
|
|
|
184
106
|
* 4. Generate optimal process for that quote
|
|
185
107
|
* */
|
|
186
108
|
|
|
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
109
|
const {
|
|
196
110
|
path,
|
|
197
111
|
swapQuoteResponse
|
|
@@ -201,63 +115,131 @@ export class SwapService {
|
|
|
201
115
|
selectedQuote: swapQuoteResponse.optimalQuote,
|
|
202
116
|
path
|
|
203
117
|
});
|
|
118
|
+
console.log('-------');
|
|
119
|
+
console.log('optimalProcess', optimalProcess);
|
|
120
|
+
console.log('-------');
|
|
121
|
+
if (optimalProcess.steps.length - 1 < optimalProcess.path.length) {
|
|
122
|
+
// minus the fill info step
|
|
123
|
+
throw new Error('Swap pair is not found');
|
|
124
|
+
}
|
|
204
125
|
return {
|
|
205
126
|
process: optimalProcess,
|
|
206
127
|
quote: swapQuoteResponse
|
|
207
128
|
};
|
|
208
129
|
}
|
|
130
|
+
|
|
131
|
+
// todo: rewrite this function
|
|
209
132
|
getAvailablePath(request) {
|
|
210
133
|
const {
|
|
134
|
+
address,
|
|
211
135
|
pair
|
|
212
136
|
} = request;
|
|
213
137
|
// todo: control provider tighter
|
|
214
|
-
const
|
|
138
|
+
const supportSwapChains = getSupportSwapChain();
|
|
215
139
|
const fromToken = this.chainService.getAssetBySlug(pair.from);
|
|
216
140
|
const toToken = this.chainService.getAssetBySlug(pair.to);
|
|
217
141
|
const fromChain = _getAssetOriginChain(fromToken);
|
|
218
142
|
const toChain = _getAssetOriginChain(toToken);
|
|
219
143
|
const toChainInfo = this.chainService.getChainInfoByKey(toChain);
|
|
220
|
-
const
|
|
144
|
+
const assetRefMap = this.chainService.getAssetRefMap();
|
|
145
|
+
let process = [];
|
|
221
146
|
if (!fromToken || !toToken) {
|
|
222
147
|
throw Error('Token not found');
|
|
223
148
|
}
|
|
224
149
|
if (!fromChain || !toChain) {
|
|
225
150
|
throw Error('Token metadata error');
|
|
226
151
|
}
|
|
152
|
+
const directXcmRef = Object.values(assetRefMap).find(assetRef => assetRef.path === _AssetRefPath.XCM && assetRef.srcAsset === fromToken.slug && assetRef.destAsset === toToken.slug);
|
|
153
|
+
if (directXcmRef) {
|
|
154
|
+
return [[], undefined];
|
|
155
|
+
}
|
|
227
156
|
|
|
228
157
|
// SWAP: 2 tokens in the same chain and chain has dex
|
|
229
158
|
if (isChainsHasSameProvider(fromChain, toChain)) {
|
|
230
159
|
// there's a dex that can support direct swapping
|
|
231
|
-
|
|
160
|
+
process.push(getSwapStep(fromToken.slug, toToken.slug));
|
|
161
|
+
return [process, request];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// ------------------------
|
|
165
|
+
// BRIDGE -> SWAP: Try to find a token in dest chain that can bridge from fromToken
|
|
166
|
+
const bridgeTransit = findBridgeTransitDestination(assetRefMap, fromToken, toToken);
|
|
167
|
+
if (bridgeTransit && supportSwapChains.includes(toChain)) {
|
|
168
|
+
const swapStep = getSwapStep(bridgeTransit, toToken.slug);
|
|
169
|
+
process.push(getBridgeStep(fromToken.slug, bridgeTransit));
|
|
232
170
|
process.push(swapStep);
|
|
233
171
|
return [process, {
|
|
234
172
|
...request,
|
|
173
|
+
address: reformatAddress(address, _getChainSubstrateAddressPrefix(toChainInfo)),
|
|
235
174
|
pair: swapStep.pair
|
|
236
175
|
}];
|
|
237
176
|
}
|
|
238
177
|
|
|
239
|
-
//
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
const swapStep = getSwapStep(
|
|
244
|
-
process.push(bridgeStep);
|
|
178
|
+
// ------------------------
|
|
179
|
+
// SWAP -> BRIDGE: Try to find a token in from chain that can bridge to toToken
|
|
180
|
+
const swapTransit = findSwapTransitDestination(assetRefMap, fromToken, toToken);
|
|
181
|
+
if (swapTransit && supportSwapChains.includes(fromChain)) {
|
|
182
|
+
const swapStep = getSwapStep(fromToken.slug, swapTransit);
|
|
245
183
|
process.push(swapStep);
|
|
184
|
+
process.push(getBridgeStep(swapTransit, toToken.slug));
|
|
246
185
|
return [process, {
|
|
247
186
|
...request,
|
|
248
|
-
address: reformatAddress(request.address, _getChainSubstrateAddressPrefix(toChainInfo)),
|
|
249
187
|
pair: swapStep.pair
|
|
250
188
|
}];
|
|
251
189
|
}
|
|
252
190
|
|
|
253
|
-
//
|
|
191
|
+
// ------------------------
|
|
192
|
+
// BRIDGE -> SWAP -> BRIDGE: Try to find a tri-step path to swap
|
|
193
|
+
const processList = [];
|
|
194
|
+
const swapPairList = [];
|
|
195
|
+
const allBridgeDestinations = findAllBridgeDestinations(assetRefMap, fromToken);
|
|
196
|
+
|
|
197
|
+
// currently find first path. Todo: return all paths or best path.
|
|
198
|
+
for (const bridgeTransit of allBridgeDestinations) {
|
|
199
|
+
process = [];
|
|
200
|
+
const bridgeDestinationInfo = this.chainService.getAssetBySlug(bridgeTransit);
|
|
201
|
+
const swapTransit = findSwapTransitDestination(assetRefMap, bridgeDestinationInfo, toToken);
|
|
202
|
+
if (bridgeTransit === swapTransit) {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (swapTransit && supportSwapChains.includes(bridgeDestinationInfo.originChain)) {
|
|
206
|
+
const swapStep = getSwapStep(bridgeTransit, swapTransit);
|
|
207
|
+
process.push(getBridgeStep(fromToken.slug, bridgeTransit));
|
|
208
|
+
process.push(swapStep);
|
|
209
|
+
process.push(getBridgeStep(swapTransit, toToken.slug));
|
|
210
|
+
|
|
211
|
+
// set the highest priority to hydration provider
|
|
212
|
+
if (bridgeDestinationInfo.originChain === COMMON_CHAIN_SLUGS.HYDRADX) {
|
|
213
|
+
return [process, {
|
|
214
|
+
...request,
|
|
215
|
+
address: _reformatAddressWithChain(address, this.chainService.getChainInfoByKey(COMMON_CHAIN_SLUGS.HYDRADX)),
|
|
216
|
+
pair: swapStep.pair
|
|
217
|
+
}];
|
|
218
|
+
}
|
|
219
|
+
processList.push(process);
|
|
220
|
+
swapPairList.push(swapStep.pair);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// get first process
|
|
225
|
+
if (processList.length && swapPairList.length) {
|
|
226
|
+
const [firstProcess, firstSwapPair] = [processList[0], swapPairList[0]];
|
|
227
|
+
const chainSwap = this.chainService.getAssetBySlug(firstSwapPair.from).originChain;
|
|
228
|
+
return [firstProcess, {
|
|
229
|
+
...request,
|
|
230
|
+
address: _reformatAddressWithChain(address, this.chainService.getChainInfoByKey(chainSwap)),
|
|
231
|
+
pair: firstSwapPair
|
|
232
|
+
}];
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// todo: encapsulate each route type to function
|
|
254
236
|
|
|
255
237
|
return [[], undefined];
|
|
256
238
|
}
|
|
257
239
|
async getLatestQuoteFromSwapRequest(request) {
|
|
258
240
|
const [path, directSwapRequest] = this.getAvailablePath(request);
|
|
259
241
|
if (!directSwapRequest) {
|
|
260
|
-
throw Error('Swap pair not found');
|
|
242
|
+
throw Error('Swap pair is not found');
|
|
261
243
|
}
|
|
262
244
|
const swapQuoteResponse = await this.getLatestDirectQuotes(directSwapRequest);
|
|
263
245
|
return {
|
|
@@ -284,12 +266,32 @@ export class SwapService {
|
|
|
284
266
|
quoteError = (preferredErrorResp === null || preferredErrorResp === void 0 ? void 0 : preferredErrorResp.error) || (defaultErrorResp === null || defaultErrorResp === void 0 ? void 0 : defaultErrorResp.error);
|
|
285
267
|
} else {
|
|
286
268
|
var _selectedQuote;
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
269
|
+
// sort quotes by largest receivable, with priority for some providers
|
|
270
|
+
availableQuotes.sort((a, b) => {
|
|
271
|
+
const bnToAmountA = BigN(a.toAmount);
|
|
272
|
+
const bnToAmountB = BigN(b.toAmount);
|
|
273
|
+
if (bnToAmountB.eq(bnToAmountA) && [SwapProviderId.CHAIN_FLIP_MAINNET, SwapProviderId.UNISWAP].includes(a.provider.id)) {
|
|
274
|
+
return -1;
|
|
275
|
+
}
|
|
276
|
+
if (bnToAmountA.gt(bnToAmountB)) {
|
|
277
|
+
return -1;
|
|
278
|
+
} else {
|
|
279
|
+
return 1;
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
if (request.preferredProvider) {
|
|
283
|
+
selectedQuote = availableQuotes.find(quote => quote.provider.id === request.preferredProvider) || availableQuotes[0];
|
|
284
|
+
} else {
|
|
285
|
+
selectedQuote = availableQuotes[0];
|
|
286
|
+
}
|
|
291
287
|
aliveUntil = ((_selectedQuote = selectedQuote) === null || _selectedQuote === void 0 ? void 0 : _selectedQuote.aliveUntil) || +Date.now() + SWAP_QUOTE_TIMEOUT_MAP.default;
|
|
292
288
|
}
|
|
289
|
+
const neededProviders = availableQuotes.map(quote => quote.provider.id);
|
|
290
|
+
await Promise.all(Object.values(this.handlers).map(async handler => {
|
|
291
|
+
if (neededProviders.includes(handler.providerSlug) && handler.init && handler.isReady === false) {
|
|
292
|
+
await handler.init();
|
|
293
|
+
}
|
|
294
|
+
}));
|
|
293
295
|
return {
|
|
294
296
|
optimalQuote: selectedQuote,
|
|
295
297
|
quotes: availableQuotes,
|
|
@@ -393,18 +395,29 @@ export class SwapService {
|
|
|
393
395
|
};
|
|
394
396
|
});
|
|
395
397
|
}
|
|
396
|
-
|
|
397
|
-
// private getSwapPairMetadata (slug: string): Record<string, any> | undefined {
|
|
398
|
-
// return this.getSwapPairs().find((pair) => pair.slug === slug)?.metadata;
|
|
399
|
-
// }
|
|
400
|
-
|
|
401
|
-
async validateSwapProcess(params) {
|
|
398
|
+
async validateSwapProcessV2(params) {
|
|
402
399
|
const providerId = params.selectedQuote.provider.id;
|
|
403
400
|
const handler = this.handlers[providerId];
|
|
404
|
-
if (params.currentStep >
|
|
405
|
-
// only validate from the first step
|
|
401
|
+
if (params.currentStep > 0) {
|
|
406
402
|
return [];
|
|
407
403
|
}
|
|
404
|
+
const blockedConfigObjects = await fetchBlockedConfigObjects();
|
|
405
|
+
const currentConfig = this.state.settingService.getEnvironmentSetting();
|
|
406
|
+
const passBlockedConfigId = getPassConfigId(currentConfig, blockedConfigObjects);
|
|
407
|
+
const blockedActionsFeaturesMaps = await fetchLatestBlockedActionsAndFeatures(passBlockedConfigId);
|
|
408
|
+
const originSwapPairInfo = getTokenPairFromStep(params.process.steps);
|
|
409
|
+
if (!originSwapPairInfo) {
|
|
410
|
+
return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
|
|
411
|
+
}
|
|
412
|
+
const currentAction = `${ExtrinsicType.SWAP}___${originSwapPairInfo.slug}___${params.selectedQuote.provider.id}`;
|
|
413
|
+
for (const blockedActionsFeaturesMap of blockedActionsFeaturesMaps) {
|
|
414
|
+
const {
|
|
415
|
+
blockedActionsMap
|
|
416
|
+
} = blockedActionsFeaturesMap;
|
|
417
|
+
if (blockedActionsMap.swap.includes(currentAction)) {
|
|
418
|
+
return [new TransactionError(BasicTxErrorType.UNSUPPORTED, t('Feature under maintenance. Try again later'))];
|
|
419
|
+
}
|
|
420
|
+
}
|
|
408
421
|
if (handler) {
|
|
409
422
|
return handler.validateSwapProcessV2(params);
|
|
410
423
|
} else {
|
|
@@ -417,7 +430,6 @@ export class SwapService {
|
|
|
417
430
|
// todo: do better to handle error generating steps
|
|
418
431
|
return Promise.reject(new TransactionError(BasicTxErrorType.INTERNAL_ERROR, 'Please check your network and try again'));
|
|
419
432
|
}
|
|
420
|
-
console.log('handling swap process: ', params.process);
|
|
421
433
|
if (handler) {
|
|
422
434
|
return handler.handleSwapProcess(params);
|
|
423
435
|
} else {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { _AssetRef, _ChainAsset } from '@subwallet/chain-list/types';
|
|
2
|
-
import { DynamicSwapAction } from '@subwallet/extension-base/
|
|
3
|
-
import { CommonStepDetail } from '@subwallet/extension-base/types';
|
|
2
|
+
import { CommonStepDetail, DynamicSwapAction } from '@subwallet/extension-base/types';
|
|
4
3
|
import { SwapPair } from '@subwallet/extension-base/types/swap';
|
|
5
4
|
export declare const CHAIN_FLIP_TESTNET_EXPLORER = "https://blocks-perseverance.chainflip.io";
|
|
6
5
|
export declare const CHAIN_FLIP_MAINNET_EXPLORER = "https://scan.chainflip.io";
|
|
@@ -9,6 +8,7 @@ export declare const SIMPLE_SWAP_SUPPORTED_TESTNET_ASSET_MAPPING: Record<string,
|
|
|
9
8
|
export declare const SWAP_QUOTE_TIMEOUT_MAP: Record<string, number>;
|
|
10
9
|
export declare const _PROVIDER_TO_SUPPORTED_PAIR_MAP: Record<string, string[]>;
|
|
11
10
|
export declare const FEE_RATE_MULTIPLIER: Record<string, number>;
|
|
11
|
+
export declare function getSupportSwapChain(): string[];
|
|
12
12
|
export declare function getSwapAlternativeAsset(swapPair: SwapPair): string | undefined;
|
|
13
13
|
export declare function getSwapAltToken(chainAsset: _ChainAsset): string | undefined;
|
|
14
14
|
export declare function calculateSwapRate(fromAmount: string, toAmount: string, fromAsset: _ChainAsset, toAsset: _ChainAsset): number;
|
|
@@ -28,6 +28,14 @@ export declare function getChainflipBroker(isTestnet: boolean): {
|
|
|
28
28
|
export declare function getChainflipSwap(isTestnet: boolean): string;
|
|
29
29
|
export declare function getBridgeStep(from: string, to: string): DynamicSwapAction;
|
|
30
30
|
export declare function getSwapStep(from: string, to: string): DynamicSwapAction;
|
|
31
|
-
export declare function
|
|
31
|
+
export declare function findBridgeTransitDestination(assetRefMap: Record<string, _AssetRef>, fromToken: _ChainAsset, toToken: _ChainAsset): string | undefined;
|
|
32
|
+
export declare function findSwapTransitDestination(assetRefMap: Record<string, _AssetRef>, fromToken: _ChainAsset, toToken: _ChainAsset): string | undefined;
|
|
33
|
+
export declare function findAllBridgeDestinations(assetRefMap: Record<string, _AssetRef>, fromToken: _ChainAsset): string[];
|
|
34
|
+
export declare function getAmountAfterSlippage(amount: string, slippage: number): string;
|
|
32
35
|
export declare function isChainsHasSameProvider(fromChain: string, toChain: string): boolean;
|
|
36
|
+
export declare function getLastAmountFromSteps(steps: CommonStepDetail[]): string | undefined;
|
|
37
|
+
export declare function getFirstAmountFromSteps(steps: CommonStepDetail[]): string | undefined;
|
|
38
|
+
export declare function getChainRouteFromSteps(steps: CommonStepDetail[]): string[];
|
|
33
39
|
export declare function getTokenPairFromStep(steps: CommonStepDetail[]): SwapPair | undefined;
|
|
40
|
+
export declare function getSwapChainsFromPath(path: DynamicSwapAction[]): string[];
|
|
41
|
+
export declare const DEFAULT_EXCESS_AMOUNT_WEIGHT = 1.04;
|
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
import { COMMON_ASSETS, COMMON_CHAIN_SLUGS } from '@subwallet/chain-list';
|
|
5
5
|
import { _AssetRefPath } from '@subwallet/chain-list/types';
|
|
6
|
-
import { _getAssetDecimals } from '@subwallet/extension-base/services/chain-service/utils';
|
|
6
|
+
import { _getAssetDecimals, _getAssetOriginChain, _getOriginChainOfAsset, _parseAssetRefKey } from '@subwallet/extension-base/services/chain-service/utils';
|
|
7
7
|
import { CHAINFLIP_BROKER_API } from '@subwallet/extension-base/services/swap-service/handler/chainflip-handler';
|
|
8
|
-
import { DynamicSwapType } from '@subwallet/extension-base/
|
|
9
|
-
import { CommonStepType } from '@subwallet/extension-base/types';
|
|
8
|
+
import { CommonStepType, DynamicSwapType, SwapStepType } from '@subwallet/extension-base/types';
|
|
10
9
|
import { SwapProviderId } from '@subwallet/extension-base/types/swap';
|
|
11
10
|
import BigN from 'bignumber.js';
|
|
12
11
|
export const CHAIN_FLIP_TESTNET_EXPLORER = 'https://blocks-perseverance.chainflip.io';
|
|
@@ -21,7 +20,7 @@ export const SIMPLE_SWAP_SUPPORTED_TESTNET_ASSET_MAPPING = {
|
|
|
21
20
|
};
|
|
22
21
|
export const SWAP_QUOTE_TIMEOUT_MAP = {
|
|
23
22
|
// in milliseconds
|
|
24
|
-
default:
|
|
23
|
+
default: 90000,
|
|
25
24
|
[SwapProviderId.CHAIN_FLIP_TESTNET]: 30000,
|
|
26
25
|
[SwapProviderId.CHAIN_FLIP_MAINNET]: 30000
|
|
27
26
|
};
|
|
@@ -43,6 +42,9 @@ export const FEE_RATE_MULTIPLIER = {
|
|
|
43
42
|
medium: 1.2,
|
|
44
43
|
high: 2
|
|
45
44
|
};
|
|
45
|
+
export function getSupportSwapChain() {
|
|
46
|
+
return [...new Set(Object.values(_PROVIDER_TO_SUPPORTED_PAIR_MAP).flat())];
|
|
47
|
+
}
|
|
46
48
|
export function getSwapAlternativeAsset(swapPair) {
|
|
47
49
|
var _swapPair$metadata;
|
|
48
50
|
return swapPair === null || swapPair === void 0 ? void 0 : (_swapPair$metadata = swapPair.metadata) === null || _swapPair$metadata === void 0 ? void 0 : _swapPair$metadata.alternativeAsset;
|
|
@@ -52,15 +54,15 @@ export function getSwapAltToken(chainAsset) {
|
|
|
52
54
|
return (_chainAsset$metadata = chainAsset.metadata) === null || _chainAsset$metadata === void 0 ? void 0 : _chainAsset$metadata.alternativeSwapAsset;
|
|
53
55
|
}
|
|
54
56
|
export function calculateSwapRate(fromAmount, toAmount, fromAsset, toAsset) {
|
|
55
|
-
const bnFromAmount =
|
|
56
|
-
const bnToAmount =
|
|
57
|
+
const bnFromAmount = BigN(fromAmount);
|
|
58
|
+
const bnToAmount = BigN(toAmount);
|
|
57
59
|
const decimalDiff = _getAssetDecimals(toAsset) - _getAssetDecimals(fromAsset);
|
|
58
60
|
const bnRate = bnFromAmount.div(bnToAmount);
|
|
59
61
|
return 1 / bnRate.times(10 ** decimalDiff).toNumber();
|
|
60
62
|
}
|
|
61
63
|
export function convertSwapRate(rate, fromAsset, toAsset) {
|
|
62
64
|
const decimalDiff = _getAssetDecimals(toAsset) - _getAssetDecimals(fromAsset);
|
|
63
|
-
const bnRate =
|
|
65
|
+
const bnRate = BigN(rate);
|
|
64
66
|
return bnRate.times(10 ** decimalDiff).pow(-1).toNumber();
|
|
65
67
|
}
|
|
66
68
|
export function getChainflipOptions(isTestnet) {
|
|
@@ -101,6 +103,7 @@ export function getBridgeStep(from, to) {
|
|
|
101
103
|
action: DynamicSwapType.BRIDGE,
|
|
102
104
|
pair: {
|
|
103
105
|
slug: `${from}___${to}`,
|
|
106
|
+
// todo: recheck with assetRef format from chain list
|
|
104
107
|
from,
|
|
105
108
|
to
|
|
106
109
|
}
|
|
@@ -111,18 +114,33 @@ export function getSwapStep(from, to) {
|
|
|
111
114
|
action: DynamicSwapType.SWAP,
|
|
112
115
|
pair: {
|
|
113
116
|
slug: `${from}___${to}`,
|
|
117
|
+
// todo: recheck with assetRef format from chain list
|
|
114
118
|
from,
|
|
115
119
|
to
|
|
116
120
|
}
|
|
117
121
|
};
|
|
118
122
|
}
|
|
119
|
-
export function
|
|
120
|
-
const foundAssetRef = Object.values(assetRefMap).find(assetRef => assetRef.srcAsset ===
|
|
123
|
+
export function findBridgeTransitDestination(assetRefMap, fromToken, toToken) {
|
|
124
|
+
const foundAssetRef = Object.values(assetRefMap).find(assetRef => assetRef.srcAsset === fromToken.slug && assetRef.destChain === _getAssetOriginChain(toToken) && assetRef.path === _AssetRefPath.XCM);
|
|
121
125
|
if (foundAssetRef) {
|
|
122
126
|
return foundAssetRef.destAsset;
|
|
123
127
|
}
|
|
124
128
|
return undefined;
|
|
125
129
|
}
|
|
130
|
+
export function findSwapTransitDestination(assetRefMap, fromToken, toToken) {
|
|
131
|
+
const foundAssetRef = Object.values(assetRefMap).find(assetRef => assetRef.destAsset === toToken.slug && assetRef.srcChain === _getAssetOriginChain(fromToken) && assetRef.path === _AssetRefPath.XCM);
|
|
132
|
+
if (foundAssetRef) {
|
|
133
|
+
return foundAssetRef.srcAsset;
|
|
134
|
+
}
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
export function findAllBridgeDestinations(assetRefMap, fromToken) {
|
|
138
|
+
const foundAssetRefs = Object.values(assetRefMap).filter(assetRef => assetRef.srcAsset === fromToken.slug && assetRef.path === _AssetRefPath.XCM);
|
|
139
|
+
return foundAssetRefs.map(assetRef => assetRef.destAsset);
|
|
140
|
+
}
|
|
141
|
+
export function getAmountAfterSlippage(amount, slippage) {
|
|
142
|
+
return BigN(amount).multipliedBy(BigN(1).minus(BigN(slippage))).integerValue(BigN.ROUND_DOWN).toString();
|
|
143
|
+
}
|
|
126
144
|
export function isChainsHasSameProvider(fromChain, toChain) {
|
|
127
145
|
// todo: a provider may support multiple chains but not cross-chain swaps
|
|
128
146
|
for (const group of Object.values(_PROVIDER_TO_SUPPORTED_PAIR_MAP)) {
|
|
@@ -132,27 +150,90 @@ export function isChainsHasSameProvider(fromChain, toChain) {
|
|
|
132
150
|
}
|
|
133
151
|
return false;
|
|
134
152
|
}
|
|
135
|
-
export function
|
|
153
|
+
export function getLastAmountFromSteps(steps) {
|
|
154
|
+
var _lastStep$metadata;
|
|
155
|
+
const lastStep = steps[steps.length - 1]; // last step
|
|
156
|
+
const lastAmount = lastStep === null || lastStep === void 0 ? void 0 : (_lastStep$metadata = lastStep.metadata) === null || _lastStep$metadata === void 0 ? void 0 : _lastStep$metadata.destinationValue;
|
|
157
|
+
return lastAmount !== null && lastAmount !== void 0 ? lastAmount : undefined;
|
|
158
|
+
}
|
|
159
|
+
export function getFirstAmountFromSteps(steps) {
|
|
160
|
+
var _firstStep$metadata;
|
|
161
|
+
const firstStep = steps[1]; // first step after default step
|
|
162
|
+
const firstAmount = firstStep === null || firstStep === void 0 ? void 0 : (_firstStep$metadata = firstStep.metadata) === null || _firstStep$metadata === void 0 ? void 0 : _firstStep$metadata.sendingValue;
|
|
163
|
+
return firstAmount !== null && firstAmount !== void 0 ? firstAmount : undefined;
|
|
164
|
+
}
|
|
165
|
+
export function getChainRouteFromSteps(steps) {
|
|
166
|
+
// todo: handle metadata for other providers than hydra & pah. Also add validate metadata.
|
|
136
167
|
const mainSteps = steps.filter(step => step.type !== CommonStepType.DEFAULT);
|
|
168
|
+
return mainSteps.reduce((chainRoute, currentStep, currentIndex) => {
|
|
169
|
+
const metadata = currentStep.metadata;
|
|
170
|
+
if (!metadata) {
|
|
171
|
+
console.error('Step has no metadata');
|
|
172
|
+
return chainRoute;
|
|
173
|
+
}
|
|
174
|
+
if (currentIndex === 0) {
|
|
175
|
+
chainRoute.push(metadata.originTokenInfo.originChain);
|
|
176
|
+
chainRoute.push(metadata.destinationTokenInfo.originChain);
|
|
177
|
+
} else {
|
|
178
|
+
chainRoute.push(metadata.destinationTokenInfo.originChain);
|
|
179
|
+
}
|
|
180
|
+
return chainRoute;
|
|
181
|
+
}, []);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// note: this function may return undefined if metadata version is < 2 or does not exist
|
|
185
|
+
export function getTokenPairFromStep(steps) {
|
|
186
|
+
// todo: review this
|
|
187
|
+
const mainSteps = steps.filter(step => step.type !== CommonStepType.DEFAULT && step.type !== CommonStepType.TOKEN_APPROVAL && step.type !== SwapStepType.PERMIT);
|
|
137
188
|
if (!mainSteps.length) {
|
|
138
189
|
return undefined;
|
|
139
190
|
}
|
|
191
|
+
const isStepValidIfSwap = step => {
|
|
192
|
+
const metadata = step.metadata;
|
|
193
|
+
return step.type !== SwapStepType.SWAP || !!(metadata !== null && metadata !== void 0 && metadata.version) && (metadata === null || metadata === void 0 ? void 0 : metadata.version) >= 2;
|
|
194
|
+
};
|
|
140
195
|
if (mainSteps.length === 1) {
|
|
141
|
-
|
|
142
|
-
|
|
196
|
+
if (!isStepValidIfSwap(mainSteps[0])) {
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
const metadata = mainSteps[0].metadata;
|
|
200
|
+
if (!metadata) {
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
143
203
|
return {
|
|
144
204
|
from: metadata.originTokenInfo.slug,
|
|
145
205
|
to: metadata.destinationTokenInfo.slug,
|
|
146
|
-
slug:
|
|
206
|
+
slug: _parseAssetRefKey(metadata.originTokenInfo.slug, metadata.destinationTokenInfo.slug)
|
|
147
207
|
};
|
|
148
208
|
}
|
|
149
209
|
const firstStep = mainSteps[0];
|
|
150
210
|
const lastStep = mainSteps[mainSteps.length - 1];
|
|
211
|
+
if (!isStepValidIfSwap(firstStep) || !isStepValidIfSwap(lastStep)) {
|
|
212
|
+
return undefined;
|
|
213
|
+
}
|
|
151
214
|
const firstMetadata = firstStep.metadata;
|
|
152
215
|
const lastMetadata = lastStep.metadata;
|
|
216
|
+
if (!firstMetadata || !lastMetadata) {
|
|
217
|
+
return undefined;
|
|
218
|
+
}
|
|
153
219
|
return {
|
|
154
220
|
from: firstMetadata.originTokenInfo.slug,
|
|
155
221
|
to: lastMetadata.destinationTokenInfo.slug,
|
|
156
|
-
slug:
|
|
222
|
+
slug: _parseAssetRefKey(firstMetadata.originTokenInfo.slug, lastMetadata.destinationTokenInfo.slug)
|
|
157
223
|
};
|
|
158
|
-
}
|
|
224
|
+
}
|
|
225
|
+
export function getSwapChainsFromPath(path) {
|
|
226
|
+
const swapChains = [];
|
|
227
|
+
path.forEach(pathElement => {
|
|
228
|
+
const fromAssetOriginChain = _getOriginChainOfAsset(pathElement.pair.from);
|
|
229
|
+
const toAssetOriginChain = _getOriginChainOfAsset(pathElement.pair.to);
|
|
230
|
+
if (swapChains.at(-1) !== fromAssetOriginChain) {
|
|
231
|
+
swapChains.push(fromAssetOriginChain);
|
|
232
|
+
}
|
|
233
|
+
if (swapChains.at(-1) !== toAssetOriginChain) {
|
|
234
|
+
swapChains.push(toAssetOriginChain);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
return swapChains;
|
|
238
|
+
}
|
|
239
|
+
export const DEFAULT_EXCESS_AMOUNT_WEIGHT = 1.04; // add 2%
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { EvmProviderError } from '@subwallet/extension-base/background/errors/EvmProviderError';
|
|
5
5
|
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
6
6
|
import { ChainType, EvmProviderErrorType, ExtrinsicStatus, ExtrinsicType, NotificationType, TransactionDirection } from '@subwallet/extension-base/background/KoniTypes';
|
|
7
|
-
import { _SUPPORT_TOKEN_PAY_FEE_GROUP, ALL_ACCOUNT_KEY, fetchBlockedConfigObjects,
|
|
7
|
+
import { _SUPPORT_TOKEN_PAY_FEE_GROUP, ALL_ACCOUNT_KEY, fetchBlockedConfigObjects, fetchLatestBlockedActionsAndFeatures, getPassConfigId } from '@subwallet/extension-base/constants';
|
|
8
8
|
import { checkBalanceWithTransactionFee, checkSigningAccountForTransaction, checkSupportForAction, checkSupportForFeature, checkSupportForTransaction, estimateFeeForTransaction } from '@subwallet/extension-base/core/logic-validation/transfer';
|
|
9
9
|
import { cellToBase64Str, externalMessage, getTransferCellPromise } from '@subwallet/extension-base/services/balance-service/helpers/subscribe/ton/utils';
|
|
10
10
|
import { _getAssetDecimals, _getAssetSymbol, _getChainNativeTokenBasicInfo, _getEvmChainId, _isChainEvmCompatible, _isNativeTokenBySlug } from '@subwallet/extension-base/services/chain-service/utils';
|
|
@@ -80,7 +80,7 @@ export default class TransactionService {
|
|
|
80
80
|
const blockedConfigObjects = await fetchBlockedConfigObjects();
|
|
81
81
|
const currentConfig = this.state.settingService.getEnvironmentSetting();
|
|
82
82
|
const passBlockedConfigId = getPassConfigId(currentConfig, blockedConfigObjects);
|
|
83
|
-
const blockedActionsFeaturesMaps = await
|
|
83
|
+
const blockedActionsFeaturesMaps = await fetchLatestBlockedActionsAndFeatures(passBlockedConfigId);
|
|
84
84
|
for (const blockedActionsFeaturesMap of blockedActionsFeaturesMaps) {
|
|
85
85
|
const {
|
|
86
86
|
blockedActionsMap,
|