@lifi/sdk 3.4.2 → 3.5.0-beta.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 (150) hide show
  1. package/package.json +2 -2
  2. package/src/_cjs/constants.js +4 -2
  3. package/src/_cjs/constants.js.map +1 -1
  4. package/src/_cjs/core/EVM/EVM.js +0 -4
  5. package/src/_cjs/core/EVM/EVM.js.map +1 -1
  6. package/src/_cjs/core/EVM/EVMStepExecutor.js +96 -74
  7. package/src/_cjs/core/EVM/EVMStepExecutor.js.map +1 -1
  8. package/src/_cjs/core/EVM/abi.js +36 -43
  9. package/src/_cjs/core/EVM/abi.js.map +1 -1
  10. package/src/_cjs/core/EVM/checkAllowance.js +36 -30
  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/getNativePermit.js +90 -0
  15. package/src/_cjs/core/EVM/getNativePermit.js.map +1 -0
  16. package/src/_cjs/core/EVM/parseEVMErrors.js +3 -0
  17. package/src/_cjs/core/EVM/parseEVMErrors.js.map +1 -1
  18. package/src/_cjs/core/EVM/permit2/allowanceTransfer.js +100 -0
  19. package/src/_cjs/core/EVM/permit2/allowanceTransfer.js.map +1 -0
  20. package/src/_cjs/core/EVM/permit2/constants.js +12 -0
  21. package/src/_cjs/core/EVM/permit2/constants.js.map +1 -0
  22. package/src/_cjs/core/EVM/permit2/domain.js +12 -0
  23. package/src/_cjs/core/EVM/permit2/domain.js.map +1 -0
  24. package/src/_cjs/core/EVM/permit2/signatureTransfer.js +121 -0
  25. package/src/_cjs/core/EVM/permit2/signatureTransfer.js.map +1 -0
  26. package/src/_cjs/core/EVM/setAllowance.js +3 -4
  27. package/src/_cjs/core/EVM/setAllowance.js.map +1 -1
  28. package/src/_cjs/core/EVM/signPermitMessage.js +168 -0
  29. package/src/_cjs/core/EVM/signPermitMessage.js.map +1 -0
  30. package/src/_cjs/core/EVM/types.js.map +1 -1
  31. package/src/_cjs/core/EVM/utils.js +2 -1
  32. package/src/_cjs/core/EVM/utils.js.map +1 -1
  33. package/src/_cjs/core/EVM/waitForBatchTransactionReceipt.js +29 -0
  34. package/src/_cjs/core/EVM/waitForBatchTransactionReceipt.js.map +1 -0
  35. package/src/_cjs/core/checkBalance.js +3 -3
  36. package/src/_cjs/core/checkBalance.js.map +1 -1
  37. package/src/_cjs/index.js.map +1 -1
  38. package/src/_cjs/utils/invariant.js +17 -0
  39. package/src/_cjs/utils/invariant.js.map +1 -0
  40. package/src/_cjs/version.js +1 -1
  41. package/src/_cjs/version.js.map +1 -1
  42. package/src/_esm/constants.js +3 -1
  43. package/src/_esm/constants.js.map +1 -1
  44. package/src/_esm/core/EVM/EVM.js +0 -4
  45. package/src/_esm/core/EVM/EVM.js.map +1 -1
  46. package/src/_esm/core/EVM/EVMStepExecutor.js +124 -84
  47. package/src/_esm/core/EVM/EVMStepExecutor.js.map +1 -1
  48. package/src/_esm/core/EVM/abi.js +37 -42
  49. package/src/_esm/core/EVM/abi.js.map +1 -1
  50. package/src/_esm/core/EVM/checkAllowance.js +41 -32
  51. package/src/_esm/core/EVM/checkAllowance.js.map +1 -1
  52. package/src/_esm/core/EVM/getAllowance.js.map +1 -1
  53. package/src/_esm/core/EVM/getEVMBalance.js.map +1 -1
  54. package/src/_esm/core/EVM/getNativePermit.js +95 -0
  55. package/src/_esm/core/EVM/getNativePermit.js.map +1 -0
  56. package/src/_esm/core/EVM/parseEVMErrors.js +8 -0
  57. package/src/_esm/core/EVM/parseEVMErrors.js.map +1 -1
  58. package/src/_esm/core/EVM/permit2/allowanceTransfer.js +93 -0
  59. package/src/_esm/core/EVM/permit2/allowanceTransfer.js.map +1 -0
  60. package/src/_esm/core/EVM/permit2/constants.js +9 -0
  61. package/src/_esm/core/EVM/permit2/constants.js.map +1 -0
  62. package/src/_esm/core/EVM/permit2/domain.js +9 -0
  63. package/src/_esm/core/EVM/permit2/domain.js.map +1 -0
  64. package/src/_esm/core/EVM/permit2/signatureTransfer.js +117 -0
  65. package/src/_esm/core/EVM/permit2/signatureTransfer.js.map +1 -0
  66. package/src/_esm/core/EVM/setAllowance.js +3 -4
  67. package/src/_esm/core/EVM/setAllowance.js.map +1 -1
  68. package/src/_esm/core/EVM/signPermitMessage.js +162 -0
  69. package/src/_esm/core/EVM/signPermitMessage.js.map +1 -0
  70. package/src/_esm/core/EVM/types.js.map +1 -1
  71. package/src/_esm/core/EVM/utils.js +2 -1
  72. package/src/_esm/core/EVM/utils.js.map +1 -1
  73. package/src/_esm/core/EVM/waitForBatchTransactionReceipt.js +25 -0
  74. package/src/_esm/core/EVM/waitForBatchTransactionReceipt.js.map +1 -0
  75. package/src/_esm/core/checkBalance.js +3 -3
  76. package/src/_esm/core/checkBalance.js.map +1 -1
  77. package/src/_esm/index.js.map +1 -1
  78. package/src/_esm/utils/invariant.js +43 -0
  79. package/src/_esm/utils/invariant.js.map +1 -0
  80. package/src/_esm/version.js +1 -1
  81. package/src/_esm/version.js.map +1 -1
  82. package/src/_types/constants.d.ts +3 -1
  83. package/src/_types/constants.d.ts.map +1 -1
  84. package/src/_types/core/EVM/EVM.d.ts.map +1 -1
  85. package/src/_types/core/EVM/EVMStepExecutor.d.ts +7 -4
  86. package/src/_types/core/EVM/EVMStepExecutor.d.ts.map +1 -1
  87. package/src/_types/core/EVM/abi.d.ts +202 -5
  88. package/src/_types/core/EVM/abi.d.ts.map +1 -1
  89. package/src/_types/core/EVM/checkAllowance.d.ts +12 -2
  90. package/src/_types/core/EVM/checkAllowance.d.ts.map +1 -1
  91. package/src/_types/core/EVM/getAllowance.d.ts +5 -4
  92. package/src/_types/core/EVM/getAllowance.d.ts.map +1 -1
  93. package/src/_types/core/EVM/getEVMBalance.d.ts +2 -1
  94. package/src/_types/core/EVM/getEVMBalance.d.ts.map +1 -1
  95. package/src/_types/core/EVM/getNativePermit.d.ts +18 -0
  96. package/src/_types/core/EVM/getNativePermit.d.ts.map +1 -0
  97. package/src/_types/core/EVM/permit2/allowanceTransfer.d.ts +41 -0
  98. package/src/_types/core/EVM/permit2/allowanceTransfer.d.ts.map +1 -0
  99. package/src/_types/core/EVM/permit2/constants.d.ts +8 -0
  100. package/src/_types/core/EVM/permit2/constants.d.ts.map +1 -0
  101. package/src/_types/core/EVM/permit2/domain.d.ts +8 -0
  102. package/src/_types/core/EVM/permit2/domain.d.ts.map +1 -0
  103. package/src/_types/core/EVM/permit2/signatureTransfer.d.ts +42 -0
  104. package/src/_types/core/EVM/permit2/signatureTransfer.d.ts.map +1 -0
  105. package/src/_types/core/EVM/setAllowance.d.ts +2 -2
  106. package/src/_types/core/EVM/setAllowance.d.ts.map +1 -1
  107. package/src/_types/core/EVM/signPermitMessage.d.ts +22 -0
  108. package/src/_types/core/EVM/signPermitMessage.d.ts.map +1 -0
  109. package/src/_types/core/EVM/types.d.ts +1 -18
  110. package/src/_types/core/EVM/types.d.ts.map +1 -1
  111. package/src/_types/core/EVM/utils.d.ts +2 -2
  112. package/src/_types/core/EVM/utils.d.ts.map +1 -1
  113. package/src/_types/core/EVM/waitForBatchTransactionReceipt.d.ts +4 -0
  114. package/src/_types/core/EVM/waitForBatchTransactionReceipt.d.ts.map +1 -0
  115. package/src/_types/core/checkBalance.d.ts.map +1 -1
  116. package/src/_types/index.d.ts +1 -1
  117. package/src/_types/index.d.ts.map +1 -1
  118. package/src/_types/utils/invariant.d.ts +22 -0
  119. package/src/_types/utils/invariant.d.ts.map +1 -0
  120. package/src/_types/version.d.ts +1 -1
  121. package/src/_types/version.d.ts.map +1 -1
  122. package/src/constants.ts +6 -1
  123. package/src/core/EVM/EVM.ts +0 -4
  124. package/src/core/EVM/EVMStepExecutor.ts +177 -134
  125. package/src/core/EVM/abi.ts +40 -43
  126. package/src/core/EVM/checkAllowance.ts +96 -92
  127. package/src/core/EVM/getAllowance.ts +8 -8
  128. package/src/core/EVM/getEVMBalance.ts +2 -2
  129. package/src/core/EVM/getNativePermit.ts +113 -0
  130. package/src/core/EVM/parseEVMErrors.ts +8 -0
  131. package/src/core/EVM/permit2/allowanceTransfer.ts +168 -0
  132. package/src/core/EVM/permit2/constants.ts +11 -0
  133. package/src/core/EVM/permit2/domain.ts +20 -0
  134. package/src/core/EVM/permit2/signatureTransfer.ts +214 -0
  135. package/src/core/EVM/setAllowance.ts +14 -15
  136. package/src/core/EVM/signPermitMessage.ts +248 -0
  137. package/src/core/EVM/types.ts +1 -27
  138. package/src/core/EVM/utils.ts +4 -3
  139. package/src/core/EVM/waitForBatchTransactionReceipt.ts +49 -0
  140. package/src/core/checkBalance.ts +6 -3
  141. package/src/index.ts +0 -3
  142. package/src/utils/invariant.ts +51 -0
  143. package/src/version.ts +1 -1
  144. package/src/_cjs/core/EVM/multisig.js +0 -29
  145. package/src/_cjs/core/EVM/multisig.js.map +0 -1
  146. package/src/_esm/core/EVM/multisig.js +0 -25
  147. package/src/_esm/core/EVM/multisig.js.map +0 -1
  148. package/src/_types/core/EVM/multisig.d.ts +0 -6
  149. package/src/_types/core/EVM/multisig.d.ts.map +0 -1
  150. package/src/core/EVM/multisig.ts +0 -54
package/src/constants.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  export const AddressZero = '0x0000000000000000000000000000000000000000'
2
2
  export const AlternativeAddressZero =
3
3
  '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'
4
- export const wrappedSolAddress = 'So11111111111111111111111111111111111111112'
4
+
5
5
  export const SolSystemProgram = '11111111111111111111111111111111'
6
+
7
+ export const MaxUint48 = BigInt('0xffffffffffff')
8
+ export const MaxUint160 = BigInt('0xffffffffffffffffffffffffffffffffffffffff')
9
+ export const MaxUint256 =
10
+ BigInt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn)
@@ -12,9 +12,6 @@ export function EVM(options?: EVMProviderOptions): EVMProvider {
12
12
  get type() {
13
13
  return ChainType.EVM
14
14
  },
15
- get multisig() {
16
- return _options.multisig
17
- },
18
15
  isAddress,
19
16
  resolveAddress: getENSAddress,
20
17
  getBalance: getEVMBalance,
@@ -29,7 +26,6 @@ export function EVM(options?: EVMProviderOptions): EVMProvider {
29
26
 
30
27
  const executor = new EVMStepExecutor({
31
28
  client: walletClient,
32
- multisig: _options.multisig,
33
29
  routeId: options.routeId,
34
30
  executionOptions: {
35
31
  ...options.executionOptions,
@@ -3,11 +3,19 @@ import type {
3
3
  FullStatusData,
4
4
  Process,
5
5
  } from '@lifi/types'
6
- import type { Client, Hash, SendTransactionParameters } from 'viem'
7
- import { getAddresses, sendTransaction } from 'viem/actions'
6
+ import type {
7
+ Address,
8
+ Client,
9
+ Hash,
10
+ Hex,
11
+ SendTransactionParameters,
12
+ TransactionReceipt,
13
+ } from 'viem'
14
+ import { estimateGas, getAddresses, sendTransaction } from 'viem/actions'
15
+ import { getCapabilities, sendCalls } from 'viem/experimental'
8
16
  import { config } from '../../config.js'
9
17
  import { LiFiErrorCode } from '../../errors/constants.js'
10
- import { TransactionError, ValidationError } from '../../errors/errors.js'
18
+ import { TransactionError } from '../../errors/errors.js'
11
19
  import { getStepTransaction } from '../../services/api.js'
12
20
  import { getTransactionFailedMessage } from '../../utils/getTransactionMessage.js'
13
21
  import { isZeroAddress } from '../../utils/isZeroAddress.js'
@@ -22,33 +30,38 @@ import type {
22
30
  } from '../types.js'
23
31
  import { waitForReceivingTransaction } from '../waitForReceivingTransaction.js'
24
32
  import { checkAllowance } from './checkAllowance.js'
25
- import { updateMultisigRouteProcess } from './multisig.js'
33
+ import { getNativePermit } from './getNativePermit.js'
26
34
  import { parseEVMErrors } from './parseEVMErrors.js'
35
+ import { signPermitMessage } from './signPermitMessage.js'
27
36
  import { switchChain } from './switchChain.js'
28
- import type { MultisigConfig, MultisigTransaction } from './types.js'
29
37
  import { getMaxPriorityFeePerGas } from './utils.js'
38
+ import {
39
+ type WalletCallReceipt,
40
+ waitForBatchTransactionReceipt,
41
+ } from './waitForBatchTransactionReceipt.js'
30
42
  import { waitForTransactionReceipt } from './waitForTransactionReceipt.js'
31
43
 
44
+ export type Call = {
45
+ data?: Hex
46
+ to?: Address
47
+ value?: bigint
48
+ chainId?: number
49
+ }
50
+
32
51
  export interface EVMStepExecutorOptions extends StepExecutorOptions {
33
52
  client: Client
34
- multisig?: MultisigConfig
35
53
  }
36
54
 
37
55
  export class EVMStepExecutor extends BaseStepExecutor {
38
56
  private client: Client
39
- private multisig?: MultisigConfig
40
57
 
41
58
  constructor(options: EVMStepExecutorOptions) {
42
59
  super(options)
43
60
  this.client = options.client
44
- this.multisig = options.multisig
45
61
  }
46
62
 
47
63
  // Ensure that we are using the right chain and wallet when executing transactions.
48
- checkClient = async (
49
- step: LiFiStepExtended,
50
- process?: Process
51
- ): Promise<Client | undefined> => {
64
+ checkClient = async (step: LiFiStepExtended, process?: Process) => {
52
65
  const updatedClient = await switchChain(
53
66
  this.client,
54
67
  this.statusManager,
@@ -115,49 +128,81 @@ export class EVMStepExecutor extends BaseStepExecutor {
115
128
  }
116
129
  }
117
130
 
118
- const isMultisigClient = !!this.multisig?.isMultisigWalletClient
119
- const multisigBatchTransactions: MultisigTransaction[] = []
120
-
121
- const shouldBatchTransactions =
122
- this.multisig?.shouldBatchTransactions &&
123
- !!this.multisig.sendBatchTransaction
124
-
125
131
  const fromChain = await config.getChainById(step.action.fromChainId)
126
132
  const toChain = await config.getChainById(step.action.toChainId)
127
133
 
134
+ let atomicBatchSupported = false
135
+ try {
136
+ const capabilities = await getCapabilities(this.client)
137
+ atomicBatchSupported = capabilities[fromChain.id]?.atomicBatch?.supported
138
+ } catch {
139
+ // If the wallet does not support getCapabilities, we assume that atomic batch is not supported
140
+ }
141
+
142
+ const calls: Call[] = []
143
+
128
144
  const isBridgeExecution = fromChain.id !== toChain.id
129
145
  const currentProcessType = isBridgeExecution ? 'CROSS_CHAIN' : 'SWAP'
130
146
 
131
147
  // STEP 1: Check allowance
148
+ // Find existing swap/bridge process
132
149
  const existingProcess = step.execution.process.find(
133
150
  (p) => p.type === currentProcessType
134
151
  )
135
152
 
136
- // Check token approval only if fromToken is not the native token => no approval needed in that case
153
+ // Check if token requires approval
154
+ // Native tokens (like ETH) don't need approval since they're not ERC20 tokens
155
+ // We should support different permit types:
156
+ // 1. Native permits (EIP-2612)
157
+ // 2. Permit2 - Universal permit implementation by Uniswap (limited to certain chains)
158
+ // 3. Standard ERC20 approval
159
+ const nativePermit = await getNativePermit(
160
+ this.client,
161
+ fromChain,
162
+ step.action.fromToken.address as Address
163
+ )
164
+ // Check if proxy contract is available and token supports native permits, not available for atomic batch
165
+ const nativePermitSupported =
166
+ !!fromChain.permit2Proxy &&
167
+ nativePermit.supported &&
168
+ !atomicBatchSupported
169
+ // Check if chain has Permit2 contract deployed. Permit2 should not be available for atomic batch.
170
+ const permit2Supported =
171
+ !!fromChain.permit2 && !!fromChain.permit2Proxy && !atomicBatchSupported
172
+ // Token supports either native permits or Permit2
173
+ const permitSupported = permit2Supported || nativePermitSupported
174
+
137
175
  const checkForAllowance =
176
+ // No existing swap/bridgetransaction is pending
138
177
  !existingProcess?.txHash &&
178
+ // Token is not native (address is not zero)
139
179
  !isZeroAddress(step.action.fromToken.address) &&
140
- (shouldBatchTransactions || !isMultisigClient)
180
+ // Token doesn't support native permits
181
+ !nativePermitSupported
141
182
 
142
183
  if (checkForAllowance) {
143
- const data = await checkAllowance(
144
- this.client,
145
- fromChain,
184
+ // Check if token needs approval and get approval transaction or message data when available
185
+ const data = await checkAllowance({
186
+ client: this.client,
187
+ chain: fromChain,
146
188
  step,
147
- this.statusManager,
148
- this.executionOptions,
149
- this.allowUserInteraction,
150
- shouldBatchTransactions
151
- )
189
+ statusManager: this.statusManager,
190
+ executionOptions: this.executionOptions,
191
+ allowUserInteraction: this.allowUserInteraction,
192
+ atomicBatchSupported,
193
+ permit2Supported,
194
+ })
152
195
 
153
196
  if (data) {
154
- // allowance doesn't need value
155
- const baseTransaction: MultisigTransaction = {
156
- to: step.action.fromToken.address,
157
- data,
197
+ // Create approval transaction call
198
+ // No value needed since we're only approving ERC20 tokens
199
+ if (atomicBatchSupported) {
200
+ calls.push({
201
+ chainId: step.action.fromToken.chainId,
202
+ to: step.action.fromToken.address as Address,
203
+ data,
204
+ })
158
205
  }
159
-
160
- multisigBatchTransactions.push(baseTransaction)
161
206
  }
162
207
  }
163
208
 
@@ -169,28 +214,7 @@ export class EVMStepExecutor extends BaseStepExecutor {
169
214
  })
170
215
 
171
216
  if (process.status !== 'DONE') {
172
- const multisigProcess = step.execution.process.find(
173
- (p) => !!p.multisigTxHash
174
- )
175
-
176
217
  try {
177
- if (isMultisigClient && multisigProcess) {
178
- const multisigTxHash = multisigProcess.multisigTxHash as Hash
179
- if (!multisigTxHash) {
180
- throw new ValidationError(
181
- 'Multisig internal transaction hash is undefined.'
182
- )
183
- }
184
- await updateMultisigRouteProcess(
185
- multisigTxHash,
186
- step,
187
- process.type,
188
- fromChain,
189
- this.statusManager,
190
- this.multisig
191
- )
192
- }
193
-
194
218
  let txHash: Hash
195
219
  if (process.txHash) {
196
220
  // Make sure that the chain is still correct
@@ -211,7 +235,7 @@ export class EVMStepExecutor extends BaseStepExecutor {
211
235
  // Check balance
212
236
  await checkBalance(this.client.account!.address, step)
213
237
 
214
- // Create new transaction
238
+ // Create new transaction request
215
239
  if (!step.transactionRequest) {
216
240
  const { execution, ...stepBase } = step
217
241
  const updatedStep = await getStepTransaction(stepBase)
@@ -235,23 +259,6 @@ export class EVMStepExecutor extends BaseStepExecutor {
235
259
  )
236
260
  }
237
261
 
238
- // STEP 3: Send the transaction
239
- // Make sure that the chain is still correct
240
- const updatedClient = await this.checkClient(step, process)
241
- if (!updatedClient) {
242
- return step
243
- }
244
-
245
- process = this.statusManager.updateProcess(
246
- step,
247
- process.type,
248
- 'ACTION_REQUIRED'
249
- )
250
-
251
- if (!this.allowUserInteraction) {
252
- return step
253
- }
254
-
255
262
  let transactionRequest: TransactionParameters = {
256
263
  to: step.transactionRequest.to,
257
264
  from: step.transactionRequest.from,
@@ -289,25 +296,71 @@ export class EVMStepExecutor extends BaseStepExecutor {
289
296
  }
290
297
  }
291
298
 
292
- if (shouldBatchTransactions && this.multisig?.sendBatchTransaction) {
293
- if (transactionRequest.to && transactionRequest.data) {
294
- const populatedTransaction: MultisigTransaction = {
295
- value: transactionRequest.value,
296
- to: transactionRequest.to,
297
- data: transactionRequest.data,
298
- }
299
- multisigBatchTransactions.push(populatedTransaction)
299
+ // STEP 3: Send the transaction
300
+ // Make sure that the chain is still correct
301
+ const updatedClient = await this.checkClient(step, process)
302
+ if (!updatedClient) {
303
+ return step
304
+ }
305
+
306
+ process = this.statusManager.updateProcess(
307
+ step,
308
+ process.type,
309
+ permitSupported ? 'PERMIT_REQUIRED' : 'ACTION_REQUIRED'
310
+ )
311
+
312
+ if (!this.allowUserInteraction) {
313
+ return step
314
+ }
315
+
316
+ if (atomicBatchSupported) {
317
+ const transferCall: Call = {
318
+ chainId: fromChain.id,
319
+ data: transactionRequest.data as Hex,
320
+ to: transactionRequest.to as Address,
321
+ value: transactionRequest.value,
322
+ }
323
+
324
+ calls.push(transferCall)
300
325
 
301
- txHash = await this.multisig?.sendBatchTransaction(
302
- multisigBatchTransactions
326
+ txHash = (await sendCalls(this.client, {
327
+ account: this.client.account!,
328
+ calls,
329
+ })) as Address
330
+ } else {
331
+ if (permitSupported) {
332
+ const { data } = await signPermitMessage(
333
+ this.client,
334
+ transactionRequest,
335
+ fromChain,
336
+ step.action.fromToken.address as Address,
337
+ BigInt(step.action.fromAmount),
338
+ nativePermit
303
339
  )
304
- } else {
305
- throw new TransactionError(
306
- LiFiErrorCode.TransactionUnprepared,
307
- 'Unable to prepare transaction.'
340
+
341
+ transactionRequest.to = fromChain.permit2Proxy
342
+ transactionRequest.data = data
343
+
344
+ try {
345
+ // Try to re-estimate the gas due to additional Permit data
346
+ transactionRequest.gas = await estimateGas(this.client, {
347
+ account: this.client.account!,
348
+ to: transactionRequest.to as Address,
349
+ data: transactionRequest.data as Hex,
350
+ value: transactionRequest.value,
351
+ })
352
+ } catch {
353
+ // Let the wallet estimate the gas in case of failure
354
+ transactionRequest.gas = undefined
355
+ }
356
+
357
+ process = this.statusManager.updateProcess(
358
+ step,
359
+ process.type,
360
+ 'ACTION_REQUIRED'
308
361
  )
309
362
  }
310
- } else {
363
+
311
364
  txHash = await sendTransaction(this.client, {
312
365
  to: transactionRequest.to,
313
366
  account: this.client.account!,
@@ -317,62 +370,53 @@ export class EVMStepExecutor extends BaseStepExecutor {
317
370
  gasPrice: transactionRequest.gasPrice,
318
371
  maxFeePerGas: transactionRequest.maxFeePerGas,
319
372
  maxPriorityFeePerGas: transactionRequest.maxPriorityFeePerGas,
320
- chain: null,
321
373
  } as SendTransactionParameters)
322
374
  }
323
375
 
324
376
  // STEP 4: Wait for the transaction
325
- if (isMultisigClient) {
326
- process = this.statusManager.updateProcess(
327
- step,
328
- process.type,
329
- 'ACTION_REQUIRED',
330
- {
331
- multisigTxHash: txHash,
332
- }
333
- )
334
- } else {
335
- process = this.statusManager.updateProcess(
336
- step,
337
- process.type,
338
- 'PENDING',
339
- {
340
- txHash: txHash,
341
- txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${txHash}`,
342
- }
343
- )
344
- }
377
+ process = this.statusManager.updateProcess(
378
+ step,
379
+ process.type,
380
+ 'PENDING',
381
+ // When atomic batch is supported, txHash represents the batch hash rather than an individual transaction hash at this point
382
+ atomicBatchSupported
383
+ ? {
384
+ atomicBatchSupported,
385
+ }
386
+ : {
387
+ txHash: txHash,
388
+ txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${txHash}`,
389
+ }
390
+ )
345
391
  }
346
392
 
347
- const transactionReceipt = await waitForTransactionReceipt({
348
- client: this.client,
349
- chainId: fromChain.id,
350
- txHash,
351
- onReplaced: (response) => {
352
- this.statusManager.updateProcess(step, process.type, 'PENDING', {
353
- txHash: response.transaction.hash,
354
- txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${response.transaction.hash}`,
355
- })
356
- },
357
- })
393
+ let transactionReceipt:
394
+ | TransactionReceipt
395
+ | WalletCallReceipt
396
+ | undefined
358
397
 
359
- // if it's multisig wallet client and the process is in ACTION_REQUIRED
360
- // then signatures are still needed
361
- if (isMultisigClient && process.status === 'ACTION_REQUIRED') {
362
- await updateMultisigRouteProcess(
363
- transactionReceipt?.transactionHash || txHash,
364
- step,
365
- process.type,
366
- fromChain,
367
- this.statusManager,
368
- this.multisig
398
+ if (atomicBatchSupported) {
399
+ transactionReceipt = await waitForBatchTransactionReceipt(
400
+ this.client,
401
+ txHash
369
402
  )
403
+ } else {
404
+ transactionReceipt = await waitForTransactionReceipt({
405
+ client: this.client,
406
+ chainId: fromChain.id,
407
+ txHash,
408
+ onReplaced: (response) => {
409
+ this.statusManager.updateProcess(step, process.type, 'PENDING', {
410
+ txHash: response.transaction.hash,
411
+ txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${response.transaction.hash}`,
412
+ })
413
+ },
414
+ })
370
415
  }
371
416
 
372
417
  // Update pending process if the transaction hash from the receipt is different.
373
418
  // This might happen if the transaction was replaced.
374
419
  if (
375
- !isMultisigClient &&
376
420
  transactionReceipt?.transactionHash &&
377
421
  transactionReceipt.transactionHash !== txHash
378
422
  ) {
@@ -419,13 +463,12 @@ export class EVMStepExecutor extends BaseStepExecutor {
419
463
  chainId: toChain.id,
420
464
  })
421
465
  }
422
- let statusResponse: FullStatusData
423
466
 
424
467
  try {
425
468
  if (!processTxHash) {
426
469
  throw new Error('Transaction hash is undefined.')
427
470
  }
428
- statusResponse = (await waitForReceivingTransaction(
471
+ const statusResponse = (await waitForReceivingTransaction(
429
472
  processTxHash,
430
473
  this.statusManager,
431
474
  process.type,
@@ -1,47 +1,44 @@
1
- import type { Abi } from 'viem'
1
+ import { parseAbi } from 'viem'
2
2
 
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
- ]
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
+ ])
15
9
 
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
- ]
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
+ ])
28
17
 
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
- ]
18
+ export const approveAbi = parseAbi([
19
+ 'function approve(address, uint256) external returns (bool)',
20
+ ])
38
21
 
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
- ]
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