@subwallet/extension-base 1.3.37-0 → 1.3.38-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 +2 -0
- package/cjs/core/logic-validation/request.js +49 -12
- package/cjs/koni/background/handlers/State.js +4 -8
- package/cjs/koni/background/handlers/Tabs.js +38 -5
- package/cjs/packageInfo.js +1 -1
- package/cjs/page/cardano/cips/cip30.js +21 -1
- package/cjs/page/cardano/index.js +5 -5
- package/cjs/services/request-service/handler/CardanoRequestHandler.js +4 -3
- package/cjs/services/request-service/helper/index.js +19 -17
- package/cjs/services/swap-service/handler/base-handler.js +4 -2
- package/cjs/services/swap-service/handler/uniswap-handler.js +122 -57
- package/cjs/services/swap-service/index.js +1 -1
- package/core/logic-validation/request.d.ts +1 -0
- package/core/logic-validation/request.js +50 -14
- package/koni/background/handlers/State.js +5 -9
- package/koni/background/handlers/Tabs.d.ts +1 -0
- package/koni/background/handlers/Tabs.js +38 -5
- package/package.json +8 -8
- package/packageInfo.js +1 -1
- package/page/cardano/cips/cip30.d.ts +31 -17
- package/page/cardano/cips/cip30.js +17 -1
- package/page/cardano/index.d.ts +20 -4
- package/page/cardano/index.js +5 -5
- package/services/request-service/handler/CardanoRequestHandler.js +4 -3
- package/services/request-service/helper/index.js +19 -17
- package/services/swap-service/handler/base-handler.js +4 -2
- package/services/swap-service/handler/uniswap-handler.d.ts +1 -1
- package/services/swap-service/handler/uniswap-handler.js +99 -34
- package/services/swap-service/index.js +1 -1
- package/types/service-base.d.ts +1 -0
|
@@ -1,22 +1,36 @@
|
|
|
1
1
|
import { CardanoPaginate, Cbor } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
2
|
import { SendRequest } from '@subwallet/extension-base/page/types';
|
|
3
3
|
export declare class CIP30Api {
|
|
4
|
-
private sendMessage;
|
|
4
|
+
private readonly sendMessage;
|
|
5
5
|
constructor(sendMessage: SendRequest);
|
|
6
|
-
getExtension
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
6
|
+
private getExtension;
|
|
7
|
+
private getNetworkId;
|
|
8
|
+
private getCollateral;
|
|
9
|
+
private getUtxos;
|
|
10
|
+
private getUsedAddresses;
|
|
11
|
+
private getChangeAddress;
|
|
12
|
+
private getUnusedAddresses;
|
|
13
|
+
private getRewardAddresses;
|
|
14
|
+
private signTx;
|
|
15
|
+
private signData;
|
|
16
|
+
private submitTx;
|
|
17
|
+
private getBalance;
|
|
18
|
+
get apis(): {
|
|
19
|
+
getExtension: () => {
|
|
20
|
+
cip: number;
|
|
21
|
+
}[];
|
|
22
|
+
getNetworkId: () => Promise<number>;
|
|
23
|
+
getCollateral: (payload: {
|
|
24
|
+
amount: Cbor;
|
|
25
|
+
}) => Promise<string[] | null>;
|
|
26
|
+
getUtxos: (amount?: Cbor, paginate?: CardanoPaginate) => Promise<string[] | null>;
|
|
27
|
+
getUsedAddresses: () => Promise<string[]>;
|
|
28
|
+
getChangeAddress: () => Promise<string>;
|
|
29
|
+
getUnusedAddresses: () => Promise<string[]>;
|
|
30
|
+
getRewardAddresses: () => Promise<string[]>;
|
|
31
|
+
signTx: (tx: Cbor, partialSign?: boolean) => Promise<string>;
|
|
32
|
+
signData: (address: string, payload: string) => Promise<import("@subwallet/extension-base/background/KoniTypes").ResponseCardanoSignData>;
|
|
33
|
+
submitTx: (tx: Cbor) => Promise<string>;
|
|
34
|
+
getBalance: () => Promise<string>;
|
|
35
|
+
};
|
|
22
36
|
}
|
|
@@ -32,7 +32,7 @@ export class CIP30Api {
|
|
|
32
32
|
return new Promise(resolve => resolve([]));
|
|
33
33
|
}
|
|
34
34
|
async getRewardAddresses() {
|
|
35
|
-
return
|
|
35
|
+
return await this.sendMessage('cardano(account.get.reward.address)');
|
|
36
36
|
}
|
|
37
37
|
async signTx(tx, partialSign = false) {
|
|
38
38
|
return await this.sendMessage('cardano(transaction.sign)', {
|
|
@@ -52,4 +52,20 @@ export class CIP30Api {
|
|
|
52
52
|
async getBalance() {
|
|
53
53
|
return await this.sendMessage('cardano(account.get.balance)');
|
|
54
54
|
}
|
|
55
|
+
get apis() {
|
|
56
|
+
return {
|
|
57
|
+
getExtension: () => this.getExtension(),
|
|
58
|
+
getNetworkId: () => this.getNetworkId(),
|
|
59
|
+
getCollateral: payload => this.getCollateral(payload),
|
|
60
|
+
getUtxos: (amount, paginate) => this.getUtxos(amount, paginate),
|
|
61
|
+
getUsedAddresses: () => this.getUsedAddresses(),
|
|
62
|
+
getChangeAddress: () => this.getChangeAddress(),
|
|
63
|
+
getUnusedAddresses: () => this.getUnusedAddresses(),
|
|
64
|
+
getRewardAddresses: () => this.getRewardAddresses(),
|
|
65
|
+
signTx: (tx, partialSign = false) => this.signTx(tx, partialSign),
|
|
66
|
+
signData: (address, payload) => this.signData(address, payload),
|
|
67
|
+
submitTx: tx => this.submitTx(tx),
|
|
68
|
+
getBalance: () => this.getBalance()
|
|
69
|
+
};
|
|
70
|
+
}
|
|
55
71
|
}
|
package/page/cardano/index.d.ts
CHANGED
|
@@ -1,13 +1,29 @@
|
|
|
1
1
|
import type { CardanoExtensionCIP, CardanoProvider } from '@subwallet/extension-inject/types';
|
|
2
|
-
import { CIP30Api } from '@subwallet/extension-base/page/cardano/cips';
|
|
3
2
|
import { SendRequest } from '@subwallet/extension-base/page/types';
|
|
4
3
|
export default class SubWalletCardanoProvider implements CardanoProvider {
|
|
5
4
|
readonly apiVersion: string;
|
|
6
5
|
readonly icon: string;
|
|
7
6
|
readonly name: string;
|
|
8
7
|
readonly supportedExtensions: CardanoExtensionCIP[];
|
|
9
|
-
|
|
8
|
+
private readonly sendMessage;
|
|
10
9
|
constructor(sendMessage: SendRequest);
|
|
11
|
-
enable()
|
|
12
|
-
|
|
10
|
+
enable: () => Promise<Readonly<{
|
|
11
|
+
getExtension: () => {
|
|
12
|
+
cip: number;
|
|
13
|
+
}[];
|
|
14
|
+
getNetworkId: () => Promise<number>;
|
|
15
|
+
getCollateral: (payload: {
|
|
16
|
+
amount: string;
|
|
17
|
+
}) => Promise<string[] | null>;
|
|
18
|
+
getUtxos: (amount?: string | undefined, paginate?: import("../../background/KoniTypes").CardanoPaginate | undefined) => Promise<string[] | null>;
|
|
19
|
+
getUsedAddresses: () => Promise<string[]>;
|
|
20
|
+
getChangeAddress: () => Promise<string>;
|
|
21
|
+
getUnusedAddresses: () => Promise<string[]>;
|
|
22
|
+
getRewardAddresses: () => Promise<string[]>;
|
|
23
|
+
signTx: (tx: string, partialSign?: boolean) => Promise<string>;
|
|
24
|
+
signData: (address: string, payload: string) => Promise<import("../../background/KoniTypes").ResponseCardanoSignData>;
|
|
25
|
+
submitTx: (tx: string) => Promise<string>;
|
|
26
|
+
getBalance: () => Promise<string>;
|
|
27
|
+
}>>;
|
|
28
|
+
isEnable: () => Promise<boolean>;
|
|
13
29
|
}
|
package/page/cardano/index.js
CHANGED
|
@@ -14,7 +14,7 @@ export default class SubWalletCardanoProvider {
|
|
|
14
14
|
this.icon = WALLET_ICON;
|
|
15
15
|
this.sendMessage = sendMessage;
|
|
16
16
|
}
|
|
17
|
-
async
|
|
17
|
+
enable = async () => {
|
|
18
18
|
const isEnabled = await this.sendMessage('pub(authorize.tabV2)', {
|
|
19
19
|
origin,
|
|
20
20
|
accountAuthTypes: ['cardano']
|
|
@@ -23,12 +23,12 @@ export default class SubWalletCardanoProvider {
|
|
|
23
23
|
throw new Error('Access to the wallet is denied');
|
|
24
24
|
}
|
|
25
25
|
const CIP30 = new CIP30Api(this.sendMessage);
|
|
26
|
-
return Object.freeze(CIP30);
|
|
27
|
-
}
|
|
28
|
-
async
|
|
26
|
+
return Object.freeze(CIP30.apis);
|
|
27
|
+
};
|
|
28
|
+
isEnable = async () => {
|
|
29
29
|
const accountList = await this.sendMessage('pub(accounts.list)', {
|
|
30
30
|
accountAuthType: 'cardano'
|
|
31
31
|
});
|
|
32
32
|
return accountList.length > 0;
|
|
33
|
-
}
|
|
33
|
+
};
|
|
34
34
|
}
|
|
@@ -132,14 +132,15 @@ export default class CardanoRequestHandler {
|
|
|
132
132
|
}
|
|
133
133
|
signMessage(confirmation) {
|
|
134
134
|
const {
|
|
135
|
-
address,
|
|
135
|
+
address: addressToSign,
|
|
136
|
+
currentAddress,
|
|
136
137
|
payload
|
|
137
138
|
} = confirmation.payload;
|
|
138
|
-
const pair = keyring.getPair(
|
|
139
|
+
const pair = keyring.getPair(currentAddress);
|
|
139
140
|
if (pair.isLocked) {
|
|
140
141
|
keyring.unlockPair(pair.address);
|
|
141
142
|
}
|
|
142
|
-
return pair.cardano.signMessage(payload,
|
|
143
|
+
return pair.cardano.signMessage(payload, addressToSign);
|
|
143
144
|
}
|
|
144
145
|
signTransactionCardano(confirmation) {
|
|
145
146
|
// alibaba
|
|
@@ -46,25 +46,27 @@ export const extractMetadata = store => {
|
|
|
46
46
|
export const convertAssetToValue = amount => {
|
|
47
47
|
const value = CardanoWasm.Value.new(CardanoWasm.BigNum.from_str('0'));
|
|
48
48
|
const multiAsset = CardanoWasm.MultiAsset.new();
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
49
|
+
if (amount !== null && amount !== void 0 && amount.length) {
|
|
50
|
+
for (const item of amount) {
|
|
51
|
+
if (item.unit === 'lovelace') {
|
|
52
|
+
value.set_coin(CardanoWasm.BigNum.from_str(item.quantity));
|
|
53
|
+
} else {
|
|
54
|
+
const policyIdHex = item.unit.slice(0, 56);
|
|
55
|
+
const assetNameHex = item.unit.slice(56);
|
|
56
|
+
const scriptHash = CardanoWasm.ScriptHash.from_bytes(Buffer.from(policyIdHex, 'hex'));
|
|
57
|
+
const assetName = CardanoWasm.AssetName.new(Buffer.from(assetNameHex, 'hex'));
|
|
58
|
+
const quantity = CardanoWasm.BigNum.from_str(item.quantity);
|
|
59
|
+
let assets = multiAsset.get(scriptHash);
|
|
60
|
+
if (!assets) {
|
|
61
|
+
assets = CardanoWasm.Assets.new();
|
|
62
|
+
}
|
|
63
|
+
assets.insert(assetName, quantity);
|
|
64
|
+
multiAsset.insert(scriptHash, assets);
|
|
61
65
|
}
|
|
62
|
-
assets.insert(assetName, quantity);
|
|
63
|
-
multiAsset.insert(scriptHash, assets);
|
|
64
66
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
if (multiAsset.len() > 0) {
|
|
68
|
+
value.set_multiasset(multiAsset);
|
|
69
|
+
}
|
|
68
70
|
}
|
|
69
71
|
return value;
|
|
70
72
|
};
|
|
@@ -165,6 +165,8 @@ export class SwapBaseHandler {
|
|
|
165
165
|
if (needEditAmount) {
|
|
166
166
|
bnSendingValue = BigN(selectedQuote.toAmount).multipliedBy(DEFAULT_EXCESS_AMOUNT_WEIGHT); // need to round
|
|
167
167
|
} else {
|
|
168
|
+
// todo: remove
|
|
169
|
+
console.log('The code cannot run into here, if it runs into here, pls ask dev to check');
|
|
168
170
|
bnSendingValue = BigN(selectedQuote.toAmount);
|
|
169
171
|
}
|
|
170
172
|
}
|
|
@@ -365,8 +367,8 @@ export class SwapBaseHandler {
|
|
|
365
367
|
if (recipient) {
|
|
366
368
|
const isEvmAddress = isEthereumAddress(recipient);
|
|
367
369
|
const isEvmDestChain = _isChainEvmCompatible(swapToChain);
|
|
368
|
-
if (isEvmAddress
|
|
369
|
-
// todo: update
|
|
370
|
+
if (isEvmAddress !== isEvmDestChain) {
|
|
371
|
+
// todo: update condition if support swap chain # EVM or Substrate
|
|
370
372
|
return [new TransactionError(SwapErrorType.INVALID_RECIPIENT)];
|
|
371
373
|
}
|
|
372
374
|
}
|
|
@@ -71,7 +71,7 @@ export declare class UniswapHandler implements SwapBaseInterface {
|
|
|
71
71
|
generateOptimalProcessV2(params: OptimalSwapPathParamsV2): Promise<CommonOptimalSwapPath>;
|
|
72
72
|
getApprovalStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
73
73
|
getApproveSwap(params: OptimalSwapPathParamsV2): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
74
|
-
getApproveBridge(params: OptimalSwapPathParamsV2): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
74
|
+
getApproveBridge(params: OptimalSwapPathParamsV2, isBridgeFirst: boolean): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
75
75
|
getPermitStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
76
76
|
getSubmitStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
77
77
|
getBridgeStep(params: OptimalSwapPathParamsV2, stepIndex: number): Promise<[BaseStepDetail, CommonStepFeeInfo] | undefined>;
|
|
@@ -7,6 +7,7 @@ import { validateTypedSignMessageDataV3V4 } from '@subwallet/extension-base/core
|
|
|
7
7
|
import { estimateTxFee, getERC20Allowance, getERC20SpendingApprovalTx } from '@subwallet/extension-base/koni/api/contract-handler/evm/web3';
|
|
8
8
|
import { createAcrossBridgeExtrinsic } from '@subwallet/extension-base/services/balance-service/transfer/xcm';
|
|
9
9
|
import { getAcrossQuote } from '@subwallet/extension-base/services/balance-service/transfer/xcm/acrossBridge';
|
|
10
|
+
import { DEFAULT_EXCESS_AMOUNT_WEIGHT, FEE_RATE_MULTIPLIER } from '@subwallet/extension-base/services/swap-service/utils';
|
|
10
11
|
import { BasicTxErrorType, CommonStepType, DynamicSwapType, FeeOptionKey, SwapFeeType, SwapProviderId, SwapStepType } from '@subwallet/extension-base/types';
|
|
11
12
|
import { _reformatAddressWithChain } from '@subwallet/extension-base/utils';
|
|
12
13
|
import { getId } from '@subwallet/extension-base/utils/getId';
|
|
@@ -94,7 +95,8 @@ export class UniswapHandler {
|
|
|
94
95
|
const stepFuncList = [];
|
|
95
96
|
/**
|
|
96
97
|
* approve - permit - swap or
|
|
97
|
-
* approve - permit - swap - approve - bridge
|
|
98
|
+
* approve - permit - swap - approve - bridge or
|
|
99
|
+
* approve - bridge - approve - permit - swap
|
|
98
100
|
*/
|
|
99
101
|
|
|
100
102
|
params.path.forEach(step => {
|
|
@@ -111,11 +113,26 @@ export class UniswapHandler {
|
|
|
111
113
|
return this.swapBaseHandler.generateOptimalProcessV2(params, stepFuncList);
|
|
112
114
|
}
|
|
113
115
|
async getApprovalStep(params, stepIndex) {
|
|
114
|
-
|
|
116
|
+
/**
|
|
117
|
+
* Explain: All processes will go through one of below processes. If a step do not have, it returns undefined and
|
|
118
|
+
* the stepIndex is still counted up
|
|
119
|
+
*
|
|
120
|
+
* Processes:
|
|
121
|
+
* approve - permit - swap or
|
|
122
|
+
* approve - permit - swap - approve - bridge or
|
|
123
|
+
* approve - bridge - approve - permit - swap
|
|
124
|
+
*/
|
|
125
|
+
const actionList = JSON.stringify(params.path.map(step => step.action));
|
|
126
|
+
const swap = actionList === JSON.stringify([DynamicSwapType.SWAP]);
|
|
127
|
+
const swapBridge = actionList === JSON.stringify([DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
|
|
128
|
+
const bridgeSwap = actionList === JSON.stringify([DynamicSwapType.BRIDGE, DynamicSwapType.SWAP]);
|
|
129
|
+
const isApproveBridge = stepIndex === 3 && swapBridge || stepIndex === 0 && bridgeSwap;
|
|
130
|
+
const isApproveSwap = stepIndex === 0 && swap || stepIndex === 0 && swapBridge || stepIndex === 2 && bridgeSwap;
|
|
131
|
+
if (isApproveSwap) {
|
|
115
132
|
return this.getApproveSwap(params);
|
|
116
133
|
}
|
|
117
|
-
if (
|
|
118
|
-
return this.getApproveBridge(params);
|
|
134
|
+
if (isApproveBridge) {
|
|
135
|
+
return this.getApproveBridge(params, bridgeSwap);
|
|
119
136
|
}
|
|
120
137
|
return Promise.resolve(undefined);
|
|
121
138
|
}
|
|
@@ -196,20 +213,28 @@ export class UniswapHandler {
|
|
|
196
213
|
};
|
|
197
214
|
return Promise.resolve([submitStep, feeInfo]);
|
|
198
215
|
}
|
|
199
|
-
async getApproveBridge(params) {
|
|
200
|
-
const
|
|
201
|
-
|
|
216
|
+
async getApproveBridge(params, isBridgeFirst) {
|
|
217
|
+
const {
|
|
218
|
+
path,
|
|
219
|
+
request,
|
|
220
|
+
selectedQuote
|
|
221
|
+
} = params;
|
|
222
|
+
if (!selectedQuote) {
|
|
202
223
|
return Promise.resolve(undefined);
|
|
203
224
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
225
|
+
const bridgePairInfo = path.find(action => action.action === DynamicSwapType.BRIDGE);
|
|
226
|
+
if (!bridgePairInfo || !bridgePairInfo.pair) {
|
|
227
|
+
return Promise.resolve(undefined);
|
|
228
|
+
}
|
|
229
|
+
const _sendingAmount = isBridgeFirst ? request.fromAmount : selectedQuote.toAmount;
|
|
230
|
+
const sendingAmount = BigNumber(_sendingAmount).multipliedBy(2).toFixed(0, 1); // ensure approve enough amount
|
|
231
|
+
const senderAddress = request.address;
|
|
232
|
+
const fromTokenInfo = this.chainService.getAssetBySlug(bridgePairInfo.pair.from);
|
|
208
233
|
const fromChainInfo = this.chainService.getChainInfoByKey(_getAssetOriginChain(fromTokenInfo));
|
|
209
234
|
const fromChainId = _getEvmChainId(fromChainInfo);
|
|
210
235
|
const evmApi = this.chainService.getEvmApi(fromChainInfo.slug);
|
|
211
236
|
const tokenContract = _getContractAddressOfToken(fromTokenInfo);
|
|
212
|
-
const toTokenInfo = this.chainService.getAssetBySlug(
|
|
237
|
+
const toTokenInfo = this.chainService.getAssetBySlug(bridgePairInfo.pair.to);
|
|
213
238
|
const toChainInfo = this.chainService.getChainInfoByKey(_getAssetOriginChain(toTokenInfo));
|
|
214
239
|
if (_isNativeToken(fromTokenInfo)) {
|
|
215
240
|
return Promise.resolve(undefined);
|
|
@@ -220,9 +245,10 @@ export class UniswapHandler {
|
|
|
220
245
|
const inputData = {
|
|
221
246
|
destinationTokenInfo: toTokenInfo,
|
|
222
247
|
originTokenInfo: fromTokenInfo,
|
|
223
|
-
sendingValue:
|
|
248
|
+
sendingValue: _sendingAmount,
|
|
224
249
|
sender: senderAddress,
|
|
225
250
|
recipient: senderAddress,
|
|
251
|
+
// todo: there's a case swap - bridge to another address
|
|
226
252
|
destinationChain: toChainInfo,
|
|
227
253
|
originChain: fromChainInfo
|
|
228
254
|
};
|
|
@@ -295,6 +321,10 @@ export class UniswapHandler {
|
|
|
295
321
|
if (!selectedQuote) {
|
|
296
322
|
return Promise.resolve(undefined);
|
|
297
323
|
}
|
|
324
|
+
const actionList = JSON.stringify(path.map(step => step.action));
|
|
325
|
+
const swapXcm = actionList === JSON.stringify([DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
|
|
326
|
+
const sendingValue = swapXcm ? BigNumber(request.fromAmount).multipliedBy(DEFAULT_EXCESS_AMOUNT_WEIGHT).toFixed(0, 1) : request.fromAmount;
|
|
327
|
+
const expectedReceive = swapXcm ? BigNumber(selectedQuote.toAmount).multipliedBy(DEFAULT_EXCESS_AMOUNT_WEIGHT).toFixed(0, 1) : selectedQuote.toAmount;
|
|
298
328
|
const originTokenInfo = this.chainService.getAssetBySlug(selectedQuote.pair.from);
|
|
299
329
|
const destinationTokenInfo = this.chainService.getAssetBySlug(selectedQuote.pair.to);
|
|
300
330
|
const originChain = this.chainService.getChainInfoByKey(originTokenInfo.originChain);
|
|
@@ -304,8 +334,8 @@ export class UniswapHandler {
|
|
|
304
334
|
type: SwapStepType.SWAP,
|
|
305
335
|
// @ts-ignore
|
|
306
336
|
metadata: {
|
|
307
|
-
sendingValue
|
|
308
|
-
expectedReceive
|
|
337
|
+
sendingValue,
|
|
338
|
+
expectedReceive,
|
|
309
339
|
originTokenInfo,
|
|
310
340
|
destinationTokenInfo,
|
|
311
341
|
sender: _reformatAddressWithChain(request.address, originChain),
|
|
@@ -321,6 +351,20 @@ export class UniswapHandler {
|
|
|
321
351
|
request,
|
|
322
352
|
selectedQuote
|
|
323
353
|
} = params;
|
|
354
|
+
/**
|
|
355
|
+
* Explain: All processes will go through one of below processes. If a step do not have, it returns undefined and
|
|
356
|
+
* the stepIndex is still counted up
|
|
357
|
+
*
|
|
358
|
+
* Processes:
|
|
359
|
+
* approve - permit - swap or
|
|
360
|
+
* approve - permit - swap - approve - bridge or
|
|
361
|
+
* approve - bridge - approve - permit - swap
|
|
362
|
+
*/
|
|
363
|
+
const actionList = JSON.stringify(path.map(step => step.action));
|
|
364
|
+
const bridgeSwap = actionList === JSON.stringify([DynamicSwapType.BRIDGE, DynamicSwapType.SWAP]);
|
|
365
|
+
const swapBridge = actionList === JSON.stringify([DynamicSwapType.SWAP, DynamicSwapType.BRIDGE]);
|
|
366
|
+
const isBridgeFirst = stepIndex === 1 && bridgeSwap;
|
|
367
|
+
const isBridgeSecond = stepIndex === 4 && swapBridge;
|
|
324
368
|
|
|
325
369
|
// stepIndex is not corresponding index in path, because uniswap include approval and permit step
|
|
326
370
|
const bridgePairInfo = path.find(action => action.action === DynamicSwapType.BRIDGE);
|
|
@@ -337,9 +381,18 @@ export class UniswapHandler {
|
|
|
337
381
|
if (!fromChainInfo || !toChainInfo || !fromChainInfo || !toChainInfo) {
|
|
338
382
|
throw Error('Token or chain not found');
|
|
339
383
|
}
|
|
384
|
+
let receiverAddress;
|
|
385
|
+
let mockSendingValue;
|
|
340
386
|
const senderAddress = _reformatAddressWithChain(request.address, fromChainInfo);
|
|
341
|
-
|
|
342
|
-
|
|
387
|
+
if (isBridgeFirst) {
|
|
388
|
+
receiverAddress = _reformatAddressWithChain(request.address, toChainInfo);
|
|
389
|
+
mockSendingValue = BigNumber(selectedQuote.fromAmount).toFixed(0, 1);
|
|
390
|
+
} else if (isBridgeSecond) {
|
|
391
|
+
receiverAddress = _reformatAddressWithChain(request.recipient || request.address, toChainInfo);
|
|
392
|
+
mockSendingValue = BigNumber(selectedQuote.toAmount).toFixed(0, 1);
|
|
393
|
+
} else {
|
|
394
|
+
return undefined;
|
|
395
|
+
}
|
|
343
396
|
try {
|
|
344
397
|
const evmApi = await this.chainService.getEvmApi(fromChainInfo.slug).isReady;
|
|
345
398
|
const feeInfo = await this.feeService.subscribeChainFee(getId(), fromTokenInfo.originChain, 'evm');
|
|
@@ -351,25 +404,37 @@ export class UniswapHandler {
|
|
|
351
404
|
evmApi,
|
|
352
405
|
feeInfo,
|
|
353
406
|
// Mock sending value to get payment info
|
|
354
|
-
sendingValue,
|
|
407
|
+
sendingValue: mockSendingValue,
|
|
355
408
|
sender: senderAddress,
|
|
356
409
|
recipient: receiverAddress
|
|
357
410
|
});
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
// });
|
|
370
|
-
|
|
411
|
+
const acrossQuote = await getAcrossQuote({
|
|
412
|
+
destinationChain: toChainInfo,
|
|
413
|
+
destinationTokenInfo: toTokenInfo,
|
|
414
|
+
originChain: fromChainInfo,
|
|
415
|
+
originTokenInfo: fromTokenInfo,
|
|
416
|
+
recipient: receiverAddress,
|
|
417
|
+
sender: senderAddress,
|
|
418
|
+
sendingValue: mockSendingValue,
|
|
419
|
+
feeInfo
|
|
420
|
+
});
|
|
421
|
+
const acrossQuoteMetadata = acrossQuote.metadata;
|
|
371
422
|
const estimatedBridgeFee = await estimateTxFee(tx, evmApi, feeInfo);
|
|
372
|
-
const
|
|
423
|
+
const estimatedDestinationFee = BigNumber(mockSendingValue).minus(acrossQuoteMetadata.outputAmount).toFixed(0, 1); // todo: should better handle on backend and return desFee metadata instead of minus like this
|
|
424
|
+
|
|
425
|
+
let sendingValue;
|
|
426
|
+
let expectedReceive;
|
|
427
|
+
if (isBridgeFirst) {
|
|
428
|
+
expectedReceive = selectedQuote.fromAmount;
|
|
429
|
+
sendingValue = BigNumber(estimatedDestinationFee).multipliedBy(FEE_RATE_MULTIPLIER.medium).plus(selectedQuote.fromAmount).toFixed(0, 1);
|
|
430
|
+
} else if (isBridgeSecond) {
|
|
431
|
+
expectedReceive = selectedQuote.toAmount;
|
|
432
|
+
sendingValue = BigNumber(selectedQuote.toAmount).multipliedBy(DEFAULT_EXCESS_AMOUNT_WEIGHT).toFixed(0, 1);
|
|
433
|
+
} else {
|
|
434
|
+
return undefined;
|
|
435
|
+
}
|
|
436
|
+
console.log('[i] estimatedBridgeFee', estimatedBridgeFee);
|
|
437
|
+
console.log('[i] estimatedDestinationFee', estimatedDestinationFee);
|
|
373
438
|
const fee = {
|
|
374
439
|
feeComponent: [{
|
|
375
440
|
feeType: SwapFeeType.NETWORK_FEE,
|
|
@@ -738,7 +803,7 @@ export class UniswapHandler {
|
|
|
738
803
|
if (swapIndex <= -1) {
|
|
739
804
|
return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
|
|
740
805
|
}
|
|
741
|
-
if (swapXcm && bridgeIndex <= -1) {
|
|
806
|
+
if ((swapXcm || xcmSwap) && bridgeIndex <= -1) {
|
|
742
807
|
return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
|
|
743
808
|
}
|
|
744
809
|
if (swap) {
|
|
@@ -749,7 +814,7 @@ export class UniswapHandler {
|
|
|
749
814
|
return this.swapBaseHandler.validateSwapXcmProcess(params, swapIndex, bridgeIndex);
|
|
750
815
|
}
|
|
751
816
|
if (xcmSwap) {
|
|
752
|
-
return
|
|
817
|
+
return this.swapBaseHandler.validateXcmSwapProcess(params, swapIndex, bridgeIndex);
|
|
753
818
|
}
|
|
754
819
|
if (xcmSwapXcm) {
|
|
755
820
|
return [new TransactionError(BasicTxErrorType.INTERNAL_ERROR)];
|