@lifi/sdk 3.5.0-beta.0 → 3.5.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/package.json +7 -7
- package/src/_cjs/constants.js +2 -4
- package/src/_cjs/constants.js.map +1 -1
- package/src/_cjs/core/EVM/EVM.js +4 -0
- package/src/_cjs/core/EVM/EVM.js.map +1 -1
- package/src/_cjs/core/EVM/EVMStepExecutor.js +77 -98
- package/src/_cjs/core/EVM/EVMStepExecutor.js.map +1 -1
- package/src/_cjs/core/EVM/abi.js +43 -36
- package/src/_cjs/core/EVM/abi.js.map +1 -1
- package/src/_cjs/core/EVM/checkAllowance.js +30 -36
- package/src/_cjs/core/EVM/checkAllowance.js.map +1 -1
- package/src/_cjs/core/EVM/getAllowance.js.map +1 -1
- package/src/_cjs/core/EVM/getEVMBalance.js.map +1 -1
- package/src/_cjs/core/EVM/multisig.js +29 -0
- package/src/_cjs/core/EVM/multisig.js.map +1 -0
- package/src/_cjs/core/EVM/parseEVMErrors.js +0 -3
- package/src/_cjs/core/EVM/parseEVMErrors.js.map +1 -1
- package/src/_cjs/core/EVM/setAllowance.js +6 -4
- package/src/_cjs/core/EVM/setAllowance.js.map +1 -1
- package/src/_cjs/core/EVM/switchChain.js +3 -2
- package/src/_cjs/core/EVM/switchChain.js.map +1 -1
- package/src/_cjs/core/EVM/types.js.map +1 -1
- package/src/_cjs/core/EVM/utils.js +1 -2
- package/src/_cjs/core/EVM/utils.js.map +1 -1
- package/src/_cjs/core/checkBalance.js +3 -3
- package/src/_cjs/core/checkBalance.js.map +1 -1
- package/src/_cjs/index.js.map +1 -1
- package/src/_cjs/version.js +1 -1
- package/src/_cjs/version.js.map +1 -1
- package/src/_esm/constants.js +1 -3
- package/src/_esm/constants.js.map +1 -1
- package/src/_esm/core/EVM/EVM.js +4 -0
- package/src/_esm/core/EVM/EVM.js.map +1 -1
- package/src/_esm/core/EVM/EVMStepExecutor.js +87 -126
- package/src/_esm/core/EVM/EVMStepExecutor.js.map +1 -1
- package/src/_esm/core/EVM/abi.js +42 -37
- package/src/_esm/core/EVM/abi.js.map +1 -1
- package/src/_esm/core/EVM/checkAllowance.js +32 -41
- package/src/_esm/core/EVM/checkAllowance.js.map +1 -1
- package/src/_esm/core/EVM/getAllowance.js.map +1 -1
- package/src/_esm/core/EVM/getEVMBalance.js.map +1 -1
- package/src/_esm/core/EVM/multisig.js +25 -0
- package/src/_esm/core/EVM/multisig.js.map +1 -0
- package/src/_esm/core/EVM/parseEVMErrors.js +0 -8
- package/src/_esm/core/EVM/parseEVMErrors.js.map +1 -1
- package/src/_esm/core/EVM/setAllowance.js +6 -4
- package/src/_esm/core/EVM/setAllowance.js.map +1 -1
- package/src/_esm/core/EVM/switchChain.js +3 -2
- package/src/_esm/core/EVM/switchChain.js.map +1 -1
- package/src/_esm/core/EVM/types.js.map +1 -1
- package/src/_esm/core/EVM/utils.js +1 -2
- package/src/_esm/core/EVM/utils.js.map +1 -1
- package/src/_esm/core/checkBalance.js +3 -3
- package/src/_esm/core/checkBalance.js.map +1 -1
- package/src/_esm/index.js.map +1 -1
- package/src/_esm/version.js +1 -1
- package/src/_esm/version.js.map +1 -1
- package/src/_types/constants.d.ts +1 -3
- package/src/_types/constants.d.ts.map +1 -1
- package/src/_types/core/EVM/EVM.d.ts.map +1 -1
- package/src/_types/core/EVM/EVMStepExecutor.d.ts +4 -7
- package/src/_types/core/EVM/EVMStepExecutor.d.ts.map +1 -1
- package/src/_types/core/EVM/abi.d.ts +5 -202
- package/src/_types/core/EVM/abi.d.ts.map +1 -1
- package/src/_types/core/EVM/checkAllowance.d.ts +2 -12
- package/src/_types/core/EVM/checkAllowance.d.ts.map +1 -1
- package/src/_types/core/EVM/getAllowance.d.ts +4 -5
- package/src/_types/core/EVM/getAllowance.d.ts.map +1 -1
- package/src/_types/core/EVM/getEVMBalance.d.ts +1 -2
- package/src/_types/core/EVM/getEVMBalance.d.ts.map +1 -1
- package/src/_types/core/EVM/multisig.d.ts +6 -0
- package/src/_types/core/EVM/multisig.d.ts.map +1 -0
- package/src/_types/core/EVM/setAllowance.d.ts +2 -2
- package/src/_types/core/EVM/setAllowance.d.ts.map +1 -1
- package/src/_types/core/EVM/switchChain.d.ts.map +1 -1
- package/src/_types/core/EVM/types.d.ts +18 -1
- package/src/_types/core/EVM/types.d.ts.map +1 -1
- package/src/_types/core/EVM/utils.d.ts +2 -2
- package/src/_types/core/EVM/utils.d.ts.map +1 -1
- package/src/_types/core/checkBalance.d.ts.map +1 -1
- package/src/_types/index.d.ts +1 -1
- package/src/_types/index.d.ts.map +1 -1
- package/src/_types/version.d.ts +1 -1
- package/src/_types/version.d.ts.map +1 -1
- package/src/constants.ts +1 -6
- package/src/core/EVM/EVM.ts +4 -0
- package/src/core/EVM/EVMStepExecutor.ts +145 -174
- package/src/core/EVM/abi.ts +43 -40
- package/src/core/EVM/checkAllowance.ts +92 -96
- package/src/core/EVM/getAllowance.ts +8 -8
- package/src/core/EVM/getEVMBalance.ts +2 -2
- package/src/core/EVM/multisig.ts +54 -0
- package/src/core/EVM/parseEVMErrors.ts +0 -8
- package/src/core/EVM/setAllowance.ts +21 -15
- package/src/core/EVM/switchChain.ts +12 -3
- package/src/core/EVM/types.ts +27 -1
- package/src/core/EVM/utils.ts +3 -4
- package/src/core/checkBalance.ts +3 -6
- package/src/index.ts +3 -0
- package/src/version.ts +1 -1
- package/src/_cjs/core/EVM/getNativePermit.js +0 -90
- package/src/_cjs/core/EVM/getNativePermit.js.map +0 -1
- package/src/_cjs/core/EVM/permit2/allowanceTransfer.js +0 -100
- package/src/_cjs/core/EVM/permit2/allowanceTransfer.js.map +0 -1
- package/src/_cjs/core/EVM/permit2/constants.js +0 -12
- package/src/_cjs/core/EVM/permit2/constants.js.map +0 -1
- package/src/_cjs/core/EVM/permit2/domain.js +0 -12
- package/src/_cjs/core/EVM/permit2/domain.js.map +0 -1
- package/src/_cjs/core/EVM/permit2/signatureTransfer.js +0 -121
- package/src/_cjs/core/EVM/permit2/signatureTransfer.js.map +0 -1
- package/src/_cjs/core/EVM/signPermitMessage.js +0 -168
- package/src/_cjs/core/EVM/signPermitMessage.js.map +0 -1
- package/src/_cjs/core/EVM/waitForBatchTransactionReceipt.js +0 -29
- package/src/_cjs/core/EVM/waitForBatchTransactionReceipt.js.map +0 -1
- package/src/_cjs/utils/invariant.js +0 -17
- package/src/_cjs/utils/invariant.js.map +0 -1
- package/src/_esm/core/EVM/getNativePermit.js +0 -95
- package/src/_esm/core/EVM/getNativePermit.js.map +0 -1
- package/src/_esm/core/EVM/permit2/allowanceTransfer.js +0 -93
- package/src/_esm/core/EVM/permit2/allowanceTransfer.js.map +0 -1
- package/src/_esm/core/EVM/permit2/constants.js +0 -9
- package/src/_esm/core/EVM/permit2/constants.js.map +0 -1
- package/src/_esm/core/EVM/permit2/domain.js +0 -9
- package/src/_esm/core/EVM/permit2/domain.js.map +0 -1
- package/src/_esm/core/EVM/permit2/signatureTransfer.js +0 -117
- package/src/_esm/core/EVM/permit2/signatureTransfer.js.map +0 -1
- package/src/_esm/core/EVM/signPermitMessage.js +0 -162
- package/src/_esm/core/EVM/signPermitMessage.js.map +0 -1
- package/src/_esm/core/EVM/waitForBatchTransactionReceipt.js +0 -25
- package/src/_esm/core/EVM/waitForBatchTransactionReceipt.js.map +0 -1
- package/src/_esm/utils/invariant.js +0 -43
- package/src/_esm/utils/invariant.js.map +0 -1
- package/src/_types/core/EVM/getNativePermit.d.ts +0 -18
- package/src/_types/core/EVM/getNativePermit.d.ts.map +0 -1
- package/src/_types/core/EVM/permit2/allowanceTransfer.d.ts +0 -41
- package/src/_types/core/EVM/permit2/allowanceTransfer.d.ts.map +0 -1
- package/src/_types/core/EVM/permit2/constants.d.ts +0 -8
- package/src/_types/core/EVM/permit2/constants.d.ts.map +0 -1
- package/src/_types/core/EVM/permit2/domain.d.ts +0 -8
- package/src/_types/core/EVM/permit2/domain.d.ts.map +0 -1
- package/src/_types/core/EVM/permit2/signatureTransfer.d.ts +0 -42
- package/src/_types/core/EVM/permit2/signatureTransfer.d.ts.map +0 -1
- package/src/_types/core/EVM/signPermitMessage.d.ts +0 -22
- package/src/_types/core/EVM/signPermitMessage.d.ts.map +0 -1
- package/src/_types/core/EVM/waitForBatchTransactionReceipt.d.ts +0 -4
- package/src/_types/core/EVM/waitForBatchTransactionReceipt.d.ts.map +0 -1
- package/src/_types/utils/invariant.d.ts +0 -22
- package/src/_types/utils/invariant.d.ts.map +0 -1
- package/src/core/EVM/getNativePermit.ts +0 -113
- package/src/core/EVM/permit2/allowanceTransfer.ts +0 -168
- package/src/core/EVM/permit2/constants.ts +0 -11
- package/src/core/EVM/permit2/domain.ts +0 -20
- package/src/core/EVM/permit2/signatureTransfer.ts +0 -214
- package/src/core/EVM/signPermitMessage.ts +0 -248
- package/src/core/EVM/waitForBatchTransactionReceipt.ts +0 -49
- package/src/utils/invariant.ts +0 -51
package/src/core/EVM/abi.ts
CHANGED
|
@@ -1,44 +1,47 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Abi } from 'viem'
|
|
2
2
|
|
|
3
|
-
export const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
export const approveAbi: Abi = [
|
|
4
|
+
{
|
|
5
|
+
name: 'approve',
|
|
6
|
+
inputs: [
|
|
7
|
+
{ internalType: 'address', name: 'spender', type: 'address' },
|
|
8
|
+
{ internalType: 'uint256', name: 'amount', type: 'uint256' },
|
|
9
|
+
],
|
|
10
|
+
outputs: [{ internalType: 'bool', name: 'approved', type: 'bool' }],
|
|
11
|
+
stateMutability: 'nonpayable',
|
|
12
|
+
type: 'function',
|
|
13
|
+
},
|
|
14
|
+
]
|
|
9
15
|
|
|
10
|
-
export const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
]
|
|
16
|
+
export const allowanceAbi: Abi = [
|
|
17
|
+
{
|
|
18
|
+
name: 'allowance',
|
|
19
|
+
inputs: [
|
|
20
|
+
{ internalType: 'address', name: 'owner', type: 'address' },
|
|
21
|
+
{ internalType: 'address', name: 'spender', type: 'address' },
|
|
22
|
+
],
|
|
23
|
+
outputs: [{ internalType: 'uint256', name: 'allowance', type: 'uint256' }],
|
|
24
|
+
stateMutability: 'view',
|
|
25
|
+
type: 'function',
|
|
26
|
+
},
|
|
27
|
+
]
|
|
17
28
|
|
|
18
|
-
export const
|
|
19
|
-
|
|
20
|
-
]
|
|
29
|
+
export const getEthBalanceAbi: Abi = [
|
|
30
|
+
{
|
|
31
|
+
inputs: [{ name: '_owner', type: 'address' }],
|
|
32
|
+
name: 'getEthBalance',
|
|
33
|
+
outputs: [{ name: 'balance', type: 'uint256' }],
|
|
34
|
+
type: 'function',
|
|
35
|
+
stateMutability: 'view',
|
|
36
|
+
},
|
|
37
|
+
]
|
|
21
38
|
|
|
22
|
-
export const
|
|
23
|
-
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
'function balanceOf(address) external view returns (uint256)',
|
|
32
|
-
])
|
|
33
|
-
|
|
34
|
-
// EIP-2612 types
|
|
35
|
-
// https://eips.ethereum.org/EIPS/eip-2612
|
|
36
|
-
export const eip2612Types = {
|
|
37
|
-
Permit: [
|
|
38
|
-
{ name: 'owner', type: 'address' },
|
|
39
|
-
{ name: 'spender', type: 'address' },
|
|
40
|
-
{ name: 'value', type: 'uint256' },
|
|
41
|
-
{ name: 'nonce', type: 'uint256' },
|
|
42
|
-
{ name: 'deadline', type: 'uint256' },
|
|
43
|
-
],
|
|
44
|
-
} as const
|
|
39
|
+
export const balanceOfAbi: Abi = [
|
|
40
|
+
{
|
|
41
|
+
inputs: [{ name: '_owner', type: 'address' }],
|
|
42
|
+
name: 'balanceOf',
|
|
43
|
+
outputs: [{ name: 'balance', type: 'uint256' }],
|
|
44
|
+
type: 'function',
|
|
45
|
+
stateMutability: 'view',
|
|
46
|
+
},
|
|
47
|
+
]
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Chain, LiFiStep, Process, ProcessType } from '@lifi/types'
|
|
2
2
|
import type { Address, Client, Hash } from 'viem'
|
|
3
|
-
import { MaxUint256 } from '../../constants.js'
|
|
4
3
|
import type { StatusManager } from '../StatusManager.js'
|
|
5
4
|
import type { ExecutionOptions } from '../types.js'
|
|
6
5
|
import { getAllowance } from './getAllowance.js'
|
|
@@ -8,107 +7,108 @@ import { parseEVMErrors } from './parseEVMErrors.js'
|
|
|
8
7
|
import { setAllowance } from './setAllowance.js'
|
|
9
8
|
import { waitForTransactionReceipt } from './waitForTransactionReceipt.js'
|
|
10
9
|
|
|
11
|
-
export
|
|
12
|
-
client: Client
|
|
13
|
-
chain:
|
|
14
|
-
step: LiFiStep
|
|
15
|
-
statusManager: StatusManager
|
|
16
|
-
|
|
17
|
-
allowUserInteraction?: boolean
|
|
18
|
-
atomicBatchSupported?: boolean
|
|
19
|
-
permit2Supported?: boolean
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const checkAllowance = async ({
|
|
23
|
-
client,
|
|
24
|
-
chain,
|
|
25
|
-
step,
|
|
26
|
-
statusManager,
|
|
27
|
-
executionOptions,
|
|
10
|
+
export const checkAllowance = async (
|
|
11
|
+
client: Client,
|
|
12
|
+
chain: Chain,
|
|
13
|
+
step: LiFiStep,
|
|
14
|
+
statusManager: StatusManager,
|
|
15
|
+
settings?: ExecutionOptions,
|
|
28
16
|
allowUserInteraction = false,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const allowanceProcess: Process = statusManager.findOrCreateProcess({
|
|
17
|
+
shouldBatchTransactions = false
|
|
18
|
+
): Promise<Hash | void> => {
|
|
19
|
+
// Ask the user to set an allowance
|
|
20
|
+
let allowanceProcess: Process = statusManager.findOrCreateProcess({
|
|
34
21
|
step,
|
|
35
22
|
type: 'TOKEN_ALLOWANCE',
|
|
36
23
|
chainId: step.action.fromChainId,
|
|
37
24
|
})
|
|
38
25
|
|
|
26
|
+
// Check allowance
|
|
39
27
|
try {
|
|
40
|
-
// Handle existing pending transaction
|
|
41
28
|
if (allowanceProcess.txHash && allowanceProcess.status !== 'DONE') {
|
|
42
29
|
await waitForApprovalTransaction(
|
|
43
30
|
client,
|
|
44
|
-
allowanceProcess.txHash as Address,
|
|
31
|
+
allowanceProcess.txHash! as Address,
|
|
45
32
|
allowanceProcess.type,
|
|
46
33
|
step,
|
|
47
34
|
chain,
|
|
48
35
|
statusManager
|
|
49
36
|
)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const spenderAddress = permit2Supported
|
|
57
|
-
? chain.permit2
|
|
58
|
-
: step.estimate.approvalAddress
|
|
59
|
-
const fromAmount = BigInt(step.action.fromAmount)
|
|
60
|
-
|
|
61
|
-
const approved = await getAllowance(
|
|
62
|
-
chain.id,
|
|
63
|
-
step.action.fromToken.address as Address,
|
|
64
|
-
client.account!.address,
|
|
65
|
-
spenderAddress as Address
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
// Return early if already approved
|
|
69
|
-
if (fromAmount <= approved) {
|
|
70
|
-
statusManager.updateProcess(step, allowanceProcess.type, 'DONE')
|
|
71
|
-
return
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (!allowUserInteraction) {
|
|
75
|
-
return
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
statusManager.updateProcess(step, allowanceProcess.type, 'ACTION_REQUIRED')
|
|
37
|
+
} else {
|
|
38
|
+
allowanceProcess = statusManager.updateProcess(
|
|
39
|
+
step,
|
|
40
|
+
allowanceProcess.type,
|
|
41
|
+
'STARTED'
|
|
42
|
+
)
|
|
79
43
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
approveAmount,
|
|
87
|
-
executionOptions,
|
|
88
|
-
atomicBatchSupported
|
|
89
|
-
)
|
|
44
|
+
const approved = await getAllowance(
|
|
45
|
+
chain.id,
|
|
46
|
+
step.action.fromToken.address,
|
|
47
|
+
client.account!.address,
|
|
48
|
+
step.estimate.approvalAddress
|
|
49
|
+
)
|
|
90
50
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
51
|
+
const fromAmount = BigInt(step.action.fromAmount)
|
|
52
|
+
|
|
53
|
+
if (fromAmount > approved) {
|
|
54
|
+
if (!allowUserInteraction) {
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (shouldBatchTransactions) {
|
|
59
|
+
const approveTxHash = await setAllowance(
|
|
60
|
+
client,
|
|
61
|
+
step.action.fromToken.address,
|
|
62
|
+
step.estimate.approvalAddress,
|
|
63
|
+
fromAmount,
|
|
64
|
+
settings,
|
|
65
|
+
true
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
allowanceProcess = statusManager.updateProcess(
|
|
69
|
+
step,
|
|
70
|
+
allowanceProcess.type,
|
|
71
|
+
'DONE'
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
return approveTxHash
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const approveTxHash = await setAllowance(
|
|
78
|
+
client,
|
|
79
|
+
step.action.fromToken.address,
|
|
80
|
+
step.estimate.approvalAddress,
|
|
81
|
+
fromAmount
|
|
82
|
+
)
|
|
83
|
+
await waitForApprovalTransaction(
|
|
84
|
+
client,
|
|
85
|
+
approveTxHash,
|
|
86
|
+
allowanceProcess.type,
|
|
87
|
+
step,
|
|
88
|
+
chain,
|
|
89
|
+
statusManager
|
|
90
|
+
)
|
|
91
|
+
} else {
|
|
92
|
+
allowanceProcess = statusManager.updateProcess(
|
|
93
|
+
step,
|
|
94
|
+
allowanceProcess.type,
|
|
95
|
+
'DONE'
|
|
96
|
+
)
|
|
97
|
+
}
|
|
94
98
|
}
|
|
95
|
-
|
|
96
|
-
await waitForApprovalTransaction(
|
|
97
|
-
client,
|
|
98
|
-
approveTxHash,
|
|
99
|
-
allowanceProcess.type,
|
|
100
|
-
step,
|
|
101
|
-
chain,
|
|
102
|
-
statusManager
|
|
103
|
-
)
|
|
104
99
|
} catch (e: any) {
|
|
105
100
|
const error = await parseEVMErrors(e, step, allowanceProcess)
|
|
106
|
-
statusManager.updateProcess(
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
101
|
+
allowanceProcess = statusManager.updateProcess(
|
|
102
|
+
step,
|
|
103
|
+
allowanceProcess.type,
|
|
104
|
+
'FAILED',
|
|
105
|
+
{
|
|
106
|
+
error: {
|
|
107
|
+
message: error.cause.message,
|
|
108
|
+
code: error.code,
|
|
109
|
+
},
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
112
|
statusManager.updateExecution(step, 'FAILED')
|
|
113
113
|
throw error
|
|
114
114
|
}
|
|
@@ -119,33 +119,29 @@ const waitForApprovalTransaction = async (
|
|
|
119
119
|
txHash: Hash,
|
|
120
120
|
processType: ProcessType,
|
|
121
121
|
step: LiFiStep,
|
|
122
|
-
chain:
|
|
122
|
+
chain: Chain,
|
|
123
123
|
statusManager: StatusManager
|
|
124
124
|
) => {
|
|
125
|
-
const baseExplorerUrl = chain.metamask.blockExplorerUrls[0]
|
|
126
|
-
const getTxLink = (hash: Hash) => `${baseExplorerUrl}tx/${hash}`
|
|
127
|
-
|
|
128
125
|
statusManager.updateProcess(step, processType, 'PENDING', {
|
|
129
126
|
txHash,
|
|
130
|
-
txLink:
|
|
127
|
+
txLink: `${chain.metamask.blockExplorerUrls[0]}tx/${txHash}`,
|
|
131
128
|
})
|
|
132
129
|
|
|
133
130
|
const transactionReceipt = await waitForTransactionReceipt({
|
|
134
|
-
client,
|
|
131
|
+
client: client,
|
|
135
132
|
chainId: chain.id,
|
|
136
|
-
txHash,
|
|
133
|
+
txHash: txHash,
|
|
137
134
|
onReplaced(response) {
|
|
138
|
-
const newHash = response.transaction.hash
|
|
139
135
|
statusManager.updateProcess(step, processType, 'PENDING', {
|
|
140
|
-
txHash:
|
|
141
|
-
txLink:
|
|
136
|
+
txHash: response.transaction.hash,
|
|
137
|
+
txLink: `${chain.metamask.blockExplorerUrls[0]}tx/${response.transaction.hash}`,
|
|
142
138
|
})
|
|
143
139
|
},
|
|
144
140
|
})
|
|
145
141
|
|
|
146
|
-
const
|
|
142
|
+
const transactionHash = transactionReceipt?.transactionHash || txHash
|
|
147
143
|
statusManager.updateProcess(step, processType, 'DONE', {
|
|
148
|
-
txHash:
|
|
149
|
-
txLink:
|
|
144
|
+
txHash: transactionHash,
|
|
145
|
+
txLink: `${chain.metamask.blockExplorerUrls[0]}tx/${transactionHash}`,
|
|
150
146
|
})
|
|
151
147
|
}
|
|
@@ -13,9 +13,9 @@ import { getMulticallAddress } from './utils.js'
|
|
|
13
13
|
|
|
14
14
|
export const getAllowance = async (
|
|
15
15
|
chainId: ChainId,
|
|
16
|
-
tokenAddress:
|
|
17
|
-
ownerAddress:
|
|
18
|
-
spenderAddress:
|
|
16
|
+
tokenAddress: string,
|
|
17
|
+
ownerAddress: string,
|
|
18
|
+
spenderAddress: string
|
|
19
19
|
): Promise<bigint> => {
|
|
20
20
|
const client = await getPublicClient(chainId)
|
|
21
21
|
try {
|
|
@@ -34,7 +34,7 @@ export const getAllowance = async (
|
|
|
34
34
|
export const getAllowanceMulticall = async (
|
|
35
35
|
chainId: ChainId,
|
|
36
36
|
tokens: TokenSpender[],
|
|
37
|
-
ownerAddress:
|
|
37
|
+
ownerAddress: string
|
|
38
38
|
): Promise<TokenSpenderAllowance[]> => {
|
|
39
39
|
if (!tokens.length) {
|
|
40
40
|
return []
|
|
@@ -80,8 +80,8 @@ export const getAllowanceMulticall = async (
|
|
|
80
80
|
*/
|
|
81
81
|
export const getTokenAllowance = async (
|
|
82
82
|
token: BaseToken,
|
|
83
|
-
ownerAddress:
|
|
84
|
-
spenderAddress:
|
|
83
|
+
ownerAddress: string,
|
|
84
|
+
spenderAddress: string
|
|
85
85
|
): Promise<bigint | undefined> => {
|
|
86
86
|
// native token don't need approval
|
|
87
87
|
if (isNativeTokenAddress(token.address)) {
|
|
@@ -90,7 +90,7 @@ export const getTokenAllowance = async (
|
|
|
90
90
|
|
|
91
91
|
const approved = await getAllowance(
|
|
92
92
|
token.chainId,
|
|
93
|
-
token.address
|
|
93
|
+
token.address,
|
|
94
94
|
ownerAddress,
|
|
95
95
|
spenderAddress
|
|
96
96
|
)
|
|
@@ -104,7 +104,7 @@ export const getTokenAllowance = async (
|
|
|
104
104
|
* @returns Returns array of tokens and their allowance
|
|
105
105
|
*/
|
|
106
106
|
export const getTokenAllowanceMulticall = async (
|
|
107
|
-
ownerAddress:
|
|
107
|
+
ownerAddress: string,
|
|
108
108
|
tokens: TokenSpender[]
|
|
109
109
|
): Promise<TokenAllowance[]> => {
|
|
110
110
|
// filter out native tokens
|
|
@@ -12,7 +12,7 @@ import { getPublicClient } from './publicClient.js'
|
|
|
12
12
|
import { getMulticallAddress } from './utils.js'
|
|
13
13
|
|
|
14
14
|
export const getEVMBalance = async (
|
|
15
|
-
walletAddress:
|
|
15
|
+
walletAddress: string,
|
|
16
16
|
tokens: Token[]
|
|
17
17
|
): Promise<TokenAmount[]> => {
|
|
18
18
|
if (tokens.length === 0) {
|
|
@@ -85,7 +85,7 @@ const getEVMBalanceMulticall = async (
|
|
|
85
85
|
const getEVMBalanceDefault = async (
|
|
86
86
|
chainId: ChainId,
|
|
87
87
|
tokens: Token[],
|
|
88
|
-
walletAddress:
|
|
88
|
+
walletAddress: string
|
|
89
89
|
): Promise<TokenAmount[]> => {
|
|
90
90
|
const client = await getPublicClient(chainId)
|
|
91
91
|
const blockNumber = await getBlockNumber(client)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { ExtendedChain, LiFiStep, ProcessType } from '@lifi/types'
|
|
2
|
+
import type { Hash } from 'viem'
|
|
3
|
+
import { LiFiErrorCode } from '../../errors/constants.js'
|
|
4
|
+
import { TransactionError } from '../../errors/errors.js'
|
|
5
|
+
import type { StatusManager } from '../StatusManager.js'
|
|
6
|
+
import type { MultisigConfig, MultisigTxDetails } from './types.js'
|
|
7
|
+
|
|
8
|
+
export const updateMultisigRouteProcess = async (
|
|
9
|
+
internalTxHash: Hash,
|
|
10
|
+
step: LiFiStep,
|
|
11
|
+
processType: ProcessType,
|
|
12
|
+
fromChain: ExtendedChain,
|
|
13
|
+
statusManager: StatusManager,
|
|
14
|
+
multisig?: MultisigConfig
|
|
15
|
+
) => {
|
|
16
|
+
if (!multisig?.getMultisigTransactionDetails) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
'getMultisigTransactionDetails is missing in multisig config.'
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const updateIntermediateMultisigStatus = () => {
|
|
23
|
+
statusManager.updateProcess(step, processType, 'PENDING')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const multisigStatusResponse: MultisigTxDetails =
|
|
27
|
+
await multisig?.getMultisigTransactionDetails(
|
|
28
|
+
internalTxHash,
|
|
29
|
+
fromChain.id,
|
|
30
|
+
updateIntermediateMultisigStatus
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
if (multisigStatusResponse.status === 'DONE') {
|
|
34
|
+
statusManager.updateProcess(step, processType, 'PENDING', {
|
|
35
|
+
txHash: multisigStatusResponse.txHash,
|
|
36
|
+
multisigTxHash: undefined,
|
|
37
|
+
txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${multisigStatusResponse.txHash}`,
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (multisigStatusResponse.status === 'FAILED') {
|
|
42
|
+
throw new TransactionError(
|
|
43
|
+
LiFiErrorCode.TransactionFailed,
|
|
44
|
+
'Multisig transaction failed.'
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (multisigStatusResponse.status === 'CANCELLED') {
|
|
49
|
+
throw new TransactionError(
|
|
50
|
+
LiFiErrorCode.SignatureRejected,
|
|
51
|
+
'Transaction was rejected by user.'
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -29,14 +29,6 @@ const handleSpecificErrors = async (
|
|
|
29
29
|
if (e.cause?.name === 'UserRejectedRequestError') {
|
|
30
30
|
return new TransactionError(LiFiErrorCode.SignatureRejected, e.message, e)
|
|
31
31
|
}
|
|
32
|
-
// Safe Wallet via WalletConnect returns -32000 code when user rejects the signature
|
|
33
|
-
// {
|
|
34
|
-
// code: -32000,
|
|
35
|
-
// message: 'User rejected transaction',
|
|
36
|
-
// }
|
|
37
|
-
if (e.cause?.code === -32000) {
|
|
38
|
-
return new TransactionError(LiFiErrorCode.SignatureRejected, e.message, e)
|
|
39
|
-
}
|
|
40
32
|
|
|
41
33
|
if (
|
|
42
34
|
step &&
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Client, Hash, SendTransactionParameters } from 'viem'
|
|
2
2
|
import { encodeFunctionData } from 'viem'
|
|
3
3
|
import { sendTransaction } from 'viem/actions'
|
|
4
|
+
import { getAction } from 'viem/utils'
|
|
4
5
|
import { isNativeTokenAddress } from '../../utils/isZeroAddress.js'
|
|
5
6
|
import type { ExecutionOptions, TransactionParameters } from '../types.js'
|
|
6
7
|
import { approveAbi } from './abi.js'
|
|
@@ -10,10 +11,10 @@ import { getMaxPriorityFeePerGas } from './utils.js'
|
|
|
10
11
|
|
|
11
12
|
export const setAllowance = async (
|
|
12
13
|
client: Client,
|
|
13
|
-
tokenAddress:
|
|
14
|
-
contractAddress:
|
|
14
|
+
tokenAddress: string,
|
|
15
|
+
contractAddress: string,
|
|
15
16
|
amount: bigint,
|
|
16
|
-
|
|
17
|
+
settings?: ExecutionOptions,
|
|
17
18
|
returnPopulatedTransaction?: boolean
|
|
18
19
|
): Promise<Hash> => {
|
|
19
20
|
const data = encodeFunctionData({
|
|
@@ -35,9 +36,9 @@ export const setAllowance = async (
|
|
|
35
36
|
: undefined,
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
if (
|
|
39
|
+
if (settings?.updateTransactionRequestHook) {
|
|
39
40
|
const customizedTransactionRequest: TransactionParameters =
|
|
40
|
-
await
|
|
41
|
+
await settings.updateTransactionRequestHook({
|
|
41
42
|
requestType: 'approve',
|
|
42
43
|
...transactionRequest,
|
|
43
44
|
})
|
|
@@ -48,7 +49,11 @@ export const setAllowance = async (
|
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
return
|
|
52
|
+
return getAction(
|
|
53
|
+
client,
|
|
54
|
+
sendTransaction,
|
|
55
|
+
'sendTransaction'
|
|
56
|
+
)({
|
|
52
57
|
to: transactionRequest.to,
|
|
53
58
|
account: client.account!,
|
|
54
59
|
data: transactionRequest.data,
|
|
@@ -56,6 +61,7 @@ export const setAllowance = async (
|
|
|
56
61
|
gasPrice: transactionRequest.gasPrice,
|
|
57
62
|
maxFeePerGas: transactionRequest.maxFeePerGas,
|
|
58
63
|
maxPriorityFeePerGas: transactionRequest.maxPriorityFeePerGas,
|
|
64
|
+
chain: null,
|
|
59
65
|
} as SendTransactionParameters)
|
|
60
66
|
}
|
|
61
67
|
|
|
@@ -80,16 +86,16 @@ export const setTokenAllowance = async ({
|
|
|
80
86
|
}
|
|
81
87
|
const approvedAmount = await getAllowance(
|
|
82
88
|
token.chainId,
|
|
83
|
-
token.address
|
|
89
|
+
token.address,
|
|
84
90
|
walletClient.account!.address,
|
|
85
|
-
spenderAddress
|
|
91
|
+
spenderAddress
|
|
86
92
|
)
|
|
87
93
|
|
|
88
94
|
if (amount > approvedAmount) {
|
|
89
95
|
const approveTx = await setAllowance(
|
|
90
96
|
walletClient,
|
|
91
|
-
token.address
|
|
92
|
-
spenderAddress
|
|
97
|
+
token.address,
|
|
98
|
+
spenderAddress,
|
|
93
99
|
amount
|
|
94
100
|
)
|
|
95
101
|
|
|
@@ -116,15 +122,15 @@ export const revokeTokenApproval = async ({
|
|
|
116
122
|
}
|
|
117
123
|
const approvedAmount = await getAllowance(
|
|
118
124
|
token.chainId,
|
|
119
|
-
token.address
|
|
125
|
+
token.address,
|
|
120
126
|
walletClient.account!.address,
|
|
121
|
-
spenderAddress
|
|
127
|
+
spenderAddress
|
|
122
128
|
)
|
|
123
129
|
if (approvedAmount > 0) {
|
|
124
130
|
const approveTx = await setAllowance(
|
|
125
131
|
walletClient,
|
|
126
|
-
token.address
|
|
127
|
-
spenderAddress
|
|
132
|
+
token.address,
|
|
133
|
+
spenderAddress,
|
|
128
134
|
0n
|
|
129
135
|
)
|
|
130
136
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { Client } from 'viem'
|
|
1
|
+
import type { Client, GetChainIdReturnType } from 'viem'
|
|
2
2
|
import { getChainId } from 'viem/actions'
|
|
3
|
+
import { getAction } from 'viem/utils'
|
|
3
4
|
import { LiFiErrorCode } from '../../errors/constants.js'
|
|
4
5
|
import { ProviderError } from '../../errors/errors.js'
|
|
5
6
|
import type { StatusManager } from '../StatusManager.js'
|
|
@@ -30,7 +31,11 @@ export const switchChain = async (
|
|
|
30
31
|
switchChainHook?: SwitchChainHook
|
|
31
32
|
): Promise<Client | undefined> => {
|
|
32
33
|
// if we are already on the correct chain we can proceed directly
|
|
33
|
-
const currentChainId = await
|
|
34
|
+
const currentChainId = (await getAction(
|
|
35
|
+
client,
|
|
36
|
+
getChainId,
|
|
37
|
+
'getChainId'
|
|
38
|
+
)(undefined)) as GetChainIdReturnType
|
|
34
39
|
if (currentChainId === step.action.fromChainId) {
|
|
35
40
|
return client
|
|
36
41
|
}
|
|
@@ -53,7 +58,11 @@ export const switchChain = async (
|
|
|
53
58
|
const updatedClient = await switchChainHook?.(step.action.fromChainId)
|
|
54
59
|
let updatedChainId: number | undefined
|
|
55
60
|
if (updatedClient) {
|
|
56
|
-
updatedChainId = await
|
|
61
|
+
updatedChainId = (await getAction(
|
|
62
|
+
updatedClient,
|
|
63
|
+
getChainId,
|
|
64
|
+
'getChainId'
|
|
65
|
+
)(undefined)) as GetChainIdReturnType
|
|
57
66
|
}
|
|
58
67
|
if (updatedChainId !== step.action.fromChainId) {
|
|
59
68
|
throw new ProviderError(
|
package/src/core/EVM/types.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { type BaseToken, ChainType } from '@lifi/types'
|
|
2
|
-
import type { Client } from 'viem'
|
|
2
|
+
import type { Client, Hash } from 'viem'
|
|
3
3
|
import type { SwitchChainHook } from '../types.js'
|
|
4
4
|
import type { SDKProvider } from '../types.js'
|
|
5
5
|
|
|
6
6
|
export interface EVMProviderOptions {
|
|
7
7
|
getWalletClient?: () => Promise<Client>
|
|
8
8
|
switchChain?: SwitchChainHook
|
|
9
|
+
multisig?: MultisigConfig
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
export interface EVMProvider extends SDKProvider {
|
|
12
13
|
setOptions(options: EVMProviderOptions): void
|
|
14
|
+
multisig?: MultisigConfig
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
export function isEVM(provider: SDKProvider): provider is EVMProvider {
|
|
@@ -48,3 +50,27 @@ export interface RevokeApprovalRequest {
|
|
|
48
50
|
token: BaseToken
|
|
49
51
|
spenderAddress: string
|
|
50
52
|
}
|
|
53
|
+
|
|
54
|
+
export interface MultisigTxDetails {
|
|
55
|
+
status: 'DONE' | 'FAILED' | 'PENDING' | 'CANCELLED'
|
|
56
|
+
txHash?: Hash
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface MultisigTransaction {
|
|
60
|
+
to: string
|
|
61
|
+
value?: bigint
|
|
62
|
+
data: string
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface MultisigConfig {
|
|
66
|
+
isMultisigWalletClient: boolean
|
|
67
|
+
getMultisigTransactionDetails: (
|
|
68
|
+
txHash: Hash,
|
|
69
|
+
fromChainId: number,
|
|
70
|
+
updateIntermediateStatus?: () => void
|
|
71
|
+
) => Promise<MultisigTxDetails>
|
|
72
|
+
sendBatchTransaction?: (
|
|
73
|
+
batchTransactions: MultisigTransaction[]
|
|
74
|
+
) => Promise<Hash>
|
|
75
|
+
shouldBatchTransactions?: boolean
|
|
76
|
+
}
|
package/src/core/EVM/utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ChainId } from '@lifi/types'
|
|
2
|
-
import type {
|
|
2
|
+
import type { Client, Transaction } from 'viem'
|
|
3
3
|
import { getBlock } from 'viem/actions'
|
|
4
4
|
import { config } from '../../config.js'
|
|
5
5
|
import { median } from '../../utils/median.js'
|
|
@@ -37,10 +37,9 @@ export const getMaxPriorityFeePerGas = async (
|
|
|
37
37
|
// Multicall
|
|
38
38
|
export const getMulticallAddress = async (
|
|
39
39
|
chainId: ChainId
|
|
40
|
-
): Promise<
|
|
40
|
+
): Promise<string | undefined> => {
|
|
41
41
|
const chains = await config.getChains()
|
|
42
|
-
return chains.find((chain) => chain.id === chainId)
|
|
43
|
-
?.multicallAddress as Address
|
|
42
|
+
return chains.find((chain) => chain.id === chainId)?.multicallAddress
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
// Modified viem retryDelay exponential backoff function.
|