@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.
Files changed (156) hide show
  1. package/package.json +7 -7
  2. package/src/_cjs/constants.js +2 -4
  3. package/src/_cjs/constants.js.map +1 -1
  4. package/src/_cjs/core/EVM/EVM.js +4 -0
  5. package/src/_cjs/core/EVM/EVM.js.map +1 -1
  6. package/src/_cjs/core/EVM/EVMStepExecutor.js +77 -98
  7. package/src/_cjs/core/EVM/EVMStepExecutor.js.map +1 -1
  8. package/src/_cjs/core/EVM/abi.js +43 -36
  9. package/src/_cjs/core/EVM/abi.js.map +1 -1
  10. package/src/_cjs/core/EVM/checkAllowance.js +30 -36
  11. package/src/_cjs/core/EVM/checkAllowance.js.map +1 -1
  12. package/src/_cjs/core/EVM/getAllowance.js.map +1 -1
  13. package/src/_cjs/core/EVM/getEVMBalance.js.map +1 -1
  14. package/src/_cjs/core/EVM/multisig.js +29 -0
  15. package/src/_cjs/core/EVM/multisig.js.map +1 -0
  16. package/src/_cjs/core/EVM/parseEVMErrors.js +0 -3
  17. package/src/_cjs/core/EVM/parseEVMErrors.js.map +1 -1
  18. package/src/_cjs/core/EVM/setAllowance.js +6 -4
  19. package/src/_cjs/core/EVM/setAllowance.js.map +1 -1
  20. package/src/_cjs/core/EVM/switchChain.js +3 -2
  21. package/src/_cjs/core/EVM/switchChain.js.map +1 -1
  22. package/src/_cjs/core/EVM/types.js.map +1 -1
  23. package/src/_cjs/core/EVM/utils.js +1 -2
  24. package/src/_cjs/core/EVM/utils.js.map +1 -1
  25. package/src/_cjs/core/checkBalance.js +3 -3
  26. package/src/_cjs/core/checkBalance.js.map +1 -1
  27. package/src/_cjs/index.js.map +1 -1
  28. package/src/_cjs/version.js +1 -1
  29. package/src/_cjs/version.js.map +1 -1
  30. package/src/_esm/constants.js +1 -3
  31. package/src/_esm/constants.js.map +1 -1
  32. package/src/_esm/core/EVM/EVM.js +4 -0
  33. package/src/_esm/core/EVM/EVM.js.map +1 -1
  34. package/src/_esm/core/EVM/EVMStepExecutor.js +87 -126
  35. package/src/_esm/core/EVM/EVMStepExecutor.js.map +1 -1
  36. package/src/_esm/core/EVM/abi.js +42 -37
  37. package/src/_esm/core/EVM/abi.js.map +1 -1
  38. package/src/_esm/core/EVM/checkAllowance.js +32 -41
  39. package/src/_esm/core/EVM/checkAllowance.js.map +1 -1
  40. package/src/_esm/core/EVM/getAllowance.js.map +1 -1
  41. package/src/_esm/core/EVM/getEVMBalance.js.map +1 -1
  42. package/src/_esm/core/EVM/multisig.js +25 -0
  43. package/src/_esm/core/EVM/multisig.js.map +1 -0
  44. package/src/_esm/core/EVM/parseEVMErrors.js +0 -8
  45. package/src/_esm/core/EVM/parseEVMErrors.js.map +1 -1
  46. package/src/_esm/core/EVM/setAllowance.js +6 -4
  47. package/src/_esm/core/EVM/setAllowance.js.map +1 -1
  48. package/src/_esm/core/EVM/switchChain.js +3 -2
  49. package/src/_esm/core/EVM/switchChain.js.map +1 -1
  50. package/src/_esm/core/EVM/types.js.map +1 -1
  51. package/src/_esm/core/EVM/utils.js +1 -2
  52. package/src/_esm/core/EVM/utils.js.map +1 -1
  53. package/src/_esm/core/checkBalance.js +3 -3
  54. package/src/_esm/core/checkBalance.js.map +1 -1
  55. package/src/_esm/index.js.map +1 -1
  56. package/src/_esm/version.js +1 -1
  57. package/src/_esm/version.js.map +1 -1
  58. package/src/_types/constants.d.ts +1 -3
  59. package/src/_types/constants.d.ts.map +1 -1
  60. package/src/_types/core/EVM/EVM.d.ts.map +1 -1
  61. package/src/_types/core/EVM/EVMStepExecutor.d.ts +4 -7
  62. package/src/_types/core/EVM/EVMStepExecutor.d.ts.map +1 -1
  63. package/src/_types/core/EVM/abi.d.ts +5 -202
  64. package/src/_types/core/EVM/abi.d.ts.map +1 -1
  65. package/src/_types/core/EVM/checkAllowance.d.ts +2 -12
  66. package/src/_types/core/EVM/checkAllowance.d.ts.map +1 -1
  67. package/src/_types/core/EVM/getAllowance.d.ts +4 -5
  68. package/src/_types/core/EVM/getAllowance.d.ts.map +1 -1
  69. package/src/_types/core/EVM/getEVMBalance.d.ts +1 -2
  70. package/src/_types/core/EVM/getEVMBalance.d.ts.map +1 -1
  71. package/src/_types/core/EVM/multisig.d.ts +6 -0
  72. package/src/_types/core/EVM/multisig.d.ts.map +1 -0
  73. package/src/_types/core/EVM/setAllowance.d.ts +2 -2
  74. package/src/_types/core/EVM/setAllowance.d.ts.map +1 -1
  75. package/src/_types/core/EVM/switchChain.d.ts.map +1 -1
  76. package/src/_types/core/EVM/types.d.ts +18 -1
  77. package/src/_types/core/EVM/types.d.ts.map +1 -1
  78. package/src/_types/core/EVM/utils.d.ts +2 -2
  79. package/src/_types/core/EVM/utils.d.ts.map +1 -1
  80. package/src/_types/core/checkBalance.d.ts.map +1 -1
  81. package/src/_types/index.d.ts +1 -1
  82. package/src/_types/index.d.ts.map +1 -1
  83. package/src/_types/version.d.ts +1 -1
  84. package/src/_types/version.d.ts.map +1 -1
  85. package/src/constants.ts +1 -6
  86. package/src/core/EVM/EVM.ts +4 -0
  87. package/src/core/EVM/EVMStepExecutor.ts +145 -174
  88. package/src/core/EVM/abi.ts +43 -40
  89. package/src/core/EVM/checkAllowance.ts +92 -96
  90. package/src/core/EVM/getAllowance.ts +8 -8
  91. package/src/core/EVM/getEVMBalance.ts +2 -2
  92. package/src/core/EVM/multisig.ts +54 -0
  93. package/src/core/EVM/parseEVMErrors.ts +0 -8
  94. package/src/core/EVM/setAllowance.ts +21 -15
  95. package/src/core/EVM/switchChain.ts +12 -3
  96. package/src/core/EVM/types.ts +27 -1
  97. package/src/core/EVM/utils.ts +3 -4
  98. package/src/core/checkBalance.ts +3 -6
  99. package/src/index.ts +3 -0
  100. package/src/version.ts +1 -1
  101. package/src/_cjs/core/EVM/getNativePermit.js +0 -90
  102. package/src/_cjs/core/EVM/getNativePermit.js.map +0 -1
  103. package/src/_cjs/core/EVM/permit2/allowanceTransfer.js +0 -100
  104. package/src/_cjs/core/EVM/permit2/allowanceTransfer.js.map +0 -1
  105. package/src/_cjs/core/EVM/permit2/constants.js +0 -12
  106. package/src/_cjs/core/EVM/permit2/constants.js.map +0 -1
  107. package/src/_cjs/core/EVM/permit2/domain.js +0 -12
  108. package/src/_cjs/core/EVM/permit2/domain.js.map +0 -1
  109. package/src/_cjs/core/EVM/permit2/signatureTransfer.js +0 -121
  110. package/src/_cjs/core/EVM/permit2/signatureTransfer.js.map +0 -1
  111. package/src/_cjs/core/EVM/signPermitMessage.js +0 -168
  112. package/src/_cjs/core/EVM/signPermitMessage.js.map +0 -1
  113. package/src/_cjs/core/EVM/waitForBatchTransactionReceipt.js +0 -29
  114. package/src/_cjs/core/EVM/waitForBatchTransactionReceipt.js.map +0 -1
  115. package/src/_cjs/utils/invariant.js +0 -17
  116. package/src/_cjs/utils/invariant.js.map +0 -1
  117. package/src/_esm/core/EVM/getNativePermit.js +0 -95
  118. package/src/_esm/core/EVM/getNativePermit.js.map +0 -1
  119. package/src/_esm/core/EVM/permit2/allowanceTransfer.js +0 -93
  120. package/src/_esm/core/EVM/permit2/allowanceTransfer.js.map +0 -1
  121. package/src/_esm/core/EVM/permit2/constants.js +0 -9
  122. package/src/_esm/core/EVM/permit2/constants.js.map +0 -1
  123. package/src/_esm/core/EVM/permit2/domain.js +0 -9
  124. package/src/_esm/core/EVM/permit2/domain.js.map +0 -1
  125. package/src/_esm/core/EVM/permit2/signatureTransfer.js +0 -117
  126. package/src/_esm/core/EVM/permit2/signatureTransfer.js.map +0 -1
  127. package/src/_esm/core/EVM/signPermitMessage.js +0 -162
  128. package/src/_esm/core/EVM/signPermitMessage.js.map +0 -1
  129. package/src/_esm/core/EVM/waitForBatchTransactionReceipt.js +0 -25
  130. package/src/_esm/core/EVM/waitForBatchTransactionReceipt.js.map +0 -1
  131. package/src/_esm/utils/invariant.js +0 -43
  132. package/src/_esm/utils/invariant.js.map +0 -1
  133. package/src/_types/core/EVM/getNativePermit.d.ts +0 -18
  134. package/src/_types/core/EVM/getNativePermit.d.ts.map +0 -1
  135. package/src/_types/core/EVM/permit2/allowanceTransfer.d.ts +0 -41
  136. package/src/_types/core/EVM/permit2/allowanceTransfer.d.ts.map +0 -1
  137. package/src/_types/core/EVM/permit2/constants.d.ts +0 -8
  138. package/src/_types/core/EVM/permit2/constants.d.ts.map +0 -1
  139. package/src/_types/core/EVM/permit2/domain.d.ts +0 -8
  140. package/src/_types/core/EVM/permit2/domain.d.ts.map +0 -1
  141. package/src/_types/core/EVM/permit2/signatureTransfer.d.ts +0 -42
  142. package/src/_types/core/EVM/permit2/signatureTransfer.d.ts.map +0 -1
  143. package/src/_types/core/EVM/signPermitMessage.d.ts +0 -22
  144. package/src/_types/core/EVM/signPermitMessage.d.ts.map +0 -1
  145. package/src/_types/core/EVM/waitForBatchTransactionReceipt.d.ts +0 -4
  146. package/src/_types/core/EVM/waitForBatchTransactionReceipt.d.ts.map +0 -1
  147. package/src/_types/utils/invariant.d.ts +0 -22
  148. package/src/_types/utils/invariant.d.ts.map +0 -1
  149. package/src/core/EVM/getNativePermit.ts +0 -113
  150. package/src/core/EVM/permit2/allowanceTransfer.ts +0 -168
  151. package/src/core/EVM/permit2/constants.ts +0 -11
  152. package/src/core/EVM/permit2/domain.ts +0 -20
  153. package/src/core/EVM/permit2/signatureTransfer.ts +0 -214
  154. package/src/core/EVM/signPermitMessage.ts +0 -248
  155. package/src/core/EVM/waitForBatchTransactionReceipt.ts +0 -49
  156. package/src/utils/invariant.ts +0 -51
@@ -1,44 +1,47 @@
1
- import { parseAbi } from 'viem'
1
+ import type { Abi } from 'viem'
2
2
 
3
- export const permit2ProxyAbi = parseAbi([
4
- 'function callDiamondWithPermit2(bytes, ((address, uint256), uint256, uint256), bytes) external',
5
- 'function callDiamondWithEIP2612Signature(address, uint256, uint256, uint8, bytes32, bytes32, bytes) external payable',
6
- 'function nextNonce(address) external view returns (uint256)',
7
- 'function callDiamondWithPermit2Witness(bytes, address, ((address, uint256), uint256, uint256), bytes) external payable',
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 eip2612Abi = parseAbi([
11
- 'function permit(address, address, uint256, uint256, uint8, bytes32, bytes32) external',
12
- 'function DOMAIN_SEPARATOR() external view returns (bytes32)',
13
- 'function nonces(address) external view returns (uint256)',
14
- 'function name() external view returns (string)',
15
- 'function version() external view returns (string)',
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 approveAbi = parseAbi([
19
- 'function approve(address, uint256) external returns (bool)',
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 allowanceAbi = parseAbi([
23
- 'function allowance(address, address) external view returns (uint256)',
24
- ])
25
-
26
- export const getEthBalanceAbi = parseAbi([
27
- 'function getEthBalance(address) external view returns (uint256)',
28
- ])
29
-
30
- export const balanceOfAbi = parseAbi([
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 { ExtendedChain, LiFiStep, Process, ProcessType } from '@lifi/types'
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 type CheckAllowanceParams = {
12
- client: Client
13
- chain: ExtendedChain
14
- step: LiFiStep
15
- statusManager: StatusManager
16
- executionOptions?: ExecutionOptions
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
- atomicBatchSupported = false,
30
- permit2Supported = false,
31
- }: CheckAllowanceParams): Promise<Hash | void> => {
32
- // Find existing or create new allowance process
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
- return
51
- }
52
-
53
- // Start new allowance check
54
- statusManager.updateProcess(step, allowanceProcess.type, 'STARTED')
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
- // Set new allowance
81
- const approveAmount = permit2Supported ? MaxUint256 : fromAmount
82
- const approveTxHash = await setAllowance(
83
- client,
84
- step.action.fromToken.address as Address,
85
- spenderAddress as Address,
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
- if (atomicBatchSupported) {
92
- statusManager.updateProcess(step, allowanceProcess.type, 'DONE')
93
- return approveTxHash
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(step, allowanceProcess.type, 'FAILED', {
107
- error: {
108
- message: error.cause.message,
109
- code: error.code,
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: ExtendedChain,
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: getTxLink(txHash),
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: newHash,
141
- txLink: getTxLink(newHash),
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 finalHash = transactionReceipt?.transactionHash || txHash
142
+ const transactionHash = transactionReceipt?.transactionHash || txHash
147
143
  statusManager.updateProcess(step, processType, 'DONE', {
148
- txHash: finalHash,
149
- txLink: getTxLink(finalHash),
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: Address,
17
- ownerAddress: Address,
18
- spenderAddress: Address
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: Address
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: Address,
84
- spenderAddress: Address
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 as 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: Address,
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: Address,
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: Address
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 { Address, Client, Hash, SendTransactionParameters } from 'viem'
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: Address,
14
- contractAddress: Address,
14
+ tokenAddress: string,
15
+ contractAddress: string,
15
16
  amount: bigint,
16
- executionOptions?: ExecutionOptions,
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 (executionOptions?.updateTransactionRequestHook) {
39
+ if (settings?.updateTransactionRequestHook) {
39
40
  const customizedTransactionRequest: TransactionParameters =
40
- await executionOptions.updateTransactionRequestHook({
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 sendTransaction(client, {
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 as Address,
89
+ token.address,
84
90
  walletClient.account!.address,
85
- spenderAddress as Address
91
+ spenderAddress
86
92
  )
87
93
 
88
94
  if (amount > approvedAmount) {
89
95
  const approveTx = await setAllowance(
90
96
  walletClient,
91
- token.address as Address,
92
- spenderAddress as Address,
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 as Address,
125
+ token.address,
120
126
  walletClient.account!.address,
121
- spenderAddress as Address
127
+ spenderAddress
122
128
  )
123
129
  if (approvedAmount > 0) {
124
130
  const approveTx = await setAllowance(
125
131
  walletClient,
126
- token.address as Address,
127
- spenderAddress as Address,
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 getChainId(client)
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 getChainId(updatedClient)
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(
@@ -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
+ }
@@ -1,5 +1,5 @@
1
1
  import type { ChainId } from '@lifi/types'
2
- import type { Address, Client, Transaction } from 'viem'
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<Address | undefined> => {
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.