@lifi/sdk 2.2.3 → 3.0.0-alpha.2
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/dist/LiFi.d.ts +69 -62
- package/dist/LiFi.js +71 -60
- package/dist/allowance/getAllowance.d.ts +6 -0
- package/dist/allowance/getAllowance.js +78 -0
- package/dist/allowance/index.d.ts +3 -2
- package/dist/allowance/index.js +3 -2
- package/dist/allowance/setAllowance.d.ts +5 -0
- package/dist/allowance/setAllowance.js +50 -0
- package/dist/allowance/types.d.ts +27 -0
- package/dist/allowance/types.js +1 -0
- package/dist/balance/getBalance.d.ts +2 -0
- package/dist/balance/getBalance.js +93 -0
- package/dist/balance/getTokenBalance.d.ts +2 -2
- package/dist/balance/getTokenBalance.js +4 -4
- package/dist/balance/index.d.ts +1 -12
- package/dist/balance/index.js +1 -9
- package/dist/cjs/LiFi.d.ts +69 -62
- package/dist/cjs/LiFi.js +69 -58
- package/dist/cjs/allowance/getAllowance.d.ts +6 -0
- package/dist/cjs/allowance/getAllowance.js +85 -0
- package/dist/cjs/allowance/index.d.ts +3 -2
- package/dist/cjs/allowance/index.js +3 -2
- package/dist/cjs/allowance/setAllowance.d.ts +5 -0
- package/dist/cjs/allowance/setAllowance.js +56 -0
- package/dist/cjs/allowance/types.d.ts +27 -0
- package/dist/cjs/allowance/types.js +2 -0
- package/dist/cjs/balance/getBalance.d.ts +2 -0
- package/dist/cjs/balance/getBalance.js +97 -0
- package/dist/cjs/balance/getTokenBalance.d.ts +2 -2
- package/dist/cjs/balance/getTokenBalance.js +6 -9
- package/dist/cjs/balance/index.d.ts +1 -12
- package/dist/cjs/balance/index.js +1 -9
- package/dist/cjs/connectors.d.ts +7 -5
- package/dist/cjs/connectors.js +45 -37
- package/dist/cjs/constants.d.ts +6 -0
- package/dist/cjs/constants.js +9 -0
- package/dist/cjs/execution/RouteExecutionManager.d.ts +24 -30
- package/dist/cjs/execution/RouteExecutionManager.js +27 -45
- package/dist/cjs/execution/StatusManager.d.ts +22 -23
- package/dist/cjs/execution/StatusManager.js +21 -22
- package/dist/cjs/execution/StepExecutionManager.d.ts +3 -3
- package/dist/cjs/execution/StepExecutionManager.js +118 -125
- package/dist/cjs/execution/StepExecutor.d.ts +4 -4
- package/dist/cjs/execution/StepExecutor.js +6 -6
- package/dist/cjs/execution/checkAllowance.d.ts +4 -0
- package/dist/cjs/execution/checkAllowance.js +77 -0
- package/dist/cjs/execution/checkBalance.d.ts +2 -0
- package/dist/cjs/execution/checkBalance.js +42 -0
- package/dist/cjs/execution/multisig.d.ts +4 -3
- package/dist/cjs/execution/multisig.js +9 -11
- package/dist/cjs/execution/prepareRestart.d.ts +3 -0
- package/dist/cjs/execution/prepareRestart.js +65 -0
- package/dist/cjs/execution/stepComparison.d.ts +3 -3
- package/dist/cjs/execution/stepComparison.js +2 -2
- package/dist/cjs/execution/switchChain.d.ts +13 -8
- package/dist/cjs/execution/switchChain.js +16 -11
- package/dist/cjs/execution/utils.d.ts +9 -3
- package/dist/cjs/execution/utils.js +19 -66
- package/dist/cjs/execution/waitForReceivingTransaction.d.ts +3 -0
- package/dist/cjs/execution/waitForReceivingTransaction.js +58 -0
- package/dist/cjs/helpers.d.ts +7 -17
- package/dist/cjs/helpers.js +6 -38
- package/dist/cjs/request.js +1 -1
- package/dist/cjs/services/ApiService.d.ts +2 -2
- package/dist/cjs/services/ApiService.js +4 -2
- package/dist/cjs/services/ChainsService.d.ts +1 -1
- package/dist/cjs/services/ConfigService.d.ts +1 -1
- package/dist/cjs/services/ConfigService.js +1 -2
- package/dist/cjs/typeguards.d.ts +1 -1
- package/dist/cjs/types/abi.d.ts +5 -0
- package/dist/cjs/types/abi.js +45 -0
- package/dist/cjs/types/index.d.ts +2 -2
- package/dist/cjs/types/index.js +3 -3
- package/dist/cjs/types/internal.types.d.ts +24 -31
- package/dist/cjs/utils/errors.d.ts +15 -14
- package/dist/cjs/utils/errors.js +38 -37
- package/dist/cjs/utils/getMaxPriorityFeePerGas.d.ts +2 -0
- package/dist/cjs/utils/getMaxPriorityFeePerGas.js +22 -0
- package/dist/cjs/utils/index.d.ts +5 -0
- package/dist/cjs/utils/index.js +21 -0
- package/dist/cjs/utils/median.d.ts +1 -0
- package/dist/cjs/utils/median.js +15 -0
- package/dist/cjs/utils/parseError.d.ts +4 -4
- package/dist/cjs/utils/parseError.js +41 -38
- package/dist/cjs/utils/utils.d.ts +1 -16
- package/dist/cjs/utils/utils.js +9 -78
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/connectors.d.ts +7 -5
- package/dist/connectors.js +19 -35
- package/dist/constants.d.ts +6 -0
- package/dist/constants.js +6 -0
- package/dist/execution/RouteExecutionManager.d.ts +24 -30
- package/dist/execution/RouteExecutionManager.js +27 -45
- package/dist/execution/StatusManager.d.ts +22 -23
- package/dist/execution/StatusManager.js +22 -23
- package/dist/execution/StepExecutionManager.d.ts +3 -3
- package/dist/execution/StepExecutionManager.js +116 -123
- package/dist/execution/StepExecutor.d.ts +4 -4
- package/dist/execution/StepExecutor.js +6 -6
- package/dist/execution/checkAllowance.d.ts +4 -0
- package/dist/execution/checkAllowance.js +73 -0
- package/dist/execution/checkBalance.d.ts +2 -0
- package/dist/execution/checkBalance.js +38 -0
- package/dist/execution/multisig.d.ts +4 -3
- package/dist/execution/multisig.js +10 -12
- package/dist/execution/prepareRestart.d.ts +3 -0
- package/dist/execution/prepareRestart.js +61 -0
- package/dist/execution/stepComparison.d.ts +3 -3
- package/dist/execution/stepComparison.js +3 -3
- package/dist/execution/switchChain.d.ts +13 -8
- package/dist/execution/switchChain.js +17 -12
- package/dist/execution/utils.d.ts +9 -3
- package/dist/execution/utils.js +18 -61
- package/dist/execution/waitForReceivingTransaction.d.ts +3 -0
- package/dist/execution/waitForReceivingTransaction.js +51 -0
- package/dist/helpers.d.ts +7 -17
- package/dist/helpers.js +5 -34
- package/dist/request.js +2 -2
- package/dist/services/ApiService.d.ts +2 -2
- package/dist/services/ApiService.js +4 -2
- package/dist/services/ChainsService.d.ts +1 -1
- package/dist/services/ConfigService.d.ts +1 -1
- package/dist/services/ConfigService.js +2 -3
- package/dist/typeguards.d.ts +1 -1
- package/dist/types/abi.d.ts +5 -0
- package/dist/types/abi.js +42 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +2 -2
- package/dist/types/internal.types.d.ts +24 -31
- package/dist/utils/errors.d.ts +15 -14
- package/dist/utils/errors.js +36 -35
- package/dist/utils/getMaxPriorityFeePerGas.d.ts +2 -0
- package/dist/utils/getMaxPriorityFeePerGas.js +18 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.js +5 -0
- package/dist/utils/median.d.ts +1 -0
- package/dist/utils/median.js +11 -0
- package/dist/utils/parseError.d.ts +4 -4
- package/dist/utils/parseError.js +42 -39
- package/dist/utils/utils.d.ts +1 -16
- package/dist/utils/utils.js +7 -69
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +43 -40
- package/dist/allowance/checkAllowance.d.ts +0 -4
- package/dist/allowance/checkAllowance.js +0 -96
- package/dist/allowance/tokenApproval.d.ts +0 -22
- package/dist/allowance/tokenApproval.js +0 -59
- package/dist/allowance/utils.d.ts +0 -15
- package/dist/allowance/utils.js +0 -77
- package/dist/balance/checkBalance.d.ts +0 -3
- package/dist/balance/checkBalance.js +0 -38
- package/dist/balance/utils.d.ts +0 -6
- package/dist/balance/utils.js +0 -143
- package/dist/cjs/allowance/checkAllowance.d.ts +0 -4
- package/dist/cjs/allowance/checkAllowance.js +0 -103
- package/dist/cjs/allowance/tokenApproval.d.ts +0 -22
- package/dist/cjs/allowance/tokenApproval.js +0 -69
- package/dist/cjs/allowance/utils.d.ts +0 -15
- package/dist/cjs/allowance/utils.js +0 -87
- package/dist/cjs/balance/checkBalance.d.ts +0 -3
- package/dist/cjs/balance/checkBalance.js +0 -45
- package/dist/cjs/balance/utils.d.ts +0 -6
- package/dist/cjs/balance/utils.js +0 -150
- package/dist/cjs/types/ERC20.d.ts +0 -22
- package/dist/cjs/types/ERC20.js +0 -53
- package/dist/cjs/utils/getProvider.d.ts +0 -3
- package/dist/cjs/utils/getProvider.js +0 -11
- package/dist/cjs/utils/multicall.d.ts +0 -10
- package/dist/cjs/utils/multicall.js +0 -68
- package/dist/cjs/utils/multicallAbi.json +0 -313
- package/dist/cjs/utils/preRestart.d.ts +0 -3
- package/dist/cjs/utils/preRestart.js +0 -56
- package/dist/types/ERC20.d.ts +0 -22
- package/dist/types/ERC20.js +0 -50
- package/dist/utils/getProvider.d.ts +0 -3
- package/dist/utils/getProvider.js +0 -7
- package/dist/utils/multicall.d.ts +0 -10
- package/dist/utils/multicall.js +0 -61
- package/dist/utils/multicallAbi.json +0 -313
- package/dist/utils/preRestart.d.ts +0 -3
- package/dist/utils/preRestart.js +0 -52
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Execution } from '@lifi/types';
|
|
2
|
-
import { ExecutionParams } from '../types';
|
|
1
|
+
import type { Execution } from '@lifi/types';
|
|
2
|
+
import type { ExecutionParams } from '../types';
|
|
3
3
|
export declare class StepExecutionManager {
|
|
4
4
|
allowUserInteraction: boolean;
|
|
5
5
|
allowInteraction: (value: boolean) => void;
|
|
6
|
-
execute: ({
|
|
6
|
+
execute: ({ walletClient, step, statusManager, settings, }: ExecutionParams) => Promise<Execution>;
|
|
7
7
|
}
|
|
@@ -1,29 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { checkAllowance } from '../allowance';
|
|
3
|
-
import { checkBalance } from '../balance';
|
|
1
|
+
import { publicActions } from 'viem';
|
|
4
2
|
import ApiService from '../services/ApiService';
|
|
5
3
|
import ChainsService from '../services/ChainsService';
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
4
|
+
import ConfigService from '../services/ConfigService';
|
|
5
|
+
import { getMaxPriorityFeePerGas } from '../utils';
|
|
6
|
+
import { LiFiErrorCode, TransactionError, ValidationError, } from '../utils/errors';
|
|
8
7
|
import { getTransactionFailedMessage, parseError } from '../utils/parseError';
|
|
9
|
-
import { isZeroAddress
|
|
8
|
+
import { isZeroAddress } from '../utils/utils';
|
|
9
|
+
import { checkAllowance } from './checkAllowance';
|
|
10
|
+
import { checkBalance } from './checkBalance';
|
|
11
|
+
import { updateMultisigRouteProcess } from './multisig';
|
|
10
12
|
import { stepComparison } from './stepComparison';
|
|
11
13
|
import { switchChain } from './switchChain';
|
|
12
|
-
import { getSubstatusMessage
|
|
13
|
-
import
|
|
14
|
-
import { updateMultisigRouteProcess } from './multisig';
|
|
14
|
+
import { getSubstatusMessage } from './utils';
|
|
15
|
+
import { waitForReceivingTransaction } from './waitForReceivingTransaction';
|
|
15
16
|
export class StepExecutionManager {
|
|
16
17
|
constructor() {
|
|
17
18
|
this.allowUserInteraction = true;
|
|
18
19
|
this.allowInteraction = (value) => {
|
|
19
20
|
this.allowUserInteraction = value;
|
|
20
21
|
};
|
|
21
|
-
this.execute = async ({
|
|
22
|
+
this.execute = async ({ walletClient, step, statusManager, settings, }) => {
|
|
23
|
+
const client = walletClient.extend(publicActions);
|
|
22
24
|
const config = ConfigService.getInstance().getConfig();
|
|
23
|
-
const
|
|
25
|
+
const isMultisigWalletClient = !!config.multisig?.isMultisigWalletClient;
|
|
24
26
|
const multisigBatchTransactions = [];
|
|
25
|
-
const shouldBatchTransactions = config.
|
|
26
|
-
!!config.
|
|
27
|
+
const shouldBatchTransactions = config.multisig?.shouldBatchTransactions &&
|
|
28
|
+
!!config.multisig.sendBatchTransaction;
|
|
27
29
|
step.execution = statusManager.initExecutionObject(step);
|
|
28
30
|
const chainsService = ChainsService.getInstance();
|
|
29
31
|
const fromChain = await chainsService.getChainById(step.action.fromChainId);
|
|
@@ -35,20 +37,16 @@ export class StepExecutionManager {
|
|
|
35
37
|
// Check token approval only if fromToken is not the native token => no approval needed in that case
|
|
36
38
|
const checkForAllowance = !existingProcess?.txHash &&
|
|
37
39
|
!isZeroAddress(step.action.fromToken.address) &&
|
|
38
|
-
(shouldBatchTransactions || !
|
|
40
|
+
(shouldBatchTransactions || !isMultisigWalletClient);
|
|
39
41
|
if (checkForAllowance) {
|
|
40
|
-
const
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
data,
|
|
49
|
-
};
|
|
50
|
-
multisigBatchTransactions.push(cleanedPopulatedTransaction);
|
|
51
|
-
}
|
|
42
|
+
const data = await checkAllowance(client, step, statusManager, settings, fromChain, this.allowUserInteraction, shouldBatchTransactions);
|
|
43
|
+
if (data) {
|
|
44
|
+
// allowance doesn't need value
|
|
45
|
+
const baseTransaction = {
|
|
46
|
+
to: step.action.fromToken.address,
|
|
47
|
+
data,
|
|
48
|
+
};
|
|
49
|
+
multisigBatchTransactions.push(baseTransaction);
|
|
52
50
|
}
|
|
53
51
|
}
|
|
54
52
|
// STEP 2: Get transaction
|
|
@@ -56,136 +54,143 @@ export class StepExecutionManager {
|
|
|
56
54
|
if (process.status !== 'DONE') {
|
|
57
55
|
const multisigProcess = step.execution.process.find((p) => !!p.multisigTxHash);
|
|
58
56
|
try {
|
|
59
|
-
if (
|
|
60
|
-
if (!multisigProcess) {
|
|
61
|
-
throw new ValidationError('Multisig process is undefined.');
|
|
62
|
-
}
|
|
63
|
-
if (!config.multisigConfig?.getMultisigTransactionDetails) {
|
|
64
|
-
throw new ValidationError('"getMultisigTransactionDetails()" is missing in Multisig config.');
|
|
65
|
-
}
|
|
57
|
+
if (isMultisigWalletClient && multisigProcess) {
|
|
66
58
|
const multisigTxHash = multisigProcess.multisigTxHash;
|
|
67
59
|
if (!multisigTxHash) {
|
|
68
|
-
// need to check what happens in failed tx
|
|
69
60
|
throw new ValidationError('Multisig internal transaction hash is undefined.');
|
|
70
61
|
}
|
|
71
|
-
await updateMultisigRouteProcess(multisigTxHash, step, statusManager, process, fromChain);
|
|
62
|
+
await updateMultisigRouteProcess(multisigTxHash, step, statusManager, process.type, fromChain);
|
|
72
63
|
}
|
|
73
|
-
let
|
|
64
|
+
let txHash;
|
|
74
65
|
if (process.txHash) {
|
|
75
66
|
// Make sure that the chain is still correct
|
|
76
|
-
const
|
|
77
|
-
if (!
|
|
67
|
+
const updatedWalletClient = await switchChain(walletClient, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
|
|
68
|
+
if (!updatedWalletClient) {
|
|
78
69
|
// Chain switch was not successful, stop execution here
|
|
79
70
|
return step.execution;
|
|
80
71
|
}
|
|
81
|
-
|
|
72
|
+
walletClient = updatedWalletClient;
|
|
82
73
|
// Load exiting transaction
|
|
83
|
-
|
|
74
|
+
txHash = process.txHash;
|
|
84
75
|
}
|
|
85
76
|
else {
|
|
86
77
|
process = statusManager.updateProcess(step, process.type, 'STARTED');
|
|
87
78
|
// Check balance
|
|
88
|
-
await checkBalance(
|
|
79
|
+
await checkBalance(client.account.address, step);
|
|
89
80
|
// Create new transaction
|
|
90
81
|
if (!step.transactionRequest) {
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
const comparedStep = await stepComparison(statusManager, personalizedStep, updatedStep, settings, this.allowUserInteraction);
|
|
82
|
+
const updatedStep = await ApiService.getStepTransaction(step);
|
|
83
|
+
const comparedStep = await stepComparison(statusManager, step, updatedStep, settings, this.allowUserInteraction);
|
|
94
84
|
step = {
|
|
95
85
|
...comparedStep,
|
|
96
86
|
execution: step.execution,
|
|
97
87
|
};
|
|
98
88
|
}
|
|
99
|
-
|
|
89
|
+
let transactionRequest = {
|
|
90
|
+
to: step.transactionRequest?.to,
|
|
91
|
+
from: step.transactionRequest?.from,
|
|
92
|
+
data: step.transactionRequest?.data,
|
|
93
|
+
value: step.transactionRequest?.value
|
|
94
|
+
? BigInt(step.transactionRequest.value)
|
|
95
|
+
: undefined,
|
|
96
|
+
maxPriorityFeePerGas: walletClient.account?.type === 'local'
|
|
97
|
+
? await getMaxPriorityFeePerGas(client)
|
|
98
|
+
: undefined,
|
|
99
|
+
// gas: step.transactionRequest?.gasLimit
|
|
100
|
+
// ? BigInt(step.transactionRequest.gasLimit as string)
|
|
101
|
+
// : undefined,
|
|
102
|
+
// gasPrice: step.transactionRequest?.gasPrice
|
|
103
|
+
// ? BigInt(step.transactionRequest.gasPrice as string)
|
|
104
|
+
// : undefined,
|
|
105
|
+
// maxFeePerGas: step.transactionRequest?.maxFeePerGas
|
|
106
|
+
// ? BigInt(step.transactionRequest.maxFeePerGas as string)
|
|
107
|
+
// : undefined,
|
|
108
|
+
// maxPriorityFeePerGas: step.transactionRequest?.maxPriorityFeePerGas
|
|
109
|
+
// ? BigInt(step.transactionRequest.maxPriorityFeePerGas as string)
|
|
110
|
+
// : undefined,
|
|
111
|
+
};
|
|
100
112
|
if (!transactionRequest) {
|
|
101
|
-
throw new TransactionError(
|
|
113
|
+
throw new TransactionError(LiFiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
|
|
102
114
|
}
|
|
103
115
|
// STEP 3: Send the transaction
|
|
104
116
|
// Make sure that the chain is still correct
|
|
105
|
-
const
|
|
106
|
-
if (!
|
|
117
|
+
const updatedWalletClient = await switchChain(walletClient, statusManager, step, settings.switchChainHook, this.allowUserInteraction);
|
|
118
|
+
if (!updatedWalletClient) {
|
|
107
119
|
// Chain switch was not successful, stop execution here
|
|
108
120
|
return step.execution;
|
|
109
121
|
}
|
|
110
|
-
|
|
122
|
+
walletClient = updatedWalletClient;
|
|
111
123
|
process = statusManager.updateProcess(step, process.type, 'ACTION_REQUIRED');
|
|
112
124
|
if (!this.allowUserInteraction) {
|
|
113
125
|
return step.execution;
|
|
114
126
|
}
|
|
115
127
|
if (settings.updateTransactionRequestHook) {
|
|
116
|
-
const
|
|
117
|
-
transactionRequest
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
transactionRequest.maxFeePerGas = customConfig.maxFeePerGas;
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
try {
|
|
125
|
-
const estimatedGasLimit = await signer.estimateGas(transactionRequest);
|
|
126
|
-
if (estimatedGasLimit) {
|
|
127
|
-
transactionRequest.gasLimit = BigNumber.from(`${(BigInt(estimatedGasLimit.toString()) * 125n) / 100n}`);
|
|
128
|
-
}
|
|
129
|
-
// Fetch latest gasPrice from provider and use it
|
|
130
|
-
const gasPrice = await signer.getGasPrice();
|
|
131
|
-
if (gasPrice) {
|
|
132
|
-
transactionRequest.gasPrice = gasPrice;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
catch (error) { }
|
|
128
|
+
const customizedTransactionRequest = await settings.updateTransactionRequestHook(transactionRequest);
|
|
129
|
+
transactionRequest = {
|
|
130
|
+
...transactionRequest,
|
|
131
|
+
...customizedTransactionRequest,
|
|
132
|
+
};
|
|
136
133
|
}
|
|
137
|
-
// Submit the transaction
|
|
138
134
|
if (shouldBatchTransactions &&
|
|
139
|
-
config.
|
|
140
|
-
|
|
141
|
-
const isValidTransaction = to && data;
|
|
142
|
-
if (isValidTransaction) {
|
|
135
|
+
config.multisig?.sendBatchTransaction) {
|
|
136
|
+
if (transactionRequest.to && transactionRequest.data) {
|
|
143
137
|
const populatedTransaction = {
|
|
144
|
-
value: value
|
|
145
|
-
to,
|
|
146
|
-
data: data
|
|
138
|
+
value: transactionRequest.value,
|
|
139
|
+
to: transactionRequest.to,
|
|
140
|
+
data: transactionRequest.data,
|
|
147
141
|
};
|
|
148
142
|
multisigBatchTransactions.push(populatedTransaction);
|
|
149
|
-
|
|
143
|
+
txHash = await config.multisig?.sendBatchTransaction(multisigBatchTransactions);
|
|
150
144
|
}
|
|
151
145
|
else {
|
|
152
|
-
throw new TransactionError(
|
|
146
|
+
throw new TransactionError(LiFiErrorCode.TransactionUnprepared, 'Unable to prepare transaction.');
|
|
153
147
|
}
|
|
154
148
|
}
|
|
155
149
|
else {
|
|
156
|
-
|
|
150
|
+
txHash = await walletClient.sendTransaction({
|
|
151
|
+
to: transactionRequest.to,
|
|
152
|
+
account: walletClient.account,
|
|
153
|
+
data: transactionRequest.data,
|
|
154
|
+
maxPriorityFeePerGas: transactionRequest.maxPriorityFeePerGas,
|
|
155
|
+
chain: null,
|
|
156
|
+
});
|
|
157
157
|
}
|
|
158
158
|
// STEP 4: Wait for the transaction
|
|
159
|
-
if (
|
|
159
|
+
if (isMultisigWalletClient) {
|
|
160
160
|
process = statusManager.updateProcess(step, process.type, 'ACTION_REQUIRED', {
|
|
161
|
-
multisigTxHash:
|
|
161
|
+
multisigTxHash: txHash,
|
|
162
162
|
});
|
|
163
163
|
}
|
|
164
164
|
else {
|
|
165
165
|
process = statusManager.updateProcess(step, process.type, 'PENDING', {
|
|
166
|
-
txHash:
|
|
167
|
-
txLink: fromChain.metamask.blockExplorerUrls[0]
|
|
168
|
-
'tx/' +
|
|
169
|
-
transaction.hash,
|
|
166
|
+
txHash: txHash,
|
|
167
|
+
txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${txHash}`,
|
|
170
168
|
});
|
|
171
169
|
}
|
|
172
170
|
}
|
|
173
|
-
|
|
174
|
-
|
|
171
|
+
let replacementReason;
|
|
172
|
+
const transactionReceipt = await client.waitForTransactionReceipt({
|
|
173
|
+
hash: txHash,
|
|
174
|
+
onReplaced(response) {
|
|
175
|
+
replacementReason = response.reason;
|
|
176
|
+
statusManager.updateProcess(step, process.type, 'PENDING', {
|
|
177
|
+
txHash: response.transaction.hash,
|
|
178
|
+
txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${response.transaction.hash}`,
|
|
179
|
+
});
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
if (replacementReason === 'cancelled') {
|
|
183
|
+
throw new TransactionError(LiFiErrorCode.TransactionCanceled, 'User canceled transaction.');
|
|
184
|
+
}
|
|
185
|
+
// if it's multisig wallet client and the process is in ACTION_REQUIRED
|
|
175
186
|
// then signatures are still needed
|
|
176
|
-
if (
|
|
177
|
-
|
|
178
|
-
transaction.hash) {
|
|
179
|
-
// Return the execution object without updating the process
|
|
180
|
-
// The execution would progress once all multisigs signer approve
|
|
181
|
-
await updateMultisigRouteProcess(transaction.hash, step, statusManager, process, fromChain);
|
|
187
|
+
if (isMultisigWalletClient && process.status === 'ACTION_REQUIRED') {
|
|
188
|
+
await updateMultisigRouteProcess(transactionReceipt.transactionHash, step, statusManager, process.type, fromChain);
|
|
182
189
|
}
|
|
183
|
-
if (!
|
|
190
|
+
if (!isMultisigWalletClient) {
|
|
184
191
|
process = statusManager.updateProcess(step, process.type, 'PENDING', {
|
|
185
|
-
txHash:
|
|
186
|
-
txLink: fromChain.metamask.blockExplorerUrls[0]
|
|
187
|
-
'tx/' +
|
|
188
|
-
transaction.hash,
|
|
192
|
+
txHash: transactionReceipt.transactionHash,
|
|
193
|
+
txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${transactionReceipt.transactionHash}`,
|
|
189
194
|
});
|
|
190
195
|
}
|
|
191
196
|
if (isBridgeExecution) {
|
|
@@ -193,26 +198,16 @@ export class StepExecutionManager {
|
|
|
193
198
|
}
|
|
194
199
|
}
|
|
195
200
|
catch (e) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
process = statusManager.updateProcess(step, process.type, 'FAILED', {
|
|
207
|
-
error: {
|
|
208
|
-
message: error.message,
|
|
209
|
-
htmlMessage: error.htmlMessage,
|
|
210
|
-
code: error.code,
|
|
211
|
-
},
|
|
212
|
-
});
|
|
213
|
-
statusManager.updateExecution(step, 'FAILED');
|
|
214
|
-
throw error;
|
|
215
|
-
}
|
|
201
|
+
const error = await parseError(e, step, process);
|
|
202
|
+
process = statusManager.updateProcess(step, process.type, 'FAILED', {
|
|
203
|
+
error: {
|
|
204
|
+
message: error.message,
|
|
205
|
+
htmlMessage: error.htmlMessage,
|
|
206
|
+
code: error.code,
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
statusManager.updateExecution(step, 'FAILED');
|
|
210
|
+
throw error;
|
|
216
211
|
}
|
|
217
212
|
}
|
|
218
213
|
// STEP 5: Wait for the receiving chain
|
|
@@ -232,9 +227,7 @@ export class StepExecutionManager {
|
|
|
232
227
|
substatusMessage: statusResponse.substatusMessage ||
|
|
233
228
|
getSubstatusMessage(statusResponse.status, statusResponse.substatus),
|
|
234
229
|
txHash: statusReceiving?.txHash,
|
|
235
|
-
txLink: toChain.metamask.blockExplorerUrls[0]
|
|
236
|
-
'tx/' +
|
|
237
|
-
statusReceiving?.txHash,
|
|
230
|
+
txLink: `${toChain.metamask.blockExplorerUrls[0]}tx/${statusReceiving?.txHash}`,
|
|
238
231
|
});
|
|
239
232
|
statusManager.updateExecution(step, 'DONE', {
|
|
240
233
|
fromAmount: statusResponse.sending.amount,
|
|
@@ -251,7 +244,7 @@ export class StepExecutionManager {
|
|
|
251
244
|
const htmlMessage = await getTransactionFailedMessage(step, process.txLink);
|
|
252
245
|
process = statusManager.updateProcess(step, process.type, 'FAILED', {
|
|
253
246
|
error: {
|
|
254
|
-
code:
|
|
247
|
+
code: LiFiErrorCode.TransactionFailed,
|
|
255
248
|
message: 'Failed while waiting for receiving chain.',
|
|
256
249
|
htmlMessage,
|
|
257
250
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { InteractionSettings, InternalExecutionSettings, LifiStep } from '../types';
|
|
3
|
-
import { StatusManager } from './StatusManager';
|
|
1
|
+
import type { WalletClient } from 'viem';
|
|
2
|
+
import type { InteractionSettings, InternalExecutionSettings, LifiStep } from '../types';
|
|
3
|
+
import type { StatusManager } from './StatusManager';
|
|
4
4
|
import { StepExecutionManager } from './StepExecutionManager';
|
|
5
5
|
export declare class StepExecutor {
|
|
6
6
|
stepExecutionManager: StepExecutionManager;
|
|
@@ -11,5 +11,5 @@ export declare class StepExecutor {
|
|
|
11
11
|
constructor(statusManager: StatusManager, settings: InternalExecutionSettings);
|
|
12
12
|
setInteraction: (settings?: InteractionSettings) => void;
|
|
13
13
|
checkChain: () => never;
|
|
14
|
-
executeStep: (
|
|
14
|
+
executeStep: (walletClient: WalletClient, step: LifiStep) => Promise<LifiStep>;
|
|
15
15
|
}
|
|
@@ -20,13 +20,13 @@ export class StepExecutor {
|
|
|
20
20
|
this.statusManager.allowUpdates(interactionSettings.allowUpdates);
|
|
21
21
|
this.executionStopped = interactionSettings.stopExecution;
|
|
22
22
|
};
|
|
23
|
-
// TODO: add checkChain method and update
|
|
23
|
+
// TODO: add checkChain method and update wallet client inside executors
|
|
24
24
|
// This can come in handy when we execute multiple routes simultaneously and
|
|
25
25
|
// should be sure that we are on the right chain when waiting for transactions.
|
|
26
26
|
this.checkChain = () => {
|
|
27
27
|
throw new Error('checkChain is not implemented.');
|
|
28
28
|
};
|
|
29
|
-
this.executeStep = async (
|
|
29
|
+
this.executeStep = async (walletClient, step) => {
|
|
30
30
|
// Make sure that the chain is still correct
|
|
31
31
|
// Find if it's bridging and the step is waiting for a transaction on the receiving chain
|
|
32
32
|
const recievingChainProcess = step.execution?.process.find((process) => process.type === 'RECEIVING_CHAIN');
|
|
@@ -35,15 +35,15 @@ export class StepExecutor {
|
|
|
35
35
|
// Return the step
|
|
36
36
|
if (recievingChainProcess?.substatus !== 'WAIT_DESTINATION_TRANSACTION' ||
|
|
37
37
|
!recievingChainProcess) {
|
|
38
|
-
const
|
|
39
|
-
if (!
|
|
38
|
+
const updatedWalletClient = await switchChain(walletClient, this.statusManager, step, this.settings.switchChainHook, this.allowUserInteraction);
|
|
39
|
+
if (!updatedWalletClient) {
|
|
40
40
|
// Chain switch was not successful, stop execution here
|
|
41
41
|
return step;
|
|
42
42
|
}
|
|
43
|
-
|
|
43
|
+
walletClient = updatedWalletClient;
|
|
44
44
|
}
|
|
45
45
|
const parameters = {
|
|
46
|
-
|
|
46
|
+
walletClient,
|
|
47
47
|
step,
|
|
48
48
|
settings: this.settings,
|
|
49
49
|
statusManager: this.statusManager,
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Hash, WalletClient } from 'viem';
|
|
2
|
+
import type { StatusManager } from '../execution/StatusManager';
|
|
3
|
+
import type { Chain, InternalExecutionSettings, LifiStep } from '../types';
|
|
4
|
+
export declare const checkAllowance: (walletClient: WalletClient, step: LifiStep, statusManager: StatusManager, settings: InternalExecutionSettings, chain: Chain, allowUserInteraction?: boolean, shouldBatchTransactions?: boolean) => Promise<Hash | void>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { maxUint256, publicActions } from 'viem';
|
|
2
|
+
import { getAllowance, setAllowance } from '../allowance';
|
|
3
|
+
import { LiFiErrorCode, TransactionError } from '../utils';
|
|
4
|
+
import { parseError } from '../utils/parseError';
|
|
5
|
+
export const checkAllowance = async (walletClient, step, statusManager, settings, chain, allowUserInteraction = false, shouldBatchTransactions = false) => {
|
|
6
|
+
// Ask the user to set an allowance
|
|
7
|
+
let allowanceProcess = statusManager.findOrCreateProcess(step, 'TOKEN_ALLOWANCE');
|
|
8
|
+
// Check allowance
|
|
9
|
+
try {
|
|
10
|
+
if (allowanceProcess.txHash && allowanceProcess.status !== 'DONE') {
|
|
11
|
+
await waitForApprovalTransaction(walletClient, allowanceProcess.txHash, allowanceProcess.type, step, chain, statusManager);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
const approved = await getAllowance(chain.id, step.action.fromToken.address, walletClient.account.address, step.estimate.approvalAddress);
|
|
15
|
+
const fromAmount = BigInt(step.action.fromAmount);
|
|
16
|
+
if (fromAmount > approved) {
|
|
17
|
+
if (!allowUserInteraction) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const approvalAmount = settings.infiniteApproval
|
|
21
|
+
? maxUint256
|
|
22
|
+
: fromAmount;
|
|
23
|
+
if (shouldBatchTransactions) {
|
|
24
|
+
const approveTxHash = await setAllowance(walletClient, step.action.fromToken.address, step.estimate.approvalAddress, approvalAmount, true);
|
|
25
|
+
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
|
|
26
|
+
return approveTxHash;
|
|
27
|
+
}
|
|
28
|
+
const approveTxHash = await setAllowance(walletClient, step.action.fromToken.address, step.estimate.approvalAddress, approvalAmount);
|
|
29
|
+
await waitForApprovalTransaction(walletClient, approveTxHash, allowanceProcess.type, step, chain, statusManager);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'DONE');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
const error = await parseError(e, step, allowanceProcess);
|
|
38
|
+
allowanceProcess = statusManager.updateProcess(step, allowanceProcess.type, 'FAILED', {
|
|
39
|
+
error: {
|
|
40
|
+
message: error.message,
|
|
41
|
+
htmlMessage: error.htmlMessage,
|
|
42
|
+
code: error.code,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
statusManager.updateExecution(step, 'FAILED');
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const waitForApprovalTransaction = async (walletClient, txHash, processType, step, chain, statusManager) => {
|
|
50
|
+
const client = walletClient.extend(publicActions);
|
|
51
|
+
statusManager.updateProcess(step, processType, 'PENDING', {
|
|
52
|
+
txHash,
|
|
53
|
+
txLink: `${chain.metamask.blockExplorerUrls[0]}tx/${txHash}`,
|
|
54
|
+
});
|
|
55
|
+
let replacementReason;
|
|
56
|
+
const transactionReceipt = await client.waitForTransactionReceipt({
|
|
57
|
+
hash: txHash,
|
|
58
|
+
onReplaced(response) {
|
|
59
|
+
replacementReason = response.reason;
|
|
60
|
+
statusManager.updateProcess(step, processType, 'PENDING', {
|
|
61
|
+
txHash: response.transaction.hash,
|
|
62
|
+
txLink: `${chain.metamask.blockExplorerUrls[0]}tx/${response.transaction.hash}`,
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
if (replacementReason === 'cancelled') {
|
|
67
|
+
throw new TransactionError(LiFiErrorCode.TransactionCanceled, 'User canceled transaction.');
|
|
68
|
+
}
|
|
69
|
+
statusManager.updateProcess(step, processType, 'DONE', {
|
|
70
|
+
txHash: transactionReceipt.transactionHash,
|
|
71
|
+
txLink: `${chain.metamask.blockExplorerUrls[0]}tx/${transactionReceipt.transactionHash}`,
|
|
72
|
+
});
|
|
73
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { formatUnits } from 'viem';
|
|
2
|
+
import { getTokenBalance } from '../balance';
|
|
3
|
+
import { BalanceError } from '../utils/errors';
|
|
4
|
+
export const checkBalance = async (walletAddress, step, depth = 0) => {
|
|
5
|
+
const token = await getTokenBalance(walletAddress, step.action.fromToken);
|
|
6
|
+
if (token) {
|
|
7
|
+
const currentBalance = token.amount ?? 0n;
|
|
8
|
+
const neededBalance = BigInt(step.action.fromAmount);
|
|
9
|
+
if (currentBalance < neededBalance) {
|
|
10
|
+
if (depth <= 3) {
|
|
11
|
+
await new Promise((resolve) => {
|
|
12
|
+
setTimeout(resolve, 200);
|
|
13
|
+
});
|
|
14
|
+
await checkBalance(walletAddress, step, depth + 1);
|
|
15
|
+
}
|
|
16
|
+
else if ((neededBalance * BigInt((1 - step.action.slippage) * 1000000000)) /
|
|
17
|
+
1000000000n <=
|
|
18
|
+
currentBalance) {
|
|
19
|
+
// adjust amount in slippage limits
|
|
20
|
+
step.action.fromAmount = currentBalance.toString();
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
const neeeded = formatUnits(neededBalance, token.decimals);
|
|
24
|
+
const current = formatUnits(currentBalance, token.decimals);
|
|
25
|
+
let errorMessage = `Your ${token.symbol} balance is too low, ` +
|
|
26
|
+
`you try to transfer ${neeeded} ${token.symbol}, ` +
|
|
27
|
+
`but your wallet only holds ${current} ${token.symbol}. ` +
|
|
28
|
+
`No funds have been sent.`;
|
|
29
|
+
if (currentBalance !== 0n) {
|
|
30
|
+
errorMessage +=
|
|
31
|
+
`If the problem consists, please delete this transfer and ` +
|
|
32
|
+
`start a new one with a maximum of ${current} ${token.symbol}.`;
|
|
33
|
+
}
|
|
34
|
+
throw new BalanceError('The balance is too low.', errorMessage);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import { ExtendedChain, LifiStep,
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import type { ExtendedChain, LifiStep, ProcessType } from '@lifi/types';
|
|
2
|
+
import type { Hash } from 'viem';
|
|
3
|
+
import type { StatusManager } from './StatusManager';
|
|
4
|
+
export declare const updateMultisigRouteProcess: (internalTxHash: Hash, step: LifiStep, statusManager: StatusManager, processType: ProcessType, fromChain: ExtendedChain) => Promise<void>;
|
|
@@ -1,27 +1,25 @@
|
|
|
1
1
|
import ConfigService from '../services/ConfigService';
|
|
2
|
-
import {
|
|
3
|
-
export const updateMultisigRouteProcess = async (internalTxHash, step, statusManager,
|
|
2
|
+
import { LiFiErrorCode, TransactionError } from '../utils/errors';
|
|
3
|
+
export const updateMultisigRouteProcess = async (internalTxHash, step, statusManager, processType, fromChain) => {
|
|
4
4
|
const config = ConfigService.getInstance().getConfig();
|
|
5
|
-
if (!config.
|
|
6
|
-
throw new Error('
|
|
5
|
+
if (!config.multisig?.getMultisigTransactionDetails) {
|
|
6
|
+
throw new Error('getMultisigTransactionDetails is missing in multisig config.');
|
|
7
7
|
}
|
|
8
8
|
const updateIntermediateMultisigStatus = () => {
|
|
9
|
-
|
|
9
|
+
statusManager.updateProcess(step, processType, 'PENDING');
|
|
10
10
|
};
|
|
11
|
-
const multisigStatusResponse = await config.
|
|
11
|
+
const multisigStatusResponse = await config.multisig?.getMultisigTransactionDetails(internalTxHash, fromChain.id, updateIntermediateMultisigStatus);
|
|
12
12
|
if (multisigStatusResponse.status === 'DONE') {
|
|
13
|
-
|
|
13
|
+
statusManager.updateProcess(step, processType, 'PENDING', {
|
|
14
14
|
txHash: multisigStatusResponse.txHash,
|
|
15
15
|
multisigTxHash: undefined,
|
|
16
|
-
txLink: fromChain.metamask.blockExplorerUrls[0]
|
|
17
|
-
'tx/' +
|
|
18
|
-
multisigStatusResponse.txHash,
|
|
16
|
+
txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${multisigStatusResponse.txHash}`,
|
|
19
17
|
});
|
|
20
18
|
}
|
|
21
19
|
if (multisigStatusResponse.status === 'FAILED') {
|
|
22
|
-
throw new TransactionError(
|
|
20
|
+
throw new TransactionError(LiFiErrorCode.TransactionFailed, 'Multisig transaction failed.');
|
|
23
21
|
}
|
|
24
22
|
if (multisigStatusResponse.status === 'CANCELLED') {
|
|
25
|
-
throw new TransactionError(
|
|
23
|
+
throw new TransactionError(LiFiErrorCode.SignatureRejected, 'Transaction was rejected by user.');
|
|
26
24
|
}
|
|
27
25
|
};
|