@subwallet/extension-base 1.3.29-0 → 1.3.30-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/background/KoniTypes.d.ts +4 -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/remind-notification-time.js +3 -3
- package/cjs/core/logic-validation/swap.js +63 -4
- package/cjs/core/utils.js +9 -3
- package/cjs/koni/background/handlers/Extension.js +5 -82
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/transfer/xcm/availBridge.js +6 -6
- package/cjs/services/chain-service/constants.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/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/swap-service/handler/asset-hub/handler.js +61 -314
- package/cjs/services/swap-service/handler/base-handler.js +393 -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/types/swap/index.js +13 -1
- package/cjs/utils/swap.js +5 -1
- package/constants/blocked-actions.d.ts +1 -1
- package/constants/blocked-actions.js +1 -1
- 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/utils.js +9 -3
- package/koni/background/handlers/Extension.d.ts +0 -1
- package/koni/background/handlers/Extension.js +6 -83
- package/package.json +6 -12
- package/packageInfo.js +1 -1
- package/services/balance-service/transfer/xcm/availBridge.js +6 -6
- package/services/base/types.d.ts +0 -4
- package/services/chain-service/constants.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/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/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 +391 -229
- 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/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/yield/actions/join/submit.d.ts +4 -1
- package/types/yield/actions/others.d.ts +2 -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
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
import { COMMON_ASSETS, COMMON_CHAIN_SLUGS } from '@subwallet/chain-list';
|
|
5
5
|
import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
6
|
import { CRON_LISTEN_AVAIL_BRIDGE_CLAIM } from '@subwallet/extension-base/constants';
|
|
7
|
-
import {
|
|
7
|
+
import { fetchLatestRemindNotificationTime } from '@subwallet/extension-base/constants/remind-notification-time';
|
|
8
8
|
import { ServiceStatus } from '@subwallet/extension-base/services/base/types';
|
|
9
9
|
import { _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/earning-service/constants';
|
|
10
10
|
import { NotificationDescriptionMap, NotificationTitleMap, ONE_DAY_MILLISECOND } from '@subwallet/extension-base/services/inapp-notification-service/consts';
|
|
11
11
|
import { NotificationActionType, NotificationTab } from '@subwallet/extension-base/services/inapp-notification-service/interfaces';
|
|
12
12
|
import { AvailBridgeSourceChain, fetchAllAvailBridgeClaimable, fetchPolygonBridgeTransactions, hrsToMillisecond } from '@subwallet/extension-base/services/inapp-notification-service/utils';
|
|
13
|
+
import { getTokenPairFromStep } from '@subwallet/extension-base/services/swap-service/utils';
|
|
13
14
|
import { ProcessType, YieldPoolType } from '@subwallet/extension-base/types';
|
|
14
15
|
import { formatNumber, getAddressesByChainType, reformatAddress } from '@subwallet/extension-base/utils';
|
|
15
16
|
import { isSubstrateAddress } from '@subwallet/keyring';
|
|
@@ -148,7 +149,7 @@ export class InappNotificationService {
|
|
|
148
149
|
const [comparedNotifications, remindTimeConfig] = await Promise.all([this.fetchNotificationsByParams({
|
|
149
150
|
notificationTab: NotificationTab.ALL,
|
|
150
151
|
proxyId
|
|
151
|
-
}), await
|
|
152
|
+
}), await fetchLatestRemindNotificationTime()]);
|
|
152
153
|
for (const candidateNotification of notifications) {
|
|
153
154
|
candidateNotification.title = candidateNotification.title.replace('{{accountName}}', accountName);
|
|
154
155
|
if (this.passValidateNotification(candidateNotification, comparedNotifications, remindTimeConfig)) {
|
|
@@ -349,12 +350,17 @@ export class InappNotificationService {
|
|
|
349
350
|
actionType = NotificationActionType.SWAP;
|
|
350
351
|
extrinsicType = ExtrinsicType.SWAP;
|
|
351
352
|
const combineInfo = process.combineInfo;
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
353
|
+
const targetPair = (() => {
|
|
354
|
+
try {
|
|
355
|
+
return getTokenPairFromStep(combineInfo.process.steps) || combineInfo.quote.pair;
|
|
356
|
+
} catch (e) {
|
|
357
|
+
return combineInfo.quote.pair;
|
|
358
|
+
}
|
|
359
|
+
})();
|
|
360
|
+
const fromAsset = this.chainService.getAssetBySlug(targetPair.from);
|
|
361
|
+
const toAsset = this.chainService.getAssetBySlug(targetPair.to);
|
|
356
362
|
title = '[{{accountName}}] SWAPPED {{fromAsset}}'.replace('{{fromAsset}}', fromAsset.symbol);
|
|
357
|
-
description = '{{fromAmount}} {{fromAsset}}
|
|
363
|
+
description = '{{fromAmount}} {{fromAsset}} swapped for {{toAmount}} {{toAsset}}. Click to view details'.replace('{{fromAmount}}', formatNumber(combineInfo.quote.fromAmount, fromAsset.decimals || 0)).replace('{{fromAsset}}', fromAsset.symbol).replace('{{toAmount}}', formatNumber(combineInfo.quote.toAmount, toAsset.decimals || 0)).replace('{{toAsset}}', toAsset.symbol);
|
|
358
364
|
} else {
|
|
359
365
|
actionType = NotificationActionType.EARNING;
|
|
360
366
|
extrinsicType = ExtrinsicType.JOIN_YIELD_POOL; // Not used
|
|
@@ -2,7 +2,7 @@ import { TransactionError } from '@subwallet/extension-base/background/errors/Tr
|
|
|
2
2
|
import { BalanceService } from '@subwallet/extension-base/services/balance-service';
|
|
3
3
|
import { ChainService } from '@subwallet/extension-base/services/chain-service';
|
|
4
4
|
import FeeService from '@subwallet/extension-base/services/fee-service/service';
|
|
5
|
-
import { BaseStepDetail, CommonOptimalSwapPath, CommonStepFeeInfo,
|
|
5
|
+
import { BaseStepDetail, CommonOptimalSwapPath, CommonStepFeeInfo, OptimalSwapPathParamsV2, SwapProviderId, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types';
|
|
6
6
|
import { SwapBaseInterface } from '../base-handler';
|
|
7
7
|
export declare class AssetHubSwapHandler implements SwapBaseInterface {
|
|
8
8
|
private swapBaseHandler;
|
|
@@ -17,16 +17,9 @@ export declare class AssetHubSwapHandler implements SwapBaseInterface {
|
|
|
17
17
|
get name(): string;
|
|
18
18
|
get slug(): string;
|
|
19
19
|
init(): Promise<void>;
|
|
20
|
-
|
|
21
|
-
getSubmitStep(params: OptimalSwapPathParams): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
22
|
-
getXcmStepV2(params: OptimalSwapPathParamsV2): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
23
|
-
getSwapStepV2(params: OptimalSwapPathParamsV2): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
24
|
-
generateOptimalProcess(params: OptimalSwapPathParams): Promise<CommonOptimalSwapPath>;
|
|
20
|
+
getSubmitStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
25
21
|
generateOptimalProcessV2(params: OptimalSwapPathParamsV2): Promise<CommonOptimalSwapPath>;
|
|
26
|
-
handleXcmStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
|
|
27
22
|
handleSubmitStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
|
|
28
23
|
handleSwapProcess(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
|
|
29
|
-
validateSwapStep(params: ValidateSwapProcessParams, isXcmOk: boolean, stepIndex: number): Promise<TransactionError[]>;
|
|
30
|
-
validateSwapProcess(params: ValidateSwapProcessParams): Promise<TransactionError[]>;
|
|
31
24
|
validateSwapProcessV2(params: ValidateSwapProcessParams): Promise<TransactionError[]>;
|
|
32
25
|
}
|
|
@@ -4,14 +4,10 @@
|
|
|
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 { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { DynamicSwapType } from '@subwallet/extension-base/services/swap-service/interface';
|
|
12
|
-
import { FEE_RATE_MULTIPLIER, getSwapAlternativeAsset } from '@subwallet/extension-base/services/swap-service/utils';
|
|
13
|
-
import { BasicTxErrorType, CommonStepType, SwapErrorType, SwapFeeType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types';
|
|
14
|
-
import { getId } from '@subwallet/extension-base/utils/getId';
|
|
7
|
+
import { _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
|
|
8
|
+
import { DEFAULT_EXCESS_AMOUNT_WEIGHT, getAmountAfterSlippage } from '@subwallet/extension-base/services/swap-service/utils';
|
|
9
|
+
import { BasicTxErrorType, CommonStepType, DynamicSwapType, SwapErrorType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types';
|
|
10
|
+
import { _reformatAddressWithChain } from '@subwallet/extension-base/utils';
|
|
15
11
|
import BigN from 'bignumber.js';
|
|
16
12
|
import { SwapBaseHandler } from "../base-handler.js";
|
|
17
13
|
import { AssetHubRouter } from "./router.js";
|
|
@@ -61,235 +57,70 @@ export class AssetHubSwapHandler {
|
|
|
61
57
|
if (!chainState.active) {
|
|
62
58
|
await this.chainService.enableChain(this.chain);
|
|
63
59
|
}
|
|
64
|
-
const substrateApi = this.chainService.getSubstrateApi(this.chain);
|
|
65
|
-
await substrateApi.api.isReady;
|
|
66
60
|
this.router = new AssetHubRouter(this.chain, this.chainService);
|
|
67
61
|
this.isReady = true;
|
|
68
62
|
}
|
|
69
|
-
async
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (!alternativeAssetSlug) {
|
|
80
|
-
return undefined;
|
|
81
|
-
}
|
|
82
|
-
const alternativeAsset = this.chainService.getAssetBySlug(alternativeAssetSlug);
|
|
83
|
-
const alternativeAssetBalance = await this.balanceService.getTransferableBalance(params.request.address, alternativeAsset.originChain, alternativeAsset.slug);
|
|
84
|
-
const bnAlternativeAssetBalance = new BigN(alternativeAssetBalance.value);
|
|
85
|
-
if (bnAlternativeAssetBalance.lte(0)) {
|
|
86
|
-
return undefined;
|
|
87
|
-
}
|
|
88
|
-
try {
|
|
89
|
-
const alternativeChainInfo = this.chainService.getChainInfoByKey(alternativeAsset.originChain);
|
|
90
|
-
const originalChainInfo = this.chainService.getChainInfoByKey(this.chain);
|
|
91
|
-
const xcmOriginSubstrateApi = await this.chainService.getSubstrateApi(alternativeAsset.originChain).isReady;
|
|
92
|
-
const id = getId();
|
|
93
|
-
const feeInfo = await this.swapBaseHandler.feeService.subscribeChainFee(id, alternativeChainInfo.slug, 'substrate');
|
|
94
|
-
const xcmTransfer = await createXcmExtrinsic({
|
|
95
|
-
originTokenInfo: alternativeAsset,
|
|
96
|
-
destinationTokenInfo: fromAsset,
|
|
97
|
-
// Mock sending value to get payment info
|
|
98
|
-
sendingValue: bnAmount.toString(),
|
|
99
|
-
recipient: params.request.address,
|
|
100
|
-
sender: params.request.address,
|
|
101
|
-
feeInfo: feeInfo,
|
|
102
|
-
substrateApi: xcmOriginSubstrateApi,
|
|
103
|
-
destinationChain: originalChainInfo,
|
|
104
|
-
originChain: alternativeChainInfo
|
|
105
|
-
});
|
|
106
|
-
const _xcmFeeInfo = await xcmTransfer.paymentInfo(params.request.address);
|
|
107
|
-
const xcmFeeInfo = _xcmFeeInfo.toPrimitive();
|
|
108
|
-
const fee = {
|
|
109
|
-
feeComponent: [{
|
|
110
|
-
feeType: SwapFeeType.NETWORK_FEE,
|
|
111
|
-
amount: Math.round(xcmFeeInfo.partialFee * XCM_MIN_AMOUNT_RATIO).toString(),
|
|
112
|
-
tokenSlug: _getChainNativeTokenSlug(alternativeChainInfo)
|
|
113
|
-
}],
|
|
114
|
-
defaultFeeToken: _getChainNativeTokenSlug(alternativeChainInfo),
|
|
115
|
-
feeOptions: [_getChainNativeTokenSlug(alternativeChainInfo)]
|
|
116
|
-
};
|
|
117
|
-
let bnTransferAmount = bnAmount.minus(bnFromAssetBalance);
|
|
118
|
-
if (_isNativeToken(alternativeAsset)) {
|
|
119
|
-
const bnXcmFee = new BigN(fee.feeComponent[0].amount); // xcm fee is paid in native token but swap token is not always native token
|
|
120
|
-
|
|
121
|
-
bnTransferAmount = bnTransferAmount.plus(bnXcmFee);
|
|
122
|
-
}
|
|
123
|
-
const step = {
|
|
124
|
-
metadata: {
|
|
125
|
-
sendingValue: bnTransferAmount.toString(),
|
|
126
|
-
originTokenInfo: alternativeAsset,
|
|
127
|
-
destinationTokenInfo: fromAsset
|
|
128
|
-
},
|
|
129
|
-
name: `Transfer ${alternativeAsset.symbol} from ${alternativeChainInfo.name}`,
|
|
130
|
-
type: CommonStepType.XCM
|
|
131
|
-
};
|
|
132
|
-
return [step, fee];
|
|
133
|
-
} catch (e) {
|
|
134
|
-
console.error('Error creating xcm step', e);
|
|
135
|
-
return undefined;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
async getSubmitStep(params) {
|
|
139
|
-
if (params.selectedQuote) {
|
|
140
|
-
const submitStep = {
|
|
141
|
-
name: 'Swap',
|
|
142
|
-
type: SwapStepType.SWAP
|
|
143
|
-
};
|
|
144
|
-
return Promise.resolve([submitStep, params.selectedQuote.feeInfo]);
|
|
145
|
-
}
|
|
146
|
-
return Promise.resolve(undefined);
|
|
147
|
-
}
|
|
148
|
-
async getXcmStepV2(params) {
|
|
149
|
-
var _params$path$find;
|
|
150
|
-
// todo: improve this function for Round 2
|
|
151
|
-
|
|
152
|
-
const xcmPairInfo = (_params$path$find = params.path.find((step, i) => i === 0 && step.action === DynamicSwapType.BRIDGE)) === null || _params$path$find === void 0 ? void 0 : _params$path$find.pair;
|
|
153
|
-
if (!xcmPairInfo) {
|
|
154
|
-
return undefined;
|
|
155
|
-
}
|
|
156
|
-
const fromTokenInfo = this.chainService.getAssetBySlug(xcmPairInfo.from);
|
|
157
|
-
const toTokenInfo = this.chainService.getAssetBySlug(xcmPairInfo.to);
|
|
158
|
-
const fromChainInfo = this.chainService.getChainInfoByKey(fromTokenInfo.originChain);
|
|
159
|
-
const toChainInfo = this.chainService.getChainInfoByKey(toTokenInfo.originChain);
|
|
160
|
-
const substrateApi = await this.chainService.getSubstrateApi(fromTokenInfo.originChain).isReady;
|
|
161
|
-
if (!fromChainInfo || !toChainInfo || !fromChainInfo || !toChainInfo) {
|
|
162
|
-
throw Error('Token and chain not found');
|
|
163
|
-
}
|
|
164
|
-
try {
|
|
165
|
-
const id = getId();
|
|
166
|
-
const [feeInfo, toTokenBalance] = await Promise.all([this.swapBaseHandler.feeService.subscribeChainFee(id, fromTokenInfo.originChain, 'substrate'), this.balanceService.getTotalBalance(params.request.address, toTokenInfo.originChain, toTokenInfo.slug, ExtrinsicType.TRANSFER_BALANCE)]);
|
|
167
|
-
const xcmTransfer = await createXcmExtrinsic({
|
|
168
|
-
originTokenInfo: fromTokenInfo,
|
|
169
|
-
destinationTokenInfo: toTokenInfo,
|
|
170
|
-
// Mock sending value to get payment info
|
|
171
|
-
sendingValue: params.request.fromAmount,
|
|
172
|
-
recipient: params.request.address,
|
|
173
|
-
substrateApi: substrateApi,
|
|
174
|
-
sender: params.request.address,
|
|
175
|
-
originChain: fromChainInfo,
|
|
176
|
-
destinationChain: toChainInfo,
|
|
177
|
-
feeInfo
|
|
178
|
-
});
|
|
179
|
-
const _xcmFeeInfo = await xcmTransfer.paymentInfo(params.request.address);
|
|
180
|
-
const xcmFeeInfo = _xcmFeeInfo.toPrimitive();
|
|
181
|
-
const fee = {
|
|
182
|
-
feeComponent: [{
|
|
183
|
-
feeType: SwapFeeType.NETWORK_FEE,
|
|
184
|
-
amount: Math.ceil(xcmFeeInfo.partialFee * FEE_RATE_MULTIPLIER.high).toString(),
|
|
185
|
-
tokenSlug: _getChainNativeTokenSlug(fromChainInfo)
|
|
186
|
-
}],
|
|
187
|
-
defaultFeeToken: _getChainNativeTokenSlug(fromChainInfo),
|
|
188
|
-
feeOptions: [_getChainNativeTokenSlug(fromChainInfo)]
|
|
189
|
-
};
|
|
190
|
-
let bnTransferAmount = new BigN(params.request.fromAmount);
|
|
191
|
-
if (_isNativeToken(fromTokenInfo)) {
|
|
192
|
-
// xcm fee is paid in native token but swap token is not always native token
|
|
193
|
-
// add amount of fee into sending value to ensure has enough token to swap
|
|
194
|
-
const bnXcmFee = new BigN(fee.feeComponent[0].amount);
|
|
195
|
-
bnTransferAmount = bnTransferAmount.plus(bnXcmFee);
|
|
196
|
-
} else {
|
|
197
|
-
bnTransferAmount = bnTransferAmount.plus(BigN(_getTokenMinAmount(toTokenInfo)).multipliedBy(FEE_RATE_MULTIPLIER.medium));
|
|
198
|
-
}
|
|
199
|
-
if (BigN(toTokenBalance.value).lte(0)) {
|
|
200
|
-
bnTransferAmount = bnTransferAmount.plus(_getTokenMinAmount(toTokenInfo));
|
|
201
|
-
}
|
|
202
|
-
const step = {
|
|
203
|
-
metadata: {
|
|
204
|
-
sendingValue: bnTransferAmount.toString(),
|
|
205
|
-
originTokenInfo: fromTokenInfo,
|
|
206
|
-
destinationTokenInfo: toTokenInfo
|
|
207
|
-
},
|
|
208
|
-
name: `Transfer ${fromTokenInfo.symbol} from ${fromChainInfo.name}`,
|
|
209
|
-
type: CommonStepType.XCM
|
|
210
|
-
};
|
|
211
|
-
return [step, fee];
|
|
212
|
-
} catch (e) {
|
|
213
|
-
console.error('Error creating xcm step', e);
|
|
214
|
-
return undefined;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
async getSwapStepV2(params) {
|
|
218
|
-
var _params$path$find2;
|
|
219
|
-
const swapPairInfo = (_params$path$find2 = params.path.find(step => step.action === DynamicSwapType.SWAP)) === null || _params$path$find2 === void 0 ? void 0 : _params$path$find2.pair;
|
|
220
|
-
if (!swapPairInfo) {
|
|
63
|
+
async getSubmitStep(params, stepIndex) {
|
|
64
|
+
const {
|
|
65
|
+
path,
|
|
66
|
+
request: {
|
|
67
|
+
fromAmount
|
|
68
|
+
},
|
|
69
|
+
selectedQuote
|
|
70
|
+
} = params;
|
|
71
|
+
const stepData = path[stepIndex];
|
|
72
|
+
if (stepData.action !== DynamicSwapType.SWAP) {
|
|
221
73
|
return Promise.resolve(undefined);
|
|
222
74
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
type: SwapStepType.SWAP,
|
|
227
|
-
metadata: {
|
|
228
|
-
sendingValue: params.request.fromAmount.toString(),
|
|
229
|
-
originTokenInfo: this.chainService.getAssetBySlug(swapPairInfo.from),
|
|
230
|
-
destinationTokenInfo: this.chainService.getAssetBySlug(swapPairInfo.to)
|
|
231
|
-
}
|
|
232
|
-
};
|
|
233
|
-
return Promise.resolve([submitStep, params.selectedQuote.feeInfo]);
|
|
75
|
+
const swapPairInfo = stepData.pair;
|
|
76
|
+
if (!swapPairInfo || !selectedQuote) {
|
|
77
|
+
return Promise.resolve(undefined);
|
|
234
78
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
79
|
+
const originTokenInfo = this.chainService.getAssetBySlug(swapPairInfo.from);
|
|
80
|
+
const destinationTokenInfo = this.chainService.getAssetBySlug(swapPairInfo.to);
|
|
81
|
+
const originChain = this.chainService.getChainInfoByKey(originTokenInfo.originChain);
|
|
82
|
+
const destinationChain = this.chainService.getChainInfoByKey(destinationTokenInfo.originChain);
|
|
83
|
+
const actionList = JSON.stringify(path.map(step => step.action));
|
|
84
|
+
const xcmSwapXcm = actionList === JSON.stringify([DynamicSwapType.BRIDGE, DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
|
|
85
|
+
const swapXcm = actionList === JSON.stringify([DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
|
|
86
|
+
const needModifyData = swapXcm || xcmSwapXcm;
|
|
87
|
+
let bnSendingValue = BigN(fromAmount);
|
|
88
|
+
let bnExpectedReceive = BigN(selectedQuote.toAmount);
|
|
89
|
+
const sender = _reformatAddressWithChain(params.request.address, originChain);
|
|
90
|
+
let receiver = _reformatAddressWithChain(params.request.recipient || params.request.address, destinationChain);
|
|
91
|
+
if (needModifyData) {
|
|
92
|
+
bnSendingValue = bnSendingValue.multipliedBy(DEFAULT_EXCESS_AMOUNT_WEIGHT);
|
|
93
|
+
bnExpectedReceive = bnExpectedReceive.multipliedBy(DEFAULT_EXCESS_AMOUNT_WEIGHT);
|
|
94
|
+
receiver = _reformatAddressWithChain(params.request.address, destinationChain);
|
|
95
|
+
}
|
|
96
|
+
const submitStep = {
|
|
97
|
+
name: 'Swap',
|
|
98
|
+
type: SwapStepType.SWAP,
|
|
99
|
+
// @ts-ignore
|
|
100
|
+
metadata: {
|
|
101
|
+
sendingValue: bnSendingValue.toFixed(0, 1),
|
|
102
|
+
expectedReceive: bnExpectedReceive.toFixed(0, 1),
|
|
103
|
+
originTokenInfo,
|
|
104
|
+
destinationTokenInfo,
|
|
105
|
+
sender,
|
|
106
|
+
receiver,
|
|
107
|
+
version: 2
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
return Promise.resolve([submitStep, selectedQuote.feeInfo]);
|
|
239
111
|
}
|
|
240
112
|
generateOptimalProcessV2(params) {
|
|
241
113
|
const stepFuncList = params.path.map(step => {
|
|
242
|
-
if (step.action === DynamicSwapType.BRIDGE) {
|
|
243
|
-
return this.getXcmStepV2.bind(this);
|
|
244
|
-
}
|
|
245
114
|
if (step.action === DynamicSwapType.SWAP) {
|
|
246
|
-
return this.
|
|
115
|
+
return this.getSubmitStep.bind(this);
|
|
116
|
+
}
|
|
117
|
+
if (step.action === DynamicSwapType.BRIDGE) {
|
|
118
|
+
return this.swapBaseHandler.getBridgeStep.bind(this.swapBaseHandler);
|
|
247
119
|
}
|
|
248
120
|
throw new Error(`Error generating optimal process: Action ${step.action} is not supported`);
|
|
249
121
|
});
|
|
250
122
|
return this.swapBaseHandler.generateOptimalProcessV2(params, stepFuncList);
|
|
251
123
|
}
|
|
252
|
-
async handleXcmStep(params) {
|
|
253
|
-
const briefXcmStep = params.process.steps[params.currentStep].metadata;
|
|
254
|
-
if (!briefXcmStep || !briefXcmStep.originTokenInfo || !briefXcmStep.destinationTokenInfo || !briefXcmStep.sendingValue) {
|
|
255
|
-
throw new Error('XCM metadata error');
|
|
256
|
-
}
|
|
257
|
-
const originAsset = briefXcmStep.originTokenInfo;
|
|
258
|
-
const destinationAsset = briefXcmStep.destinationTokenInfo;
|
|
259
|
-
const originChain = this.chainService.getChainInfoByKey(originAsset.originChain);
|
|
260
|
-
const destinationChain = this.chainService.getChainInfoByKey(destinationAsset.originChain);
|
|
261
|
-
const substrateApi = this.chainService.getSubstrateApi(originAsset.originChain);
|
|
262
|
-
const chainApi = await substrateApi.isReady;
|
|
263
|
-
const feeInfo = await this.swapBaseHandler.feeService.subscribeChainFee(getId(), originAsset.originChain, 'substrate');
|
|
264
|
-
const xcmTransfer = await createXcmExtrinsic({
|
|
265
|
-
originTokenInfo: originAsset,
|
|
266
|
-
destinationTokenInfo: destinationAsset,
|
|
267
|
-
sendingValue: briefXcmStep.sendingValue,
|
|
268
|
-
recipient: params.address,
|
|
269
|
-
substrateApi: chainApi,
|
|
270
|
-
sender: params.address,
|
|
271
|
-
destinationChain,
|
|
272
|
-
originChain,
|
|
273
|
-
feeInfo
|
|
274
|
-
});
|
|
275
|
-
const xcmData = {
|
|
276
|
-
originNetworkKey: originAsset.originChain,
|
|
277
|
-
destinationNetworkKey: destinationAsset.originChain,
|
|
278
|
-
from: params.address,
|
|
279
|
-
to: params.address,
|
|
280
|
-
value: briefXcmStep.sendingValue,
|
|
281
|
-
tokenSlug: originAsset.slug,
|
|
282
|
-
showExtraWarning: true
|
|
283
|
-
};
|
|
284
|
-
return {
|
|
285
|
-
txChain: originAsset.originChain,
|
|
286
|
-
extrinsic: xcmTransfer,
|
|
287
|
-
transferNativeAmount: _isNativeToken(originAsset) ? briefXcmStep.sendingValue : '0',
|
|
288
|
-
extrinsicType: ExtrinsicType.TRANSFER_XCM,
|
|
289
|
-
chainType: ChainType.SUBSTRATE,
|
|
290
|
-
txData: xcmData
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
124
|
async handleSubmitStep(params) {
|
|
294
125
|
var _this$router;
|
|
295
126
|
const metadata = params.process.steps[params.currentStep].metadata;
|
|
@@ -305,17 +136,11 @@ export class AssetHubSwapHandler {
|
|
|
305
136
|
process: params.process
|
|
306
137
|
};
|
|
307
138
|
const paths = params.quote.route.path.map(slug => this.chainService.getAssetBySlug(slug));
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
toAmount
|
|
311
|
-
} = params.quote;
|
|
312
|
-
|
|
313
|
-
// todo: move to gen process
|
|
314
|
-
const minReceive = new BigN(1 - params.slippage).times(toAmount).integerValue(BigN.ROUND_DOWN);
|
|
315
|
-
if (!params.address || !paths || !fromAmount || !minReceive) {
|
|
139
|
+
const minReceive = BigN(getAmountAfterSlippage(metadata.expectedReceive, params.slippage));
|
|
140
|
+
if (!params.address || !paths || !minReceive) {
|
|
316
141
|
throw new SwapError(SwapErrorType.UNKNOWN);
|
|
317
142
|
}
|
|
318
|
-
const extrinsic = await ((_this$router = this.router) === null || _this$router === void 0 ? void 0 : _this$router.buildSwapExtrinsic(paths, params.address,
|
|
143
|
+
const extrinsic = await ((_this$router = this.router) === null || _this$router === void 0 ? void 0 : _this$router.buildSwapExtrinsic(paths, params.address, metadata.sendingValue, minReceive.toString()));
|
|
319
144
|
return {
|
|
320
145
|
txChain: fromAsset.originChain,
|
|
321
146
|
txData,
|
|
@@ -334,90 +159,13 @@ export class AssetHubSwapHandler {
|
|
|
334
159
|
const type = process.steps[currentStep].type;
|
|
335
160
|
switch (type) {
|
|
336
161
|
case CommonStepType.XCM:
|
|
337
|
-
return this.
|
|
162
|
+
return this.swapBaseHandler.handleBridgeStep(params);
|
|
338
163
|
case SwapStepType.SWAP:
|
|
339
164
|
return this.handleSubmitStep(params);
|
|
340
165
|
default:
|
|
341
166
|
return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
|
|
342
167
|
}
|
|
343
168
|
}
|
|
344
|
-
async validateSwapStep(params, isXcmOk, stepIndex) {
|
|
345
|
-
// check swap quote timestamp
|
|
346
|
-
// check balance to pay transaction fee
|
|
347
|
-
// check balance against spending amount
|
|
348
|
-
if (!params.selectedQuote) {
|
|
349
|
-
return Promise.resolve([new TransactionError(BasicTxErrorType.INTERNAL_ERROR)]);
|
|
350
|
-
}
|
|
351
|
-
const selectedQuote = params.selectedQuote;
|
|
352
|
-
const currentTimestamp = +Date.now();
|
|
353
|
-
if (selectedQuote.aliveUntil <= currentTimestamp) {
|
|
354
|
-
return Promise.resolve([new TransactionError(SwapErrorType.QUOTE_TIMEOUT)]);
|
|
355
|
-
}
|
|
356
|
-
const stepFee = params.process.totalFee[stepIndex].feeComponent;
|
|
357
|
-
const networkFee = stepFee.find(fee => fee.feeType === SwapFeeType.NETWORK_FEE);
|
|
358
|
-
if (!networkFee) {
|
|
359
|
-
return Promise.resolve([new TransactionError(BasicTxErrorType.INTERNAL_ERROR)]);
|
|
360
|
-
}
|
|
361
|
-
const fromAsset = this.chainService.getAssetBySlug(params.selectedQuote.pair.from);
|
|
362
|
-
const feeTokenInfo = this.chainService.getAssetBySlug(networkFee.tokenSlug);
|
|
363
|
-
const feeTokenChain = this.chainService.getChainInfoByKey(feeTokenInfo.originChain);
|
|
364
|
-
const {
|
|
365
|
-
fromAmount,
|
|
366
|
-
minSwap
|
|
367
|
-
} = params.selectedQuote;
|
|
368
|
-
const [feeTokenBalance, fromAssetBalance] = await Promise.all([this.balanceService.getTransferableBalance(params.address, feeTokenInfo.originChain, feeTokenInfo.slug), this.balanceService.getTransferableBalance(params.address, fromAsset.originChain, fromAsset.slug)]);
|
|
369
|
-
const balanceError = _validateBalanceToSwapOnAssetHub(fromAsset, feeTokenInfo, feeTokenChain, networkFee.amount, fromAssetBalance.value, feeTokenBalance.value, fromAmount, isXcmOk, minSwap);
|
|
370
|
-
if (balanceError) {
|
|
371
|
-
return Promise.resolve([balanceError]);
|
|
372
|
-
}
|
|
373
|
-
if (!params.recipient) {
|
|
374
|
-
return Promise.resolve([]);
|
|
375
|
-
}
|
|
376
|
-
const toAsset = this.chainService.getAssetBySlug(params.selectedQuote.pair.to);
|
|
377
|
-
const toAssetChain = this.chainService.getChainInfoByKey(toAsset.originChain);
|
|
378
|
-
const recipientError = _validateSwapRecipient(toAssetChain, params.recipient);
|
|
379
|
-
if (recipientError) {
|
|
380
|
-
return Promise.resolve([recipientError]);
|
|
381
|
-
}
|
|
382
|
-
return Promise.resolve([]);
|
|
383
|
-
}
|
|
384
|
-
async validateSwapProcess(params) {
|
|
385
|
-
const amount = params.selectedQuote.fromAmount;
|
|
386
|
-
const bnAmount = new BigN(amount);
|
|
387
|
-
if (bnAmount.lte(0)) {
|
|
388
|
-
return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')];
|
|
389
|
-
}
|
|
390
|
-
const swapStep = params.process.steps.find(item => item.type === SwapStepType.SWAP);
|
|
391
|
-
if (!swapStep) {
|
|
392
|
-
return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR, 'Swap step not found')];
|
|
393
|
-
}
|
|
394
|
-
let isXcmOk = false;
|
|
395
|
-
const currentStep = params.currentStep;
|
|
396
|
-
for (const [index, step] of params.process.steps.entries()) {
|
|
397
|
-
if (currentStep > index) {
|
|
398
|
-
continue;
|
|
399
|
-
}
|
|
400
|
-
const getErrors = async () => {
|
|
401
|
-
switch (step.type) {
|
|
402
|
-
case CommonStepType.DEFAULT:
|
|
403
|
-
return Promise.resolve([]);
|
|
404
|
-
case CommonStepType.XCM:
|
|
405
|
-
return this.swapBaseHandler.validateXcmStepV2(params, index);
|
|
406
|
-
case SwapStepType.SWAP:
|
|
407
|
-
return this.validateSwapStep(params, isXcmOk, index);
|
|
408
|
-
default:
|
|
409
|
-
return Promise.reject(new TransactionError(BasicTxErrorType.UNSUPPORTED));
|
|
410
|
-
}
|
|
411
|
-
};
|
|
412
|
-
const errors = await getErrors();
|
|
413
|
-
if (errors.length) {
|
|
414
|
-
return errors;
|
|
415
|
-
} else if (step.type === CommonStepType.XCM) {
|
|
416
|
-
isXcmOk = true;
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
return [];
|
|
420
|
-
}
|
|
421
169
|
async validateSwapProcessV2(params) {
|
|
422
170
|
// todo: recheck address and recipient format in params
|
|
423
171
|
const {
|
|
@@ -430,24 +178,23 @@ export class AssetHubSwapHandler {
|
|
|
430
178
|
if (BigN(selectedQuote.fromAmount).lte(0)) {
|
|
431
179
|
return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')];
|
|
432
180
|
}
|
|
433
|
-
const actionList = process.
|
|
434
|
-
const
|
|
435
|
-
const
|
|
436
|
-
const
|
|
437
|
-
const
|
|
438
|
-
const xcmSwapXcm = firstStep === CommonStepType.DEFAULT && secondStep === CommonStepType.XCM && thirdStep === SwapStepType.SWAP && fourthStep === CommonStepType.XCM && !fifthStep;
|
|
181
|
+
const actionList = JSON.stringify(process.path.map(step => step.action));
|
|
182
|
+
const swap = actionList === JSON.stringify([DynamicSwapType.SWAP]);
|
|
183
|
+
const swapXcm = actionList === JSON.stringify([DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
|
|
184
|
+
const xcmSwap = actionList === JSON.stringify([DynamicSwapType.BRIDGE, DynamicSwapType.SWAP]);
|
|
185
|
+
const xcmSwapXcm = actionList === JSON.stringify([DynamicSwapType.BRIDGE, DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
|
|
439
186
|
if (swap) {
|
|
440
187
|
return this.swapBaseHandler.validateSwapOnlyProcess(params, 1); // todo: create interface for input request
|
|
441
188
|
}
|
|
442
189
|
|
|
443
190
|
if (swapXcm) {
|
|
444
|
-
return
|
|
191
|
+
return this.swapBaseHandler.validateSwapXcmProcess(params, 1, 2);
|
|
445
192
|
}
|
|
446
193
|
if (xcmSwap) {
|
|
447
194
|
return this.swapBaseHandler.validateXcmSwapProcess(params, 2, 1);
|
|
448
195
|
}
|
|
449
196
|
if (xcmSwapXcm) {
|
|
450
|
-
return
|
|
197
|
+
return this.swapBaseHandler.validateXcmSwapXcmProcess(params, 2, 1, 3);
|
|
451
198
|
}
|
|
452
199
|
return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
|
|
453
200
|
}
|
|
@@ -4,13 +4,11 @@ import { ChainService } from '@subwallet/extension-base/services/chain-service';
|
|
|
4
4
|
import FeeService from '@subwallet/extension-base/services/fee-service/service';
|
|
5
5
|
import { GenSwapStepFuncV2, OptimalSwapPathParamsV2 } from '@subwallet/extension-base/types';
|
|
6
6
|
import { BaseStepDetail, CommonOptimalSwapPath, CommonStepFeeInfo } from '@subwallet/extension-base/types/service-base';
|
|
7
|
-
import {
|
|
7
|
+
import { SwapProvider, SwapProviderId, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types/swap';
|
|
8
8
|
export interface SwapBaseInterface {
|
|
9
9
|
providerSlug: SwapProviderId;
|
|
10
|
-
generateOptimalProcess: (params: OptimalSwapPathParams) => Promise<CommonOptimalSwapPath>;
|
|
11
10
|
generateOptimalProcessV2: (params: OptimalSwapPathParamsV2) => Promise<CommonOptimalSwapPath>;
|
|
12
|
-
getSubmitStep: (params:
|
|
13
|
-
validateSwapProcess: (params: ValidateSwapProcessParams) => Promise<TransactionError[]>;
|
|
11
|
+
getSubmitStep: (params: OptimalSwapPathParamsV2, stepIndex: number) => Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
14
12
|
validateSwapProcessV2: (params: ValidateSwapProcessParams) => Promise<TransactionError[]>;
|
|
15
13
|
handleSwapProcess: (params: SwapSubmitParams) => Promise<SwapSubmitStepData>;
|
|
16
14
|
handleSubmitStep: (params: SwapSubmitParams) => Promise<SwapSubmitStepData>;
|
|
@@ -31,17 +29,16 @@ export declare class SwapBaseHandler {
|
|
|
31
29
|
balanceService: BalanceService;
|
|
32
30
|
feeService: FeeService;
|
|
33
31
|
constructor({ balanceService, chainService, feeService, providerName, providerSlug }: SwapBaseHandlerInitParams);
|
|
34
|
-
generateOptimalProcess(params: OptimalSwapPathParams, genStepFuncList: GenSwapStepFunc[]): Promise<CommonOptimalSwapPath>;
|
|
35
32
|
generateOptimalProcessV2(params: OptimalSwapPathParamsV2, genStepFuncList: GenSwapStepFuncV2[]): Promise<CommonOptimalSwapPath>;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
validateTokenApproveStep(params: ValidateSwapProcessParams, stepIndex: number): Promise<TransactionError[]>;
|
|
33
|
+
getBridgeStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
34
|
+
handleBridgeStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
|
|
39
35
|
validateSetFeeTokenStep(params: ValidateSwapProcessParams, stepIndex: number): Promise<TransactionError[]>;
|
|
40
|
-
validateSwapStep(params: ValidateSwapProcessParams, isXcmOk: boolean, stepIndex: number): Promise<TransactionError[]>;
|
|
41
36
|
private validateBridgeStep;
|
|
42
37
|
private validateSwapStepV2;
|
|
43
38
|
validateSwapOnlyProcess(params: ValidateSwapProcessParams, swapIndex: number): Promise<TransactionError[]>;
|
|
44
39
|
validateXcmSwapProcess(params: ValidateSwapProcessParams, swapIndex: number, xcmIndex: number): Promise<TransactionError[]>;
|
|
40
|
+
validateSwapXcmProcess(params: ValidateSwapProcessParams, swapIndex: number, xcmIndex: number): Promise<TransactionError[]>;
|
|
41
|
+
validateXcmSwapXcmProcess(params: ValidateSwapProcessParams, swapIndex: number, xcmIndex: number, transitIndex: number): Promise<TransactionError[]>;
|
|
45
42
|
get name(): string;
|
|
46
43
|
get slug(): string;
|
|
47
44
|
get providerInfo(): SwapProvider;
|