@subwallet/extension-base 1.3.26-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.
- package/background/KoniTypes.d.ts +4 -3
- package/background/warnings/TransactionWarning.d.ts +2 -0
- package/background/warnings/TransactionWarning.js +16 -1
- package/cjs/background/warnings/TransactionWarning.js +15 -0
- package/cjs/core/logic-validation/index.js +32 -1
- package/cjs/core/utils.js +25 -3
- package/cjs/koni/background/handlers/Extension.js +86 -94
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/swap-service/handler/asset-hub/handler.js +182 -40
- package/cjs/services/swap-service/handler/asset-hub/utils.js +3 -0
- package/cjs/services/swap-service/handler/base-handler.js +326 -12
- package/cjs/services/swap-service/handler/chainflip-handler.js +80 -16
- package/cjs/services/swap-service/handler/hydradx-handler.js +174 -30
- package/cjs/services/swap-service/handler/simpleswap-handler.js +50 -1
- package/cjs/services/swap-service/handler/uniswap-handler.js +47 -1
- package/cjs/services/swap-service/index.js +191 -27
- package/cjs/services/swap-service/interface.js +14 -0
- package/cjs/services/swap-service/utils.js +81 -5
- package/core/logic-validation/index.d.ts +4 -0
- package/core/logic-validation/index.js +22 -1
- package/core/utils.d.ts +3 -0
- package/core/utils.js +22 -2
- package/koni/background/handlers/Extension.d.ts +2 -2
- package/koni/background/handlers/Extension.js +20 -28
- package/package.json +12 -7
- package/packageInfo.js +1 -1
- package/services/balance-service/helpers/process.d.ts +3 -3
- package/services/balance-service/index.d.ts +2 -3
- package/services/swap-service/handler/asset-hub/handler.d.ts +6 -3
- package/services/swap-service/handler/asset-hub/handler.js +170 -28
- package/services/swap-service/handler/asset-hub/utils.js +3 -0
- package/services/swap-service/handler/base-handler.d.ts +12 -3
- package/services/swap-service/handler/base-handler.js +329 -15
- package/services/swap-service/handler/chainflip-handler.d.ts +4 -3
- package/services/swap-service/handler/chainflip-handler.js +74 -10
- package/services/swap-service/handler/hydradx-handler.d.ts +8 -3
- package/services/swap-service/handler/hydradx-handler.js +176 -32
- package/services/swap-service/handler/simpleswap-handler.d.ts +4 -2
- package/services/swap-service/handler/simpleswap-handler.js +50 -1
- package/services/swap-service/handler/uniswap-handler.d.ts +4 -2
- package/services/swap-service/handler/uniswap-handler.js +47 -1
- package/services/swap-service/index.d.ts +15 -5
- package/services/swap-service/index.js +182 -18
- package/services/swap-service/interface.d.ts +9 -0
- package/services/swap-service/interface.js +8 -0
- package/services/swap-service/utils.d.ts +9 -1
- package/services/swap-service/utils.js +74 -4
- package/types/service-base.d.ts +6 -2
- package/types/swap/index.d.ts +34 -6
- package/types/transaction/process.d.ts +0 -6
|
@@ -11,6 +11,7 @@ import { CampaignDataType, ChainType, ExternalRequestPromiseStatus, ExtrinsicTyp
|
|
|
11
11
|
import { _SUPPORT_TOKEN_PAY_FEE_GROUP, ALL_ACCOUNT_KEY, LATEST_SESSION } from '@subwallet/extension-base/constants';
|
|
12
12
|
import { additionalValidateTransferForRecipient, additionalValidateXcmTransfer, validateTransferRequest, validateXcmTransferRequest } from '@subwallet/extension-base/core/logic-validation/transfer';
|
|
13
13
|
import { _isSnowBridgeXcm } from '@subwallet/extension-base/core/substrate/xcm-parser';
|
|
14
|
+
import { _isSufficientToken } from '@subwallet/extension-base/core/utils';
|
|
14
15
|
import { ALLOWED_PATH } from '@subwallet/extension-base/defaults';
|
|
15
16
|
import { getERC20SpendingApprovalTx } from '@subwallet/extension-base/koni/api/contract-handler/evm/web3';
|
|
16
17
|
import { _ERC721_ABI, isAvailBridgeGatewayContract, isSnowBridgeGatewayContract } from '@subwallet/extension-base/koni/api/contract-handler/utils';
|
|
@@ -32,9 +33,9 @@ import { createAvailBridgeExtrinsicFromAvail, createAvailBridgeTxFromEth, create
|
|
|
32
33
|
import { getClaimTxOnAvail, getClaimTxOnEthereum, isAvailChainBridge } from '@subwallet/extension-base/services/balance-service/transfer/xcm/availBridge';
|
|
33
34
|
import { _isPolygonChainBridge, getClaimPolygonBridge, isClaimedPolygonBridge } from '@subwallet/extension-base/services/balance-service/transfer/xcm/polygonBridge';
|
|
34
35
|
import { _isPosChainBridge, getClaimPosBridge } from '@subwallet/extension-base/services/balance-service/transfer/xcm/posBridge';
|
|
35
|
-
import { _DEFAULT_MANTA_ZK_CHAIN, _MANTA_ZK_CHAIN_GROUP, _ZK_ASSET_PREFIX
|
|
36
|
+
import { _DEFAULT_MANTA_ZK_CHAIN, _MANTA_ZK_CHAIN_GROUP, _ZK_ASSET_PREFIX } from '@subwallet/extension-base/services/chain-service/constants';
|
|
36
37
|
import { _ChainConnectionStatus } from '@subwallet/extension-base/services/chain-service/types';
|
|
37
|
-
import { _getAssetDecimals, _getAssetSymbol, _getChainNativeTokenBasicInfo, _getContractAddressOfToken, _getEvmChainId,
|
|
38
|
+
import { _getAssetDecimals, _getAssetSymbol, _getChainNativeTokenBasicInfo, _getContractAddressOfToken, _getEvmChainId, _isAssetSmartContractNft, _isChainEvmCompatible, _isChainSubstrateCompatible, _isCustomAsset, _isLocalToken, _isMantaZkAsset, _isNativeToken, _isNativeTokenBySlug, _isPureEvmChain, _isTokenEvmSmartContract, _isTokenTransferredByCardano, _isTokenTransferredByEvm, _isTokenTransferredByTon } from '@subwallet/extension-base/services/chain-service/utils';
|
|
38
39
|
import { calculateToAmountByReservePool } from '@subwallet/extension-base/services/fee-service/utils';
|
|
39
40
|
import { batchExtrinsicSetFeeHydration, getAssetHubTokensCanPayFee, getHydrationTokensCanPayFee } from '@subwallet/extension-base/services/fee-service/utils/tokenPayFee';
|
|
40
41
|
import { EXTENSION_REQUEST_URL } from '@subwallet/extension-base/services/request-service/constants';
|
|
@@ -1299,7 +1300,7 @@ export default class KoniExtension {
|
|
|
1299
1300
|
const receiverSendingTokenKeepAliveBalance = BigInt(_receiverSendingTokenKeepAliveBalance);
|
|
1300
1301
|
const amount = BigInt(transferAmount.value);
|
|
1301
1302
|
const substrateApi = this.#koniState.getSubstrateApi(chain);
|
|
1302
|
-
const isSendingTokenSufficient = await
|
|
1303
|
+
const isSendingTokenSufficient = await _isSufficientToken(transferTokenInfo, substrateApi);
|
|
1303
1304
|
const [warnings, errors] = additionalValidateTransferForRecipient(transferTokenInfo, nativeTokenInfo, extrinsicType, receiverSendingTokenKeepAliveBalance, amount, senderSendingTokenTransferable, receiverSystemAccountInfo, isSendingTokenSufficient);
|
|
1304
1305
|
warnings.length && inputTransaction.warnings.push(...warnings);
|
|
1305
1306
|
errors.length && inputTransaction.errors.push(...errors);
|
|
@@ -1663,25 +1664,6 @@ export default class KoniExtension {
|
|
|
1663
1664
|
};
|
|
1664
1665
|
}
|
|
1665
1666
|
}
|
|
1666
|
-
async isSufficientToken(tokenInfo, substrateApi) {
|
|
1667
|
-
let metadata;
|
|
1668
|
-
if (SUFFICIENT_CHAIN.includes(tokenInfo.originChain) && tokenInfo.assetType !== _AssetType.NATIVE) {
|
|
1669
|
-
const assetId = _isBridgedToken(tokenInfo) ? _getXcmAssetMultilocation(tokenInfo) : _getTokenOnChainAssetId(tokenInfo);
|
|
1670
|
-
const queryParams = {
|
|
1671
|
-
section: 'query',
|
|
1672
|
-
module: 'foreignAssets',
|
|
1673
|
-
method: 'asset',
|
|
1674
|
-
args: [assetId]
|
|
1675
|
-
};
|
|
1676
|
-
if (!_isBridgedToken(tokenInfo)) {
|
|
1677
|
-
queryParams.module = 'assets';
|
|
1678
|
-
}
|
|
1679
|
-
metadata = await substrateApi.makeRpcQuery(queryParams);
|
|
1680
|
-
} else {
|
|
1681
|
-
return false;
|
|
1682
|
-
}
|
|
1683
|
-
return metadata.isSufficient;
|
|
1684
|
-
}
|
|
1685
1667
|
async deleteCustomAsset(assetSlug) {
|
|
1686
1668
|
const assetInfo = this.#koniState.getAssetBySlug(assetSlug);
|
|
1687
1669
|
if (assetInfo && _isCustomAsset(assetSlug)) {
|
|
@@ -3603,14 +3585,20 @@ export default class KoniExtension {
|
|
|
3603
3585
|
ready = true;
|
|
3604
3586
|
return this.#koniState.swapService.getSwapPairs();
|
|
3605
3587
|
}
|
|
3606
|
-
async
|
|
3607
|
-
return this.#koniState.swapService.
|
|
3588
|
+
async getOptimalSwapProcessOnSelectQuote(request) {
|
|
3589
|
+
return this.#koniState.swapService.generateOptimalProcessWithoutPath(request);
|
|
3608
3590
|
}
|
|
3609
3591
|
async handleSwapRequest(request) {
|
|
3610
3592
|
return this.#koniState.swapService.handleSwapRequest(request);
|
|
3611
3593
|
}
|
|
3594
|
+
async handleSwapRequestV2(request) {
|
|
3595
|
+
return this.#koniState.swapService.handleSwapRequestV2(request);
|
|
3596
|
+
}
|
|
3612
3597
|
async getLatestSwapQuote(swapRequest) {
|
|
3613
|
-
|
|
3598
|
+
const {
|
|
3599
|
+
swapQuoteResponse
|
|
3600
|
+
} = await this.#koniState.swapService.getLatestQuoteFromSwapRequest(swapRequest);
|
|
3601
|
+
return swapQuoteResponse;
|
|
3614
3602
|
}
|
|
3615
3603
|
async validateSwapProcess(params) {
|
|
3616
3604
|
return this.#koniState.swapService.validateSwapProcess(params);
|
|
@@ -3647,7 +3635,8 @@ export default class KoniExtension {
|
|
|
3647
3635
|
address,
|
|
3648
3636
|
process,
|
|
3649
3637
|
selectedQuote: quote,
|
|
3650
|
-
recipient
|
|
3638
|
+
recipient,
|
|
3639
|
+
currentStep: inputData.currentStep
|
|
3651
3640
|
});
|
|
3652
3641
|
if (swapValidations.length > 0) {
|
|
3653
3642
|
if (step) {
|
|
@@ -3668,6 +3657,7 @@ export default class KoniExtension {
|
|
|
3668
3657
|
}
|
|
3669
3658
|
throw e;
|
|
3670
3659
|
}
|
|
3660
|
+
console.log('swap data', submitData);
|
|
3671
3661
|
|
|
3672
3662
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
3673
3663
|
const {
|
|
@@ -4716,10 +4706,12 @@ export default class KoniExtension {
|
|
|
4716
4706
|
/* Swap service */
|
|
4717
4707
|
case 'pri(swapService.subscribePairs)':
|
|
4718
4708
|
return this.subscribeSwapPairs(id, port);
|
|
4719
|
-
case 'pri(swapService.
|
|
4720
|
-
return this.
|
|
4709
|
+
case 'pri(swapService.getOptimalProcessOnSelectQuote)':
|
|
4710
|
+
return this.getOptimalSwapProcessOnSelectQuote(request);
|
|
4721
4711
|
case 'pri(swapService.handleSwapRequest)':
|
|
4722
4712
|
return this.handleSwapRequest(request);
|
|
4713
|
+
case 'pri(swapService.handleSwapRequestV2)':
|
|
4714
|
+
return this.handleSwapRequestV2(request);
|
|
4723
4715
|
case 'pri(swapService.getLatestQuote)':
|
|
4724
4716
|
return this.getLatestSwapQuote(request);
|
|
4725
4717
|
case 'pri(swapService.validateSwapProcess)':
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"./cjs/detectPackage.js"
|
|
18
18
|
],
|
|
19
19
|
"type": "module",
|
|
20
|
-
"version": "1.3.
|
|
20
|
+
"version": "1.3.27-0",
|
|
21
21
|
"main": "./cjs/index.js",
|
|
22
22
|
"module": "./index.js",
|
|
23
23
|
"types": "./index.d.ts",
|
|
@@ -1886,6 +1886,11 @@
|
|
|
1886
1886
|
"require": "./cjs/services/swap-service/handler/uniswap-handler.js",
|
|
1887
1887
|
"default": "./services/swap-service/handler/uniswap-handler.js"
|
|
1888
1888
|
},
|
|
1889
|
+
"./services/swap-service/interface": {
|
|
1890
|
+
"types": "./services/swap-service/interface.d.ts",
|
|
1891
|
+
"require": "./cjs/services/swap-service/interface.js",
|
|
1892
|
+
"default": "./services/swap-service/interface.js"
|
|
1893
|
+
},
|
|
1889
1894
|
"./services/swap-service/utils": {
|
|
1890
1895
|
"types": "./services/swap-service/utils.d.ts",
|
|
1891
1896
|
"require": "./cjs/services/swap-service/utils.js",
|
|
@@ -2664,13 +2669,13 @@
|
|
|
2664
2669
|
"@reduxjs/toolkit": "^1.9.1",
|
|
2665
2670
|
"@sora-substrate/type-definitions": "^1.17.7",
|
|
2666
2671
|
"@substrate/connect": "^0.8.9",
|
|
2667
|
-
"@subwallet/chain-list": "0.2.
|
|
2668
|
-
"@subwallet/extension-base": "^1.3.
|
|
2669
|
-
"@subwallet/extension-chains": "^1.3.
|
|
2670
|
-
"@subwallet/extension-dapp": "^1.3.
|
|
2671
|
-
"@subwallet/extension-inject": "^1.3.
|
|
2672
|
+
"@subwallet/chain-list": "0.2.102",
|
|
2673
|
+
"@subwallet/extension-base": "^1.3.27-0",
|
|
2674
|
+
"@subwallet/extension-chains": "^1.3.27-0",
|
|
2675
|
+
"@subwallet/extension-dapp": "^1.3.27-0",
|
|
2676
|
+
"@subwallet/extension-inject": "^1.3.27-0",
|
|
2672
2677
|
"@subwallet/keyring": "^0.1.9",
|
|
2673
|
-
"@subwallet/subwallet-api-sdk": "^1.3.
|
|
2678
|
+
"@subwallet/subwallet-api-sdk": "^1.3.27-0",
|
|
2674
2679
|
"@subwallet/ui-keyring": "^0.1.9",
|
|
2675
2680
|
"@ton/core": "^0.56.3",
|
|
2676
2681
|
"@ton/crypto": "^3.2.0",
|
package/packageInfo.js
CHANGED
|
@@ -7,5 +7,5 @@ export const packageInfo = {
|
|
|
7
7
|
name: '@subwallet/extension-base',
|
|
8
8
|
path: (import.meta && import.meta.url) ? new URL(import.meta.url).pathname.substring(0, new URL(import.meta.url).pathname.lastIndexOf('/') + 1) : 'auto',
|
|
9
9
|
type: 'esm',
|
|
10
|
-
version: '1.3.
|
|
10
|
+
version: '1.3.27-0'
|
|
11
11
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { _ChainAsset } from '@subwallet/chain-list/types';
|
|
2
2
|
import { _Address } from '@subwallet/extension-base/background/KoniTypes';
|
|
3
3
|
import { _EvmApi } from '@subwallet/extension-base/services/chain-service/types';
|
|
4
|
-
import {
|
|
4
|
+
import { CommonOptimalTransferPath } from '@subwallet/extension-base/types/service-base';
|
|
5
5
|
export interface RequestOptimalTransferProcess {
|
|
6
6
|
originChain: string;
|
|
7
7
|
destChain?: string;
|
|
@@ -9,5 +9,5 @@ export interface RequestOptimalTransferProcess {
|
|
|
9
9
|
address: _Address;
|
|
10
10
|
amount: string;
|
|
11
11
|
}
|
|
12
|
-
export declare function getDefaultTransferProcess():
|
|
13
|
-
export declare function getSnowbridgeTransferProcessFromEvm(address: string, evmApi: _EvmApi, tokenInfo: _ChainAsset, amount: string): Promise<
|
|
12
|
+
export declare function getDefaultTransferProcess(): CommonOptimalTransferPath;
|
|
13
|
+
export declare function getSnowbridgeTransferProcessFromEvm(address: string, evmApi: _EvmApi, tokenInfo: _ChainAsset, amount: string): Promise<CommonOptimalTransferPath>;
|
|
@@ -3,8 +3,7 @@ import KoniState from '@subwallet/extension-base/koni/background/handlers/State'
|
|
|
3
3
|
import { RequestOptimalTransferProcess } from '@subwallet/extension-base/services/balance-service/helpers/process';
|
|
4
4
|
import { ServiceStatus, StoppableServiceInterface } from '@subwallet/extension-base/services/base/types';
|
|
5
5
|
import { EventItem, EventType } from '@subwallet/extension-base/services/event-service/types';
|
|
6
|
-
import { BalanceItem, BalanceJson } from '@subwallet/extension-base/types';
|
|
7
|
-
import { CommonOptimalPath } from '@subwallet/extension-base/types/service-base';
|
|
6
|
+
import { BalanceItem, BalanceJson, CommonOptimalTransferPath } from '@subwallet/extension-base/types';
|
|
8
7
|
import { PromiseHandler } from '@subwallet/extension-base/utils';
|
|
9
8
|
import { BehaviorSubject } from 'rxjs';
|
|
10
9
|
/**
|
|
@@ -99,5 +98,5 @@ export declare class BalanceService implements StoppableServiceInterface {
|
|
|
99
98
|
private startBalanceDetectCache;
|
|
100
99
|
private startScanBalance;
|
|
101
100
|
private stopScanBalance;
|
|
102
|
-
getOptimalTransferProcess(params: RequestOptimalTransferProcess): Promise<
|
|
101
|
+
getOptimalTransferProcess(params: RequestOptimalTransferProcess): Promise<CommonOptimalTransferPath>;
|
|
103
102
|
}
|
|
@@ -2,8 +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,
|
|
6
|
-
import { OptimalSwapPathParams, SwapProviderId, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types/swap';
|
|
5
|
+
import { BaseStepDetail, CommonOptimalSwapPath, CommonStepFeeInfo, OptimalSwapPathParams, OptimalSwapPathParamsV2, SwapProviderId, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types';
|
|
7
6
|
import { SwapBaseInterface } from '../base-handler';
|
|
8
7
|
export declare class AssetHubSwapHandler implements SwapBaseInterface {
|
|
9
8
|
private swapBaseHandler;
|
|
@@ -20,10 +19,14 @@ export declare class AssetHubSwapHandler implements SwapBaseInterface {
|
|
|
20
19
|
init(): Promise<void>;
|
|
21
20
|
getXcmStep(params: OptimalSwapPathParams): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
22
21
|
getSubmitStep(params: OptimalSwapPathParams): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
23
|
-
|
|
22
|
+
getXcmStepV2(params: OptimalSwapPathParamsV2): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
23
|
+
getSwapStepV2(params: OptimalSwapPathParamsV2): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
24
|
+
generateOptimalProcess(params: OptimalSwapPathParams): Promise<CommonOptimalSwapPath>;
|
|
25
|
+
generateOptimalProcessV2(params: OptimalSwapPathParamsV2): Promise<CommonOptimalSwapPath>;
|
|
24
26
|
handleXcmStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
|
|
25
27
|
handleSubmitStep(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
|
|
26
28
|
handleSwapProcess(params: SwapSubmitParams): Promise<SwapSubmitStepData>;
|
|
27
29
|
validateSwapStep(params: ValidateSwapProcessParams, isXcmOk: boolean, stepIndex: number): Promise<TransactionError[]>;
|
|
28
30
|
validateSwapProcess(params: ValidateSwapProcessParams): Promise<TransactionError[]>;
|
|
31
|
+
validateSwapProcessV2(params: ValidateSwapProcessParams): Promise<TransactionError[]>;
|
|
29
32
|
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import { SwapError } from '@subwallet/extension-base/background/errors/SwapError';
|
|
4
5
|
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
5
6
|
import { ChainType, ExtrinsicType } from '@subwallet/extension-base/background/KoniTypes';
|
|
6
7
|
import { XCM_MIN_AMOUNT_RATIO } from '@subwallet/extension-base/constants';
|
|
7
8
|
import { _validateBalanceToSwapOnAssetHub, _validateSwapRecipient } from '@subwallet/extension-base/core/logic-validation/swap';
|
|
8
9
|
import { createXcmExtrinsic } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
|
|
9
|
-
import { _getChainNativeTokenSlug, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { CommonStepType } from '@subwallet/extension-base/types
|
|
13
|
-
import { SwapErrorType, SwapFeeType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types/swap';
|
|
10
|
+
import { _getChainNativeTokenSlug, _getTokenMinAmount, _isNativeToken } from '@subwallet/extension-base/services/chain-service/utils';
|
|
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
14
|
import { getId } from '@subwallet/extension-base/utils/getId';
|
|
15
15
|
import BigN from 'bignumber.js';
|
|
16
16
|
import { SwapBaseHandler } from "../base-handler.js";
|
|
@@ -145,39 +145,131 @@ export class AssetHubSwapHandler {
|
|
|
145
145
|
}
|
|
146
146
|
return Promise.resolve(undefined);
|
|
147
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) {
|
|
221
|
+
return Promise.resolve(undefined);
|
|
222
|
+
}
|
|
223
|
+
if (params.selectedQuote) {
|
|
224
|
+
const submitStep = {
|
|
225
|
+
name: 'Swap',
|
|
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]);
|
|
234
|
+
}
|
|
235
|
+
return Promise.resolve(undefined);
|
|
236
|
+
}
|
|
148
237
|
generateOptimalProcess(params) {
|
|
149
238
|
return this.swapBaseHandler.generateOptimalProcess(params, [this.getXcmStep.bind(this), this.getSubmitStep.bind(this)]);
|
|
150
239
|
}
|
|
240
|
+
generateOptimalProcessV2(params) {
|
|
241
|
+
const stepFuncList = params.path.map(step => {
|
|
242
|
+
if (step.action === DynamicSwapType.BRIDGE) {
|
|
243
|
+
return this.getXcmStepV2.bind(this);
|
|
244
|
+
}
|
|
245
|
+
if (step.action === DynamicSwapType.SWAP) {
|
|
246
|
+
return this.getSwapStepV2.bind(this);
|
|
247
|
+
}
|
|
248
|
+
throw new Error(`Error generating optimal process: Action ${step.action} is not supported`);
|
|
249
|
+
});
|
|
250
|
+
return this.swapBaseHandler.generateOptimalProcessV2(params, stepFuncList);
|
|
251
|
+
}
|
|
151
252
|
async handleXcmStep(params) {
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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;
|
|
156
259
|
const originChain = this.chainService.getChainInfoByKey(originAsset.originChain);
|
|
157
260
|
const destinationChain = this.chainService.getChainInfoByKey(destinationAsset.originChain);
|
|
158
261
|
const substrateApi = this.chainService.getSubstrateApi(originAsset.originChain);
|
|
159
262
|
const chainApi = await substrateApi.isReady;
|
|
160
|
-
const
|
|
161
|
-
const xcmFee = params.process.totalFee[params.currentStep];
|
|
162
|
-
const bnAmount = new BigN(params.quote.fromAmount);
|
|
163
|
-
const bnDestinationAssetBalance = new BigN(destinationAssetBalance.value);
|
|
164
|
-
const id = getId();
|
|
165
|
-
const feeInfo = await this.swapBaseHandler.feeService.subscribeChainFee(id, originChain.slug, 'substrate');
|
|
166
|
-
let bnTotalAmount = bnAmount.minus(bnDestinationAssetBalance);
|
|
167
|
-
if (_isNativeToken(originAsset)) {
|
|
168
|
-
const bnXcmFee = new BigN(xcmFee.feeComponent[0].amount); // xcm fee is paid in native token but swap token is not always native token
|
|
169
|
-
|
|
170
|
-
bnTotalAmount = bnTotalAmount.plus(bnXcmFee);
|
|
171
|
-
}
|
|
263
|
+
const feeInfo = await this.swapBaseHandler.feeService.subscribeChainFee(getId(), originAsset.originChain, 'substrate');
|
|
172
264
|
const xcmTransfer = await createXcmExtrinsic({
|
|
173
265
|
originTokenInfo: originAsset,
|
|
174
266
|
destinationTokenInfo: destinationAsset,
|
|
175
|
-
sendingValue:
|
|
267
|
+
sendingValue: briefXcmStep.sendingValue,
|
|
176
268
|
recipient: params.address,
|
|
177
269
|
substrateApi: chainApi,
|
|
178
270
|
sender: params.address,
|
|
179
|
-
|
|
180
|
-
|
|
271
|
+
destinationChain,
|
|
272
|
+
originChain,
|
|
181
273
|
feeInfo
|
|
182
274
|
});
|
|
183
275
|
const xcmData = {
|
|
@@ -185,14 +277,14 @@ export class AssetHubSwapHandler {
|
|
|
185
277
|
destinationNetworkKey: destinationAsset.originChain,
|
|
186
278
|
from: params.address,
|
|
187
279
|
to: params.address,
|
|
188
|
-
value:
|
|
280
|
+
value: briefXcmStep.sendingValue,
|
|
189
281
|
tokenSlug: originAsset.slug,
|
|
190
282
|
showExtraWarning: true
|
|
191
283
|
};
|
|
192
284
|
return {
|
|
193
285
|
txChain: originAsset.originChain,
|
|
194
286
|
extrinsic: xcmTransfer,
|
|
195
|
-
transferNativeAmount: _isNativeToken(originAsset) ?
|
|
287
|
+
transferNativeAmount: _isNativeToken(originAsset) ? briefXcmStep.sendingValue : '0',
|
|
196
288
|
extrinsicType: ExtrinsicType.TRANSFER_XCM,
|
|
197
289
|
chainType: ChainType.SUBSTRATE,
|
|
198
290
|
txData: xcmData
|
|
@@ -200,7 +292,11 @@ export class AssetHubSwapHandler {
|
|
|
200
292
|
}
|
|
201
293
|
async handleSubmitStep(params) {
|
|
202
294
|
var _this$router;
|
|
203
|
-
const
|
|
295
|
+
const metadata = params.process.steps[params.currentStep].metadata;
|
|
296
|
+
if (!metadata || !metadata.sendingValue || !metadata.destinationTokenInfo || !metadata.originTokenInfo) {
|
|
297
|
+
return new SwapError(SwapErrorType.UNKNOWN);
|
|
298
|
+
}
|
|
299
|
+
const fromAsset = metadata.originTokenInfo;
|
|
204
300
|
const txData = {
|
|
205
301
|
provider: this.providerInfo,
|
|
206
302
|
quote: params.quote,
|
|
@@ -213,7 +309,12 @@ export class AssetHubSwapHandler {
|
|
|
213
309
|
fromAmount,
|
|
214
310
|
toAmount
|
|
215
311
|
} = params.quote;
|
|
312
|
+
|
|
313
|
+
// todo: move to gen process
|
|
216
314
|
const minReceive = new BigN(1 - params.slippage).times(toAmount).integerValue(BigN.ROUND_DOWN);
|
|
315
|
+
if (!params.address || !paths || !fromAmount || !minReceive) {
|
|
316
|
+
throw new SwapError(SwapErrorType.UNKNOWN);
|
|
317
|
+
}
|
|
217
318
|
const extrinsic = await ((_this$router = this.router) === null || _this$router === void 0 ? void 0 : _this$router.buildSwapExtrinsic(paths, params.address, fromAmount, minReceive.toString()));
|
|
218
319
|
return {
|
|
219
320
|
txChain: fromAsset.originChain,
|
|
@@ -286,14 +387,22 @@ export class AssetHubSwapHandler {
|
|
|
286
387
|
if (bnAmount.lte(0)) {
|
|
287
388
|
return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')];
|
|
288
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
|
+
}
|
|
289
394
|
let isXcmOk = false;
|
|
395
|
+
const currentStep = params.currentStep;
|
|
290
396
|
for (const [index, step] of params.process.steps.entries()) {
|
|
397
|
+
if (currentStep > index) {
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
291
400
|
const getErrors = async () => {
|
|
292
401
|
switch (step.type) {
|
|
293
402
|
case CommonStepType.DEFAULT:
|
|
294
403
|
return Promise.resolve([]);
|
|
295
404
|
case CommonStepType.XCM:
|
|
296
|
-
return this.swapBaseHandler.
|
|
405
|
+
return this.swapBaseHandler.validateXcmStepV2(params, index);
|
|
297
406
|
case SwapStepType.SWAP:
|
|
298
407
|
return this.validateSwapStep(params, isXcmOk, index);
|
|
299
408
|
default:
|
|
@@ -309,4 +418,37 @@ export class AssetHubSwapHandler {
|
|
|
309
418
|
}
|
|
310
419
|
return [];
|
|
311
420
|
}
|
|
421
|
+
async validateSwapProcessV2(params) {
|
|
422
|
+
// todo: recheck address and recipient format in params
|
|
423
|
+
const {
|
|
424
|
+
process,
|
|
425
|
+
selectedQuote
|
|
426
|
+
} = params; // todo: review flow, currentStep param.
|
|
427
|
+
|
|
428
|
+
// todo: validate path with optimalProcess
|
|
429
|
+
// todo: review error message in case many step swap
|
|
430
|
+
if (BigN(selectedQuote.fromAmount).lte(0)) {
|
|
431
|
+
return [new TransactionError(BasicTxErrorType.INVALID_PARAMS, 'Amount must be greater than 0')];
|
|
432
|
+
}
|
|
433
|
+
const actionList = process.steps.map(step => step.type);
|
|
434
|
+
const [firstStep, secondStep, thirdStep, fourthStep, fifthStep] = actionList;
|
|
435
|
+
const swap = firstStep === CommonStepType.DEFAULT && secondStep === SwapStepType.SWAP && !thirdStep;
|
|
436
|
+
const swapXcm = firstStep === CommonStepType.DEFAULT && secondStep === SwapStepType.SWAP && thirdStep === CommonStepType.XCM && !fourthStep;
|
|
437
|
+
const xcmSwap = firstStep === CommonStepType.DEFAULT && secondStep === CommonStepType.XCM && thirdStep === SwapStepType.SWAP && !fourthStep;
|
|
438
|
+
const xcmSwapXcm = firstStep === CommonStepType.DEFAULT && secondStep === CommonStepType.XCM && thirdStep === SwapStepType.SWAP && fourthStep === CommonStepType.XCM && !fifthStep;
|
|
439
|
+
if (swap) {
|
|
440
|
+
return this.swapBaseHandler.validateSwapOnlyProcess(params, 1); // todo: create interface for input request
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (swapXcm) {
|
|
444
|
+
return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
|
|
445
|
+
}
|
|
446
|
+
if (xcmSwap) {
|
|
447
|
+
return this.swapBaseHandler.validateXcmSwapProcess(params, 2, 1);
|
|
448
|
+
}
|
|
449
|
+
if (xcmSwapXcm) {
|
|
450
|
+
return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
|
|
451
|
+
}
|
|
452
|
+
return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
|
|
453
|
+
}
|
|
312
454
|
}
|
|
@@ -128,6 +128,9 @@ export const checkMinAmountForPath = (reserves, amounts, minAmounts) => {
|
|
|
128
128
|
export const buildSwapExtrinsic = (api, paths, recipient, amountIn, amountOutMin, keepAlive = true) => {
|
|
129
129
|
const pathsInfo = paths.map(asset => {
|
|
130
130
|
const multilocation = _getXcmAssetMultilocation(asset);
|
|
131
|
+
if (!multilocation) {
|
|
132
|
+
throw new Error('Error getting multilocation');
|
|
133
|
+
}
|
|
131
134
|
return api.createType('MultiLocation', multilocation).toU8a();
|
|
132
135
|
});
|
|
133
136
|
return api.tx.assetConversion.swapExactTokensForTokens(pathsInfo, amountIn, amountOutMin, recipient, keepAlive);
|
|
@@ -2,13 +2,16 @@ 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 {
|
|
5
|
+
import { GenSwapStepFuncV2, OptimalSwapPathParamsV2 } from '@subwallet/extension-base/types';
|
|
6
|
+
import { BaseStepDetail, CommonOptimalSwapPath, CommonStepFeeInfo } from '@subwallet/extension-base/types/service-base';
|
|
6
7
|
import { GenSwapStepFunc, OptimalSwapPathParams, SwapProvider, SwapProviderId, SwapSubmitParams, SwapSubmitStepData, ValidateSwapProcessParams } from '@subwallet/extension-base/types/swap';
|
|
7
8
|
export interface SwapBaseInterface {
|
|
8
9
|
providerSlug: SwapProviderId;
|
|
9
|
-
generateOptimalProcess: (params: OptimalSwapPathParams) => Promise<
|
|
10
|
+
generateOptimalProcess: (params: OptimalSwapPathParams) => Promise<CommonOptimalSwapPath>;
|
|
11
|
+
generateOptimalProcessV2: (params: OptimalSwapPathParamsV2) => Promise<CommonOptimalSwapPath>;
|
|
10
12
|
getSubmitStep: (params: OptimalSwapPathParams) => Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
11
13
|
validateSwapProcess: (params: ValidateSwapProcessParams) => Promise<TransactionError[]>;
|
|
14
|
+
validateSwapProcessV2: (params: ValidateSwapProcessParams) => Promise<TransactionError[]>;
|
|
12
15
|
handleSwapProcess: (params: SwapSubmitParams) => Promise<SwapSubmitStepData>;
|
|
13
16
|
handleSubmitStep: (params: SwapSubmitParams) => Promise<SwapSubmitStepData>;
|
|
14
17
|
isReady?: boolean;
|
|
@@ -28,11 +31,17 @@ export declare class SwapBaseHandler {
|
|
|
28
31
|
balanceService: BalanceService;
|
|
29
32
|
feeService: FeeService;
|
|
30
33
|
constructor({ balanceService, chainService, feeService, providerName, providerSlug }: SwapBaseHandlerInitParams);
|
|
31
|
-
generateOptimalProcess(params: OptimalSwapPathParams, genStepFuncList: GenSwapStepFunc[]): Promise<
|
|
34
|
+
generateOptimalProcess(params: OptimalSwapPathParams, genStepFuncList: GenSwapStepFunc[]): Promise<CommonOptimalSwapPath>;
|
|
35
|
+
generateOptimalProcessV2(params: OptimalSwapPathParamsV2, genStepFuncList: GenSwapStepFuncV2[]): Promise<CommonOptimalSwapPath>;
|
|
32
36
|
validateXcmStep(params: ValidateSwapProcessParams, stepIndex: number): Promise<TransactionError[]>;
|
|
37
|
+
validateXcmStepV2(params: ValidateSwapProcessParams, stepIndex: number): Promise<TransactionError[]>;
|
|
33
38
|
validateTokenApproveStep(params: ValidateSwapProcessParams, stepIndex: number): Promise<TransactionError[]>;
|
|
34
39
|
validateSetFeeTokenStep(params: ValidateSwapProcessParams, stepIndex: number): Promise<TransactionError[]>;
|
|
35
40
|
validateSwapStep(params: ValidateSwapProcessParams, isXcmOk: boolean, stepIndex: number): Promise<TransactionError[]>;
|
|
41
|
+
private validateBridgeStep;
|
|
42
|
+
private validateSwapStepV2;
|
|
43
|
+
validateSwapOnlyProcess(params: ValidateSwapProcessParams, swapIndex: number): Promise<TransactionError[]>;
|
|
44
|
+
validateXcmSwapProcess(params: ValidateSwapProcessParams, swapIndex: number, xcmIndex: number): Promise<TransactionError[]>;
|
|
36
45
|
get name(): string;
|
|
37
46
|
get slug(): string;
|
|
38
47
|
get providerInfo(): SwapProvider;
|