@lifi/sdk 3.10.0 → 3.11.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.
- package/package.json +1 -1
- package/src/_cjs/core/EVM/EVMStepExecutor.js +122 -131
- package/src/_cjs/core/EVM/EVMStepExecutor.js.map +1 -1
- package/src/_cjs/core/EVM/abi.js +1 -0
- package/src/_cjs/core/EVM/abi.js.map +1 -1
- package/src/_cjs/core/EVM/checkAllowance.js +126 -44
- package/src/_cjs/core/EVM/checkAllowance.js.map +1 -1
- package/src/_cjs/core/EVM/permits/getNativePermit.js +123 -16
- package/src/_cjs/core/EVM/permits/getNativePermit.js.map +1 -1
- package/src/_cjs/core/EVM/permits/isNativePermitValid.js +34 -0
- package/src/_cjs/core/EVM/permits/isNativePermitValid.js.map +1 -0
- package/src/_cjs/core/EVM/switchChain.js +8 -14
- package/src/_cjs/core/EVM/switchChain.js.map +1 -1
- package/src/_cjs/core/EVM/utils.js +10 -1
- package/src/_cjs/core/EVM/utils.js.map +1 -1
- package/src/_cjs/core/execution.js +1 -1
- package/src/_cjs/core/execution.js.map +1 -1
- package/src/_cjs/core/prepareRestart.js +5 -2
- package/src/_cjs/core/prepareRestart.js.map +1 -1
- package/src/_cjs/core/processMessages.js +4 -8
- package/src/_cjs/core/processMessages.js.map +1 -1
- package/src/_cjs/index.js +2 -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/core/EVM/EVMStepExecutor.js +136 -148
- package/src/_esm/core/EVM/EVMStepExecutor.js.map +1 -1
- package/src/_esm/core/EVM/abi.js +2 -0
- package/src/_esm/core/EVM/abi.js.map +1 -1
- package/src/_esm/core/EVM/checkAllowance.js +141 -45
- package/src/_esm/core/EVM/checkAllowance.js.map +1 -1
- package/src/_esm/core/EVM/permits/getNativePermit.js +144 -21
- package/src/_esm/core/EVM/permits/getNativePermit.js.map +1 -1
- package/src/_esm/core/EVM/permits/isNativePermitValid.js +41 -0
- package/src/_esm/core/EVM/permits/isNativePermitValid.js.map +1 -0
- package/src/_esm/core/EVM/switchChain.js +8 -15
- package/src/_esm/core/EVM/switchChain.js.map +1 -1
- package/src/_esm/core/EVM/utils.js +12 -0
- package/src/_esm/core/EVM/utils.js.map +1 -1
- package/src/_esm/core/execution.js +1 -1
- package/src/_esm/core/execution.js.map +1 -1
- package/src/_esm/core/prepareRestart.js +6 -3
- package/src/_esm/core/prepareRestart.js.map +1 -1
- package/src/_esm/core/processMessages.js +4 -8
- package/src/_esm/core/processMessages.js.map +1 -1
- package/src/_esm/index.js +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/core/EVM/EVMStepExecutor.d.ts +3 -2
- package/src/_types/core/EVM/EVMStepExecutor.d.ts.map +1 -1
- package/src/_types/core/EVM/abi.d.ts +20 -0
- package/src/_types/core/EVM/abi.d.ts.map +1 -1
- package/src/_types/core/EVM/checkAllowance.d.ts +10 -7
- package/src/_types/core/EVM/checkAllowance.d.ts.map +1 -1
- package/src/_types/core/EVM/permits/getNativePermit.d.ts +2 -2
- package/src/_types/core/EVM/permits/getNativePermit.d.ts.map +1 -1
- package/src/_types/core/EVM/permits/isNativePermitValid.d.ts +6 -0
- package/src/_types/core/EVM/permits/isNativePermitValid.d.ts.map +1 -0
- package/src/_types/core/EVM/switchChain.d.ts +2 -2
- package/src/_types/core/EVM/switchChain.d.ts.map +1 -1
- package/src/_types/core/EVM/utils.d.ts +6 -1
- package/src/_types/core/EVM/utils.d.ts.map +1 -1
- package/src/_types/core/prepareRestart.d.ts +1 -1
- package/src/_types/core/prepareRestart.d.ts.map +1 -1
- package/src/_types/core/processMessages.d.ts.map +1 -1
- package/src/_types/core/types.d.ts +2 -2
- package/src/_types/core/types.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/core/EVM/EVMStepExecutor.ts +203 -197
- package/src/core/EVM/abi.ts +2 -0
- package/src/core/EVM/checkAllowance.ts +206 -63
- package/src/core/EVM/permits/getNativePermit.ts +189 -22
- package/src/core/EVM/permits/isNativePermitValid.ts +57 -0
- package/src/core/EVM/switchChain.ts +14 -22
- package/src/core/EVM/utils.ts +17 -1
- package/src/core/execution.ts +1 -1
- package/src/core/prepareRestart.ts +6 -3
- package/src/core/processMessages.ts +4 -8
- package/src/core/types.ts +1 -2
- package/src/index.ts +1 -0
- package/src/version.ts +1 -1
|
@@ -45,11 +45,16 @@ import {
|
|
|
45
45
|
} from './parseEVMErrors.js'
|
|
46
46
|
import { encodeNativePermitData } from './permits/encodeNativePermitData.js'
|
|
47
47
|
import { encodePermit2Data } from './permits/encodePermit2Data.js'
|
|
48
|
+
import { isNativePermitValid } from './permits/isNativePermitValid.js'
|
|
48
49
|
import { signPermit2Message } from './permits/signPermit2Message.js'
|
|
49
50
|
import { switchChain } from './switchChain.js'
|
|
50
51
|
import { isGaslessStep, isRelayerStep } from './typeguards.js'
|
|
51
52
|
import type { Call, WalletCallReceipt } from './types.js'
|
|
52
|
-
import {
|
|
53
|
+
import {
|
|
54
|
+
convertExtendedChain,
|
|
55
|
+
getMaxPriorityFeePerGas,
|
|
56
|
+
isSaltMatchingChainId,
|
|
57
|
+
} from './utils.js'
|
|
53
58
|
import { waitForBatchTransactionReceipt } from './waitForBatchTransactionReceipt.js'
|
|
54
59
|
import { waitForRelayedTransactionReceipt } from './waitForRelayedTransactionReceipt.js'
|
|
55
60
|
import { waitForTransactionReceipt } from './waitForTransactionReceipt.js'
|
|
@@ -67,13 +72,19 @@ export class EVMStepExecutor extends BaseStepExecutor {
|
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
// Ensure that we are using the right chain and wallet when executing transactions.
|
|
70
|
-
checkClient = async (
|
|
75
|
+
checkClient = async (
|
|
76
|
+
step: LiFiStepExtended,
|
|
77
|
+
process: Process,
|
|
78
|
+
targetChainId?: number
|
|
79
|
+
) => {
|
|
71
80
|
const updatedClient = await switchChain(
|
|
72
81
|
this.client,
|
|
73
82
|
this.statusManager,
|
|
74
83
|
step,
|
|
84
|
+
process,
|
|
85
|
+
targetChainId ?? step.action.fromChainId,
|
|
75
86
|
this.allowUserInteraction,
|
|
76
|
-
this.executionOptions
|
|
87
|
+
this.executionOptions
|
|
77
88
|
)
|
|
78
89
|
if (updatedClient) {
|
|
79
90
|
this.client = updatedClient
|
|
@@ -92,17 +103,9 @@ export class EVMStepExecutor extends BaseStepExecutor {
|
|
|
92
103
|
if (
|
|
93
104
|
accountAddress?.toLowerCase() !== step.action.fromAddress?.toLowerCase()
|
|
94
105
|
) {
|
|
95
|
-
let processToUpdate = process
|
|
96
|
-
if (!processToUpdate) {
|
|
97
|
-
// We need to create some process if we don't have one so we can show the error
|
|
98
|
-
processToUpdate = this.statusManager.findOrCreateProcess({
|
|
99
|
-
step,
|
|
100
|
-
type: 'TRANSACTION',
|
|
101
|
-
})
|
|
102
|
-
}
|
|
103
106
|
const errorMessage =
|
|
104
107
|
'The wallet address that requested the quote does not match the wallet address attempting to sign the transaction.'
|
|
105
|
-
this.statusManager.updateProcess(step,
|
|
108
|
+
this.statusManager.updateProcess(step, process.type, 'FAILED', {
|
|
106
109
|
error: {
|
|
107
110
|
code: LiFiErrorCode.WalletChangedDuringExecution,
|
|
108
111
|
message: errorMessage,
|
|
@@ -202,14 +205,15 @@ export class EVMStepExecutor extends BaseStepExecutor {
|
|
|
202
205
|
)
|
|
203
206
|
}
|
|
204
207
|
|
|
205
|
-
private
|
|
208
|
+
private prepareUpdatedStep = async (
|
|
206
209
|
step: LiFiStepExtended,
|
|
207
|
-
|
|
208
|
-
)
|
|
210
|
+
signedTypedData?: SignedTypedData[]
|
|
211
|
+
) => {
|
|
209
212
|
// biome-ignore lint/correctness/noUnusedVariables: destructuring
|
|
210
213
|
const { execution, ...stepBase } = step
|
|
211
214
|
const relayerStep = isRelayerStep(step)
|
|
212
215
|
const gaslessStep = isGaslessStep(step)
|
|
216
|
+
let updatedStep: LiFiStep
|
|
213
217
|
if (relayerStep && gaslessStep) {
|
|
214
218
|
const updatedRelayedStep = await getRelayerQuote({
|
|
215
219
|
fromChain: stepBase.action.fromChainId,
|
|
@@ -222,18 +226,118 @@ export class EVMStepExecutor extends BaseStepExecutor {
|
|
|
222
226
|
toAddress: stepBase.action.toAddress,
|
|
223
227
|
allowBridges: [stepBase.tool],
|
|
224
228
|
})
|
|
225
|
-
|
|
229
|
+
updatedStep = {
|
|
226
230
|
...updatedRelayedStep,
|
|
227
231
|
id: stepBase.id,
|
|
228
232
|
}
|
|
233
|
+
} else {
|
|
234
|
+
const params = signedTypedData?.length
|
|
235
|
+
? { ...stepBase, typedData: signedTypedData }
|
|
236
|
+
: stepBase
|
|
237
|
+
updatedStep = await getStepTransaction(params)
|
|
229
238
|
}
|
|
230
239
|
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
240
|
+
const comparedStep = await stepComparison(
|
|
241
|
+
this.statusManager,
|
|
242
|
+
step,
|
|
243
|
+
updatedStep,
|
|
244
|
+
this.allowUserInteraction,
|
|
245
|
+
this.executionOptions
|
|
246
|
+
)
|
|
247
|
+
Object.assign(step, {
|
|
248
|
+
...comparedStep,
|
|
249
|
+
execution: step.execution,
|
|
250
|
+
typedData: updatedStep.typedData ?? step.typedData,
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
if (!step.transactionRequest && !step.typedData?.length) {
|
|
254
|
+
throw new TransactionError(
|
|
255
|
+
LiFiErrorCode.TransactionUnprepared,
|
|
256
|
+
'Unable to prepare transaction.'
|
|
257
|
+
)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
let transactionRequest: TransactionParameters | undefined
|
|
261
|
+
if (step.transactionRequest) {
|
|
262
|
+
transactionRequest = {
|
|
263
|
+
to: step.transactionRequest.to,
|
|
264
|
+
from: step.transactionRequest.from,
|
|
265
|
+
data: step.transactionRequest.data,
|
|
266
|
+
value: step.transactionRequest.value
|
|
267
|
+
? BigInt(step.transactionRequest.value)
|
|
268
|
+
: undefined,
|
|
269
|
+
gas: step.transactionRequest.gasLimit
|
|
270
|
+
? BigInt(step.transactionRequest.gasLimit)
|
|
271
|
+
: undefined,
|
|
272
|
+
// gasPrice: step.transactionRequest.gasPrice
|
|
273
|
+
// ? BigInt(step.transactionRequest.gasPrice as string)
|
|
274
|
+
// : undefined,
|
|
275
|
+
// maxFeePerGas: step.transactionRequest.maxFeePerGas
|
|
276
|
+
// ? BigInt(step.transactionRequest.maxFeePerGas as string)
|
|
277
|
+
// : undefined,
|
|
278
|
+
maxPriorityFeePerGas:
|
|
279
|
+
this.client.account?.type === 'local'
|
|
280
|
+
? await getMaxPriorityFeePerGas(this.client)
|
|
281
|
+
: step.transactionRequest.maxPriorityFeePerGas
|
|
282
|
+
? BigInt(step.transactionRequest.maxPriorityFeePerGas)
|
|
283
|
+
: undefined,
|
|
284
|
+
}
|
|
285
|
+
}
|
|
235
286
|
|
|
236
|
-
|
|
287
|
+
if (
|
|
288
|
+
this.executionOptions?.updateTransactionRequestHook &&
|
|
289
|
+
transactionRequest
|
|
290
|
+
) {
|
|
291
|
+
const customizedTransactionRequest: TransactionParameters =
|
|
292
|
+
await this.executionOptions.updateTransactionRequestHook({
|
|
293
|
+
requestType: 'transaction',
|
|
294
|
+
...transactionRequest,
|
|
295
|
+
})
|
|
296
|
+
transactionRequest = {
|
|
297
|
+
...transactionRequest,
|
|
298
|
+
...customizedTransactionRequest,
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return {
|
|
303
|
+
transactionRequest,
|
|
304
|
+
// We should always check against the updated step,
|
|
305
|
+
// because the step may be updated with typed data from the previously signed typed data
|
|
306
|
+
isRelayerTransaction: isRelayerStep(updatedStep),
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
private estimateTransactionRequest = async (
|
|
311
|
+
transactionRequest: TransactionParameters,
|
|
312
|
+
fromChain: ExtendedChain
|
|
313
|
+
) => {
|
|
314
|
+
// Target address should be the Permit2 proxy contract in case of native permit or Permit2
|
|
315
|
+
transactionRequest.to = fromChain.permit2Proxy
|
|
316
|
+
try {
|
|
317
|
+
// Try to re-estimate the gas due to additional Permit data
|
|
318
|
+
const estimatedGas = await getActionWithFallback(
|
|
319
|
+
this.client,
|
|
320
|
+
estimateGas,
|
|
321
|
+
'estimateGas',
|
|
322
|
+
{
|
|
323
|
+
account: this.client.account!,
|
|
324
|
+
to: transactionRequest.to as Address,
|
|
325
|
+
data: transactionRequest.data as Hex,
|
|
326
|
+
value: transactionRequest.value,
|
|
327
|
+
}
|
|
328
|
+
)
|
|
329
|
+
transactionRequest.gas =
|
|
330
|
+
transactionRequest.gas && transactionRequest.gas > estimatedGas
|
|
331
|
+
? transactionRequest.gas
|
|
332
|
+
: estimatedGas
|
|
333
|
+
} catch (_) {
|
|
334
|
+
// If we fail to estimate the gas, we add 80_000 gas units Permit buffer to the gas limit
|
|
335
|
+
if (transactionRequest.gas) {
|
|
336
|
+
transactionRequest.gas = transactionRequest.gas + 80_000n
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return transactionRequest
|
|
237
341
|
}
|
|
238
342
|
|
|
239
343
|
executeStep = async (
|
|
@@ -252,8 +356,14 @@ export class EVMStepExecutor extends BaseStepExecutor {
|
|
|
252
356
|
// If the step is waiting for a transaction on the destination chain, we do not switch the chain
|
|
253
357
|
// All changes are already done from the source chain
|
|
254
358
|
// Return the step
|
|
255
|
-
if (
|
|
256
|
-
|
|
359
|
+
if (
|
|
360
|
+
destinationChainProcess &&
|
|
361
|
+
destinationChainProcess.substatus !== 'WAIT_DESTINATION_TRANSACTION'
|
|
362
|
+
) {
|
|
363
|
+
const updatedClient = await this.checkClient(
|
|
364
|
+
step,
|
|
365
|
+
destinationChainProcess
|
|
366
|
+
)
|
|
257
367
|
if (!updatedClient) {
|
|
258
368
|
return step
|
|
259
369
|
}
|
|
@@ -262,18 +372,17 @@ export class EVMStepExecutor extends BaseStepExecutor {
|
|
|
262
372
|
const fromChain = await config.getChainById(step.action.fromChainId)
|
|
263
373
|
const toChain = await config.getChainById(step.action.toChainId)
|
|
264
374
|
|
|
265
|
-
// Check if step requires permit signature and will be used with relayer service
|
|
266
|
-
let isRelayerTransaction = isRelayerStep(step)
|
|
267
|
-
|
|
268
375
|
// Check if the wallet supports atomic batch transactions (EIP-5792)
|
|
269
376
|
const calls: Call[] = []
|
|
377
|
+
// Signed typed data for native permits and other messages
|
|
378
|
+
let signedTypedData: SignedTypedData[] = []
|
|
270
379
|
|
|
271
380
|
// Batching via EIP-5792 is disabled in the next cases:
|
|
272
381
|
// 1. When atomicity is not ready or the wallet rejected the upgrade to 7702 account (atomicityNotReady is true)
|
|
273
382
|
// 2. When the step is using thorswap tool (temporary disabled)
|
|
274
383
|
// 3. When using relayer transactions
|
|
275
384
|
const batchingSupported =
|
|
276
|
-
atomicityNotReady || step.tool === 'thorswap' ||
|
|
385
|
+
atomicityNotReady || step.tool === 'thorswap' || isRelayerStep(step)
|
|
277
386
|
? false
|
|
278
387
|
: await isBatchingSupported({
|
|
279
388
|
client: this.client,
|
|
@@ -317,11 +426,10 @@ export class EVMStepExecutor extends BaseStepExecutor {
|
|
|
317
426
|
// Approval address is required for allowance checks, but may be null in special cases (e.g. direct transfers)
|
|
318
427
|
!!step.estimate.approvalAddress
|
|
319
428
|
|
|
320
|
-
let signedNativePermitTypedData: SignedTypedData | undefined
|
|
321
429
|
if (checkForAllowance) {
|
|
322
430
|
// Check if token needs approval and get approval transaction or message data when available
|
|
323
431
|
const allowanceResult = await checkAllowance({
|
|
324
|
-
|
|
432
|
+
checkClient: this.checkClient,
|
|
325
433
|
chain: fromChain,
|
|
326
434
|
step,
|
|
327
435
|
statusManager: this.statusManager,
|
|
@@ -332,21 +440,22 @@ export class EVMStepExecutor extends BaseStepExecutor {
|
|
|
332
440
|
disableMessageSigning,
|
|
333
441
|
})
|
|
334
442
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
443
|
+
switch (allowanceResult.status) {
|
|
444
|
+
case 'BATCH_APPROVAL':
|
|
445
|
+
calls.push(allowanceResult.data.call)
|
|
446
|
+
signedTypedData = allowanceResult.data.signedTypedData
|
|
447
|
+
break
|
|
448
|
+
case 'NATIVE_PERMIT':
|
|
449
|
+
signedTypedData = allowanceResult.data
|
|
450
|
+
break
|
|
451
|
+
case 'DONE':
|
|
452
|
+
signedTypedData = allowanceResult.data
|
|
453
|
+
break
|
|
454
|
+
default:
|
|
455
|
+
if (!this.allowUserInteraction) {
|
|
456
|
+
return step
|
|
457
|
+
}
|
|
458
|
+
break
|
|
350
459
|
}
|
|
351
460
|
}
|
|
352
461
|
|
|
@@ -382,93 +491,18 @@ export class EVMStepExecutor extends BaseStepExecutor {
|
|
|
382
491
|
return step
|
|
383
492
|
}
|
|
384
493
|
|
|
385
|
-
const permitRequired =
|
|
386
|
-
!batchingSupported && !signedNativePermitTypedData && permit2Supported
|
|
387
494
|
process = this.statusManager.findOrCreateProcess({
|
|
388
495
|
step,
|
|
389
|
-
type:
|
|
496
|
+
type: currentProcessType,
|
|
390
497
|
status: 'STARTED',
|
|
391
498
|
chainId: fromChain.id,
|
|
392
499
|
})
|
|
393
500
|
|
|
394
|
-
// Check balance
|
|
395
501
|
await checkBalance(this.client.account!.address, step)
|
|
396
502
|
|
|
397
|
-
//
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
!step.typedData?.some((p) => p.primaryType !== 'Permit')
|
|
401
|
-
) {
|
|
402
|
-
const updatedStep = await this.getUpdatedStep(
|
|
403
|
-
step,
|
|
404
|
-
signedNativePermitTypedData
|
|
405
|
-
)
|
|
406
|
-
const comparedStep = await stepComparison(
|
|
407
|
-
this.statusManager,
|
|
408
|
-
step,
|
|
409
|
-
updatedStep,
|
|
410
|
-
this.allowUserInteraction,
|
|
411
|
-
this.executionOptions
|
|
412
|
-
)
|
|
413
|
-
Object.assign(step, {
|
|
414
|
-
...comparedStep,
|
|
415
|
-
execution: step.execution,
|
|
416
|
-
})
|
|
417
|
-
isRelayerTransaction = isRelayerStep(comparedStep)
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
if (
|
|
421
|
-
!step.transactionRequest &&
|
|
422
|
-
!step.typedData?.some((p) => p.primaryType !== 'Permit')
|
|
423
|
-
) {
|
|
424
|
-
throw new TransactionError(
|
|
425
|
-
LiFiErrorCode.TransactionUnprepared,
|
|
426
|
-
'Unable to prepare transaction.'
|
|
427
|
-
)
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
let transactionRequest: TransactionParameters | undefined
|
|
431
|
-
if (step.transactionRequest) {
|
|
432
|
-
transactionRequest = {
|
|
433
|
-
to: step.transactionRequest.to,
|
|
434
|
-
from: step.transactionRequest.from,
|
|
435
|
-
data: step.transactionRequest.data,
|
|
436
|
-
value: step.transactionRequest.value
|
|
437
|
-
? BigInt(step.transactionRequest.value)
|
|
438
|
-
: undefined,
|
|
439
|
-
gas: step.transactionRequest.gasLimit
|
|
440
|
-
? BigInt(step.transactionRequest.gasLimit)
|
|
441
|
-
: undefined,
|
|
442
|
-
// gasPrice: step.transactionRequest.gasPrice
|
|
443
|
-
// ? BigInt(step.transactionRequest.gasPrice as string)
|
|
444
|
-
// : undefined,
|
|
445
|
-
// maxFeePerGas: step.transactionRequest.maxFeePerGas
|
|
446
|
-
// ? BigInt(step.transactionRequest.maxFeePerGas as string)
|
|
447
|
-
// : undefined,
|
|
448
|
-
maxPriorityFeePerGas:
|
|
449
|
-
this.client.account?.type === 'local'
|
|
450
|
-
? await getMaxPriorityFeePerGas(this.client)
|
|
451
|
-
: step.transactionRequest.maxPriorityFeePerGas
|
|
452
|
-
? BigInt(step.transactionRequest.maxPriorityFeePerGas)
|
|
453
|
-
: undefined,
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
if (
|
|
458
|
-
this.executionOptions?.updateTransactionRequestHook &&
|
|
459
|
-
transactionRequest
|
|
460
|
-
) {
|
|
461
|
-
const customizedTransactionRequest: TransactionParameters =
|
|
462
|
-
await this.executionOptions.updateTransactionRequestHook({
|
|
463
|
-
requestType: 'transaction',
|
|
464
|
-
...transactionRequest,
|
|
465
|
-
})
|
|
466
|
-
|
|
467
|
-
transactionRequest = {
|
|
468
|
-
...transactionRequest,
|
|
469
|
-
...customizedTransactionRequest,
|
|
470
|
-
}
|
|
471
|
-
}
|
|
503
|
+
// Try to prepare a new transaction request and update the step with typed data
|
|
504
|
+
let { transactionRequest, isRelayerTransaction } =
|
|
505
|
+
await this.prepareUpdatedStep(step, signedTypedData)
|
|
472
506
|
|
|
473
507
|
// Make sure that the chain is still correct
|
|
474
508
|
const updatedClient = await this.checkClient(step, process)
|
|
@@ -512,48 +546,39 @@ export class EVMStepExecutor extends BaseStepExecutor {
|
|
|
512
546
|
taskId = id as Hash
|
|
513
547
|
txType = 'batched'
|
|
514
548
|
} else if (isRelayerTransaction) {
|
|
515
|
-
const
|
|
516
|
-
(
|
|
549
|
+
const intentTypedData = step.typedData?.filter(
|
|
550
|
+
(typedData) =>
|
|
551
|
+
!signedTypedData.some((signedPermit) =>
|
|
552
|
+
isNativePermitValid(signedPermit, typedData)
|
|
553
|
+
)
|
|
517
554
|
)
|
|
518
|
-
|
|
519
|
-
if (!relayerTypedData) {
|
|
555
|
+
if (!intentTypedData?.length) {
|
|
520
556
|
throw new TransactionError(
|
|
521
557
|
LiFiErrorCode.TransactionUnprepared,
|
|
522
558
|
'Unable to prepare transaction. Typed data for transfer is not found.'
|
|
523
559
|
)
|
|
524
560
|
}
|
|
525
|
-
|
|
526
|
-
const
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
process = this.statusManager.findOrCreateProcess({
|
|
541
|
-
step,
|
|
542
|
-
type: currentProcessType,
|
|
543
|
-
status: 'PENDING',
|
|
544
|
-
chainId: fromChain.id,
|
|
545
|
-
})
|
|
546
|
-
|
|
547
|
-
const signedTypedData: SignedTypedData[] = [
|
|
548
|
-
{
|
|
549
|
-
...relayerTypedData,
|
|
561
|
+
this.statusManager.updateProcess(step, process.type, 'MESSAGE_REQUIRED')
|
|
562
|
+
for (const typedData of intentTypedData) {
|
|
563
|
+
const signature = await getAction(
|
|
564
|
+
this.client,
|
|
565
|
+
signTypedData,
|
|
566
|
+
'signTypedData'
|
|
567
|
+
)({
|
|
568
|
+
account: this.client.account!,
|
|
569
|
+
primaryType: typedData.primaryType,
|
|
570
|
+
domain: typedData.domain,
|
|
571
|
+
types: typedData.types,
|
|
572
|
+
message: typedData.message,
|
|
573
|
+
})
|
|
574
|
+
signedTypedData.push({
|
|
575
|
+
...typedData,
|
|
550
576
|
signature: signature,
|
|
551
|
-
}
|
|
552
|
-
]
|
|
553
|
-
// Add native permit if available as first element, order is important
|
|
554
|
-
if (signedNativePermitTypedData) {
|
|
555
|
-
signedTypedData.unshift(signedNativePermitTypedData)
|
|
577
|
+
})
|
|
556
578
|
}
|
|
579
|
+
|
|
580
|
+
this.statusManager.updateProcess(step, process.type, 'PENDING')
|
|
581
|
+
|
|
557
582
|
// biome-ignore lint/correctness/noUnusedVariables: destructuring
|
|
558
583
|
const { execution, ...stepBase } = step
|
|
559
584
|
const relayedTransaction = await relayTransaction({
|
|
@@ -570,6 +595,12 @@ export class EVMStepExecutor extends BaseStepExecutor {
|
|
|
570
595
|
'Unable to prepare transaction. Transaction request is not found.'
|
|
571
596
|
)
|
|
572
597
|
}
|
|
598
|
+
const signedNativePermitTypedData = signedTypedData.find(
|
|
599
|
+
(p) =>
|
|
600
|
+
p.primaryType === 'Permit' &&
|
|
601
|
+
(p.domain.chainId === fromChain.id ||
|
|
602
|
+
isSaltMatchingChainId(p.domain.salt as Hex, fromChain.id))
|
|
603
|
+
)
|
|
573
604
|
if (signedNativePermitTypedData) {
|
|
574
605
|
transactionRequest.data = encodeNativePermitData(
|
|
575
606
|
step.action.fromToken.address as Address,
|
|
@@ -579,6 +610,11 @@ export class EVMStepExecutor extends BaseStepExecutor {
|
|
|
579
610
|
transactionRequest.data as Hex
|
|
580
611
|
)
|
|
581
612
|
} else if (permit2Supported) {
|
|
613
|
+
this.statusManager.updateProcess(
|
|
614
|
+
step,
|
|
615
|
+
process.type,
|
|
616
|
+
'MESSAGE_REQUIRED'
|
|
617
|
+
)
|
|
582
618
|
const permit2Signature = await signPermit2Message({
|
|
583
619
|
client: this.client,
|
|
584
620
|
chain: fromChain,
|
|
@@ -586,14 +622,6 @@ export class EVMStepExecutor extends BaseStepExecutor {
|
|
|
586
622
|
amount: BigInt(step.action.fromAmount),
|
|
587
623
|
data: transactionRequest.data as Hex,
|
|
588
624
|
})
|
|
589
|
-
this.statusManager.updateProcess(step, process.type, 'DONE')
|
|
590
|
-
|
|
591
|
-
process = this.statusManager.findOrCreateProcess({
|
|
592
|
-
step,
|
|
593
|
-
type: currentProcessType,
|
|
594
|
-
status: 'PENDING',
|
|
595
|
-
chainId: fromChain.id,
|
|
596
|
-
})
|
|
597
625
|
transactionRequest.data = encodePermit2Data(
|
|
598
626
|
step.action.fromToken.address as Address,
|
|
599
627
|
BigInt(step.action.fromAmount),
|
|
@@ -602,42 +630,20 @@ export class EVMStepExecutor extends BaseStepExecutor {
|
|
|
602
630
|
transactionRequest.data as Hex,
|
|
603
631
|
permit2Signature.signature
|
|
604
632
|
)
|
|
633
|
+
this.statusManager.updateProcess(
|
|
634
|
+
step,
|
|
635
|
+
process.type,
|
|
636
|
+
'ACTION_REQUIRED'
|
|
637
|
+
)
|
|
605
638
|
}
|
|
606
639
|
|
|
607
640
|
if (signedNativePermitTypedData || permit2Supported) {
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
const estimatedGas = await getActionWithFallback(
|
|
613
|
-
this.client,
|
|
614
|
-
estimateGas,
|
|
615
|
-
'estimateGas',
|
|
616
|
-
{
|
|
617
|
-
account: this.client.account!,
|
|
618
|
-
to: transactionRequest.to as Address,
|
|
619
|
-
data: transactionRequest.data as Hex,
|
|
620
|
-
value: transactionRequest.value,
|
|
621
|
-
}
|
|
622
|
-
)
|
|
623
|
-
transactionRequest.gas =
|
|
624
|
-
transactionRequest.gas && transactionRequest.gas > estimatedGas
|
|
625
|
-
? transactionRequest.gas
|
|
626
|
-
: estimatedGas
|
|
627
|
-
} catch (_) {
|
|
628
|
-
// If we fail to estimate the gas, we add 80_000 gas units Permit buffer to the gas limit
|
|
629
|
-
if (transactionRequest.gas) {
|
|
630
|
-
transactionRequest.gas = transactionRequest.gas + 80_000n
|
|
631
|
-
}
|
|
632
|
-
} finally {
|
|
633
|
-
this.statusManager.updateProcess(step, process.type, 'DONE')
|
|
634
|
-
}
|
|
641
|
+
transactionRequest = await this.estimateTransactionRequest(
|
|
642
|
+
transactionRequest,
|
|
643
|
+
fromChain
|
|
644
|
+
)
|
|
635
645
|
}
|
|
636
|
-
|
|
637
|
-
step,
|
|
638
|
-
process.type,
|
|
639
|
-
'ACTION_REQUIRED'
|
|
640
|
-
)
|
|
646
|
+
|
|
641
647
|
txHash = await getAction(
|
|
642
648
|
this.client,
|
|
643
649
|
sendTransaction,
|
package/src/core/EVM/abi.ts
CHANGED
|
@@ -14,6 +14,8 @@ export const eip2612Abi = parseAbi([
|
|
|
14
14
|
'function name() external view returns (string)',
|
|
15
15
|
'function version() external view returns (string)',
|
|
16
16
|
'function PERMIT_TYPEHASH() external view returns (bytes32)',
|
|
17
|
+
// EIP-5267
|
|
18
|
+
'function eip712Domain() external view returns (bytes1, string, string, uint256, address, bytes32, uint256[])',
|
|
17
19
|
])
|
|
18
20
|
|
|
19
21
|
export const approveAbi = parseAbi([
|