@lifi/sdk 3.6.0-beta.4 → 3.6.0-beta.6

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 (246) hide show
  1. package/package.json +4 -4
  2. package/src/_cjs/config.js +3 -0
  3. package/src/_cjs/config.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 +137 -112
  7. package/src/_cjs/core/EVM/EVMStepExecutor.js.map +1 -1
  8. package/src/_cjs/core/EVM/checkAllowance.js +34 -5
  9. package/src/_cjs/core/EVM/checkAllowance.js.map +1 -1
  10. package/src/_cjs/core/EVM/checkPermitSupport.js +33 -0
  11. package/src/_cjs/core/EVM/checkPermitSupport.js.map +1 -0
  12. package/src/_cjs/core/EVM/parseEVMErrors.js +3 -0
  13. package/src/_cjs/core/EVM/parseEVMErrors.js.map +1 -1
  14. package/src/_cjs/core/EVM/{permit2 → permits}/allowanceTransfer.js.map +1 -1
  15. package/src/_cjs/core/EVM/{permit2 → permits}/constants.js.map +1 -1
  16. package/src/_cjs/core/EVM/{permit2 → permits}/domain.js.map +1 -1
  17. package/src/_cjs/core/EVM/permits/encodeNativePermitData.js +16 -0
  18. package/src/_cjs/core/EVM/permits/encodeNativePermitData.js.map +1 -0
  19. package/src/_cjs/core/EVM/permits/encodePermit2Data.js +32 -0
  20. package/src/_cjs/core/EVM/permits/encodePermit2Data.js.map +1 -0
  21. package/src/_cjs/core/EVM/{getNativePermit.js → permits/getNativePermit.js} +30 -21
  22. package/src/_cjs/core/EVM/permits/getNativePermit.js.map +1 -0
  23. package/src/_cjs/core/EVM/permits/getPermitTransferFromValues.js +24 -0
  24. package/src/_cjs/core/EVM/permits/getPermitTransferFromValues.js.map +1 -0
  25. package/src/_cjs/core/EVM/permits/signNativePermitMessage.js +20 -0
  26. package/src/_cjs/core/EVM/permits/signNativePermitMessage.js.map +1 -0
  27. package/src/_cjs/core/EVM/permits/signPermit2Message.js +43 -0
  28. package/src/_cjs/core/EVM/permits/signPermit2Message.js.map +1 -0
  29. package/src/_cjs/core/EVM/permits/signatureTransfer.js.map +1 -0
  30. package/src/_cjs/core/EVM/permits/types.js +3 -0
  31. package/src/_cjs/core/EVM/permits/types.js.map +1 -0
  32. package/src/_cjs/core/EVM/permits/utils.js +31 -0
  33. package/src/_cjs/core/EVM/permits/utils.js.map +1 -0
  34. package/src/_cjs/core/EVM/publicClient.js +32 -33
  35. package/src/_cjs/core/EVM/publicClient.js.map +1 -1
  36. package/src/_cjs/core/EVM/typeguards.js +1 -1
  37. package/src/_cjs/core/EVM/typeguards.js.map +1 -1
  38. package/src/_cjs/core/EVM/types.js.map +1 -1
  39. package/src/_cjs/core/EVM/utils.js +37 -1
  40. package/src/_cjs/core/EVM/utils.js.map +1 -1
  41. package/src/_cjs/core/EVM/waitForBatchTransactionReceipt.js +3 -2
  42. package/src/_cjs/core/EVM/waitForBatchTransactionReceipt.js.map +1 -1
  43. package/src/_cjs/core/EVM/waitForRelayedTransactionReceipt.js +4 -4
  44. package/src/_cjs/core/EVM/waitForRelayedTransactionReceipt.js.map +1 -1
  45. package/src/_cjs/core/checkBalance.js +2 -1
  46. package/src/_cjs/core/checkBalance.js.map +1 -1
  47. package/src/_cjs/core/utils.js +1 -1
  48. package/src/_cjs/core/utils.js.map +1 -1
  49. package/src/_cjs/errors/constants.js +1 -0
  50. package/src/_cjs/errors/constants.js.map +1 -1
  51. package/src/_cjs/index.js +5 -2
  52. package/src/_cjs/index.js.map +1 -1
  53. package/src/_cjs/services/api.js +18 -6
  54. package/src/_cjs/services/api.js.map +1 -1
  55. package/src/_cjs/version.js +1 -1
  56. package/src/_esm/config.js +3 -0
  57. package/src/_esm/config.js.map +1 -1
  58. package/src/_esm/core/EVM/EVM.js +4 -0
  59. package/src/_esm/core/EVM/EVM.js.map +1 -1
  60. package/src/_esm/core/EVM/EVMStepExecutor.js +142 -125
  61. package/src/_esm/core/EVM/EVMStepExecutor.js.map +1 -1
  62. package/src/_esm/core/EVM/checkAllowance.js +35 -5
  63. package/src/_esm/core/EVM/checkAllowance.js.map +1 -1
  64. package/src/_esm/core/EVM/checkPermitSupport.js +43 -0
  65. package/src/_esm/core/EVM/checkPermitSupport.js.map +1 -0
  66. package/src/_esm/core/EVM/parseEVMErrors.js +9 -0
  67. package/src/_esm/core/EVM/parseEVMErrors.js.map +1 -1
  68. package/src/_esm/core/EVM/{permit2 → permits}/allowanceTransfer.js.map +1 -1
  69. package/src/_esm/core/EVM/{permit2 → permits}/constants.js.map +1 -1
  70. package/src/_esm/core/EVM/{permit2 → permits}/domain.js.map +1 -1
  71. package/src/_esm/core/EVM/permits/encodeNativePermitData.js +12 -0
  72. package/src/_esm/core/EVM/permits/encodeNativePermitData.js.map +1 -0
  73. package/src/_esm/core/EVM/permits/encodePermit2Data.js +28 -0
  74. package/src/_esm/core/EVM/permits/encodePermit2Data.js.map +1 -0
  75. package/src/_esm/core/EVM/{getNativePermit.js → permits/getNativePermit.js} +30 -21
  76. package/src/_esm/core/EVM/permits/getNativePermit.js.map +1 -0
  77. package/src/_esm/core/EVM/permits/getPermitTransferFromValues.js +20 -0
  78. package/src/_esm/core/EVM/permits/getPermitTransferFromValues.js.map +1 -0
  79. package/src/_esm/core/EVM/permits/signNativePermitMessage.js +16 -0
  80. package/src/_esm/core/EVM/permits/signNativePermitMessage.js.map +1 -0
  81. package/src/_esm/core/EVM/permits/signPermit2Message.js +41 -0
  82. package/src/_esm/core/EVM/permits/signPermit2Message.js.map +1 -0
  83. package/src/_esm/core/EVM/{permit2 → permits}/signatureTransfer.js +0 -2
  84. package/src/_esm/core/EVM/{permit2 → permits}/signatureTransfer.js.map +1 -1
  85. package/src/_esm/core/EVM/permits/types.js +2 -0
  86. package/src/_esm/core/EVM/permits/types.js.map +1 -0
  87. package/src/_esm/core/EVM/permits/utils.js +26 -0
  88. package/src/_esm/core/EVM/permits/utils.js.map +1 -0
  89. package/src/_esm/core/EVM/publicClient.js +34 -35
  90. package/src/_esm/core/EVM/publicClient.js.map +1 -1
  91. package/src/_esm/core/EVM/typeguards.js +1 -1
  92. package/src/_esm/core/EVM/typeguards.js.map +1 -1
  93. package/src/_esm/core/EVM/types.js.map +1 -1
  94. package/src/_esm/core/EVM/utils.js +34 -0
  95. package/src/_esm/core/EVM/utils.js.map +1 -1
  96. package/src/_esm/core/EVM/waitForBatchTransactionReceipt.js +5 -2
  97. package/src/_esm/core/EVM/waitForBatchTransactionReceipt.js.map +1 -1
  98. package/src/_esm/core/EVM/waitForRelayedTransactionReceipt.js +4 -4
  99. package/src/_esm/core/EVM/waitForRelayedTransactionReceipt.js.map +1 -1
  100. package/src/_esm/core/checkBalance.js +2 -1
  101. package/src/_esm/core/checkBalance.js.map +1 -1
  102. package/src/_esm/core/utils.js +1 -1
  103. package/src/_esm/core/utils.js.map +1 -1
  104. package/src/_esm/errors/constants.js +1 -0
  105. package/src/_esm/errors/constants.js.map +1 -1
  106. package/src/_esm/index.js +1 -0
  107. package/src/_esm/index.js.map +1 -1
  108. package/src/_esm/services/api.js +18 -6
  109. package/src/_esm/services/api.js.map +1 -1
  110. package/src/_esm/version.js +1 -1
  111. package/src/_types/config.d.ts +2 -1
  112. package/src/_types/config.d.ts.map +1 -1
  113. package/src/_types/core/BaseStepExecutor.d.ts.map +1 -1
  114. package/src/_types/core/EVM/EVM.d.ts.map +1 -1
  115. package/src/_types/core/EVM/EVMStepExecutor.d.ts +4 -10
  116. package/src/_types/core/EVM/EVMStepExecutor.d.ts.map +1 -1
  117. package/src/_types/core/EVM/checkAllowance.d.ts +13 -2
  118. package/src/_types/core/EVM/checkAllowance.d.ts.map +1 -1
  119. package/src/_types/core/EVM/checkPermitSupport.d.ts +27 -0
  120. package/src/_types/core/EVM/checkPermitSupport.d.ts.map +1 -0
  121. package/src/_types/core/EVM/getAllowance.d.ts.map +1 -1
  122. package/src/_types/core/EVM/getENSAddress.d.ts.map +1 -1
  123. package/src/_types/core/EVM/getEVMBalance.d.ts.map +1 -1
  124. package/src/_types/core/EVM/parseEVMErrors.d.ts.map +1 -1
  125. package/src/_types/core/EVM/{permit2 → permits}/allowanceTransfer.d.ts.map +1 -1
  126. package/src/_types/core/EVM/{permit2 → permits}/constants.d.ts.map +1 -1
  127. package/src/_types/core/EVM/permits/domain.d.ts +3 -0
  128. package/src/_types/core/EVM/permits/domain.d.ts.map +1 -0
  129. package/src/_types/core/EVM/permits/encodeNativePermitData.d.ts +3 -0
  130. package/src/_types/core/EVM/permits/encodeNativePermitData.d.ts.map +1 -0
  131. package/src/_types/core/EVM/permits/encodePermit2Data.d.ts +4 -0
  132. package/src/_types/core/EVM/permits/encodePermit2Data.d.ts.map +1 -0
  133. package/src/_types/core/EVM/{getNativePermit.d.ts → permits/getNativePermit.d.ts} +2 -9
  134. package/src/_types/core/EVM/permits/getNativePermit.d.ts.map +1 -0
  135. package/src/_types/core/EVM/permits/getPermitTransferFromValues.d.ts +5 -0
  136. package/src/_types/core/EVM/permits/getPermitTransferFromValues.d.ts.map +1 -0
  137. package/src/_types/core/EVM/permits/signNativePermitMessage.d.ts +4 -0
  138. package/src/_types/core/EVM/permits/signNativePermitMessage.d.ts.map +1 -0
  139. package/src/_types/core/EVM/permits/signPermit2Message.d.ts +21 -0
  140. package/src/_types/core/EVM/permits/signPermit2Message.d.ts.map +1 -0
  141. package/src/_types/core/EVM/{permit2 → permits}/signatureTransfer.d.ts +15 -16
  142. package/src/_types/core/EVM/permits/signatureTransfer.d.ts.map +1 -0
  143. package/src/_types/core/EVM/permits/types.d.ts +24 -0
  144. package/src/_types/core/EVM/permits/types.d.ts.map +1 -0
  145. package/src/_types/core/EVM/permits/utils.d.ts +6 -0
  146. package/src/_types/core/EVM/permits/utils.d.ts.map +1 -0
  147. package/src/_types/core/EVM/publicClient.d.ts.map +1 -1
  148. package/src/_types/core/EVM/setAllowance.d.ts.map +1 -1
  149. package/src/_types/core/EVM/switchChain.d.ts.map +1 -1
  150. package/src/_types/core/EVM/typeguards.d.ts +2 -1
  151. package/src/_types/core/EVM/typeguards.d.ts.map +1 -1
  152. package/src/_types/core/EVM/types.d.ts +13 -7
  153. package/src/_types/core/EVM/types.d.ts.map +1 -1
  154. package/src/_types/core/EVM/utils.d.ts +4 -2
  155. package/src/_types/core/EVM/utils.d.ts.map +1 -1
  156. package/src/_types/core/EVM/waitForBatchTransactionReceipt.d.ts.map +1 -1
  157. package/src/_types/core/EVM/waitForRelayedTransactionReceipt.d.ts.map +1 -1
  158. package/src/_types/core/Solana/SolanaStepExecutor.d.ts.map +1 -1
  159. package/src/_types/core/Solana/getSNSAddress.d.ts.map +1 -1
  160. package/src/_types/core/Solana/getSolanaBalance.d.ts.map +1 -1
  161. package/src/_types/core/Solana/parseSolanaErrors.d.ts.map +1 -1
  162. package/src/_types/core/StatusManager.d.ts.map +1 -1
  163. package/src/_types/core/UTXO/UTXOStepExecutor.d.ts.map +1 -1
  164. package/src/_types/core/UTXO/getUTXOAPIPublicClient.d.ts.map +1 -1
  165. package/src/_types/core/UTXO/getUTXOBalance.d.ts.map +1 -1
  166. package/src/_types/core/UTXO/getUTXOPublicClient.d.ts.map +1 -1
  167. package/src/_types/core/UTXO/parseUTXOErrors.d.ts.map +1 -1
  168. package/src/_types/core/checkBalance.d.ts.map +1 -1
  169. package/src/_types/core/execution.d.ts.map +1 -1
  170. package/src/_types/core/prepareRestart.d.ts.map +1 -1
  171. package/src/_types/core/provider.d.ts.map +1 -1
  172. package/src/_types/core/rpc.d.ts.map +1 -1
  173. package/src/_types/core/stepComparison.d.ts.map +1 -1
  174. package/src/_types/errors/constants.d.ts +2 -1
  175. package/src/_types/errors/constants.d.ts.map +1 -1
  176. package/src/_types/errors/utils/baseErrorRootCause.d.ts.map +1 -1
  177. package/src/_types/errors/utils/rootCause.d.ts.map +1 -1
  178. package/src/_types/index.d.ts +1 -0
  179. package/src/_types/index.d.ts.map +1 -1
  180. package/src/_types/request.d.ts.map +1 -1
  181. package/src/_types/services/api.d.ts +4 -47
  182. package/src/_types/services/api.d.ts.map +1 -1
  183. package/src/_types/services/balance.d.ts.map +1 -1
  184. package/src/_types/services/getNameServiceAddress.d.ts.map +1 -1
  185. package/src/_types/typeguards.d.ts.map +1 -1
  186. package/src/_types/utils/checkPackageUpdates.d.ts.map +1 -1
  187. package/src/_types/utils/convertQuoteToRoute.d.ts.map +1 -1
  188. package/src/_types/utils/fetchTxErrorDetails.d.ts.map +1 -1
  189. package/src/_types/utils/getTransactionMessage.d.ts.map +1 -1
  190. package/src/_types/utils/isZeroAddress.d.ts.map +1 -1
  191. package/src/_types/utils/median.d.ts.map +1 -1
  192. package/src/_types/utils/waitForResult.d.ts.map +1 -1
  193. package/src/_types/version.d.ts +1 -1
  194. package/src/config.ts +4 -1
  195. package/src/core/EVM/EVM.ts +4 -0
  196. package/src/core/EVM/EVMStepExecutor.ts +190 -150
  197. package/src/core/EVM/checkAllowance.ts +69 -6
  198. package/src/core/EVM/checkPermitSupport.ts +74 -0
  199. package/src/core/EVM/parseEVMErrors.ts +9 -0
  200. package/src/core/EVM/{permit2 → permits}/domain.ts +1 -7
  201. package/src/core/EVM/permits/encodeNativePermitData.ts +19 -0
  202. package/src/core/EVM/permits/encodePermit2Data.ts +41 -0
  203. package/src/core/EVM/{getNativePermit.ts → permits/getNativePermit.ts} +37 -31
  204. package/src/core/EVM/permits/getPermitTransferFromValues.ts +29 -0
  205. package/src/core/EVM/permits/signNativePermitMessage.ts +27 -0
  206. package/src/core/EVM/permits/signPermit2Message.ts +95 -0
  207. package/src/core/EVM/{permit2 → permits}/signatureTransfer.ts +19 -7
  208. package/src/core/EVM/permits/types.ts +33 -0
  209. package/src/core/EVM/permits/utils.ts +40 -0
  210. package/src/core/EVM/publicClient.ts +41 -38
  211. package/src/core/EVM/typeguards.ts +5 -2
  212. package/src/core/EVM/types.ts +15 -10
  213. package/src/core/EVM/utils.ts +53 -2
  214. package/src/core/EVM/waitForBatchTransactionReceipt.ts +7 -2
  215. package/src/core/EVM/waitForRelayedTransactionReceipt.ts +4 -4
  216. package/src/core/checkBalance.ts +2 -1
  217. package/src/core/utils.ts +1 -1
  218. package/src/errors/constants.ts +1 -0
  219. package/src/index.ts +1 -0
  220. package/src/services/api.ts +62 -66
  221. package/src/version.ts +1 -1
  222. package/src/_cjs/core/EVM/getNativePermit.js.map +0 -1
  223. package/src/_cjs/core/EVM/permit2/signatureTransfer.js.map +0 -1
  224. package/src/_cjs/core/EVM/signPermitMessage.js +0 -163
  225. package/src/_cjs/core/EVM/signPermitMessage.js.map +0 -1
  226. package/src/_esm/core/EVM/getNativePermit.js.map +0 -1
  227. package/src/_esm/core/EVM/signPermitMessage.js +0 -157
  228. package/src/_esm/core/EVM/signPermitMessage.js.map +0 -1
  229. package/src/_types/core/EVM/getNativePermit.d.ts.map +0 -1
  230. package/src/_types/core/EVM/permit2/domain.d.ts +0 -8
  231. package/src/_types/core/EVM/permit2/domain.d.ts.map +0 -1
  232. package/src/_types/core/EVM/permit2/signatureTransfer.d.ts.map +0 -1
  233. package/src/_types/core/EVM/signPermitMessage.d.ts +0 -25
  234. package/src/_types/core/EVM/signPermitMessage.d.ts.map +0 -1
  235. package/src/core/EVM/signPermitMessage.ts +0 -273
  236. /package/src/_cjs/core/EVM/{permit2 → permits}/allowanceTransfer.js +0 -0
  237. /package/src/_cjs/core/EVM/{permit2 → permits}/constants.js +0 -0
  238. /package/src/_cjs/core/EVM/{permit2 → permits}/domain.js +0 -0
  239. /package/src/_cjs/core/EVM/{permit2 → permits}/signatureTransfer.js +0 -0
  240. /package/src/_esm/core/EVM/{permit2 → permits}/allowanceTransfer.js +0 -0
  241. /package/src/_esm/core/EVM/{permit2 → permits}/constants.js +0 -0
  242. /package/src/_esm/core/EVM/{permit2 → permits}/domain.js +0 -0
  243. /package/src/_types/core/EVM/{permit2 → permits}/allowanceTransfer.d.ts +0 -0
  244. /package/src/_types/core/EVM/{permit2 → permits}/constants.d.ts +0 -0
  245. /package/src/core/EVM/{permit2 → permits}/allowanceTransfer.ts +0 -0
  246. /package/src/core/EVM/{permit2 → permits}/constants.ts +0 -0
@@ -1,4 +1,4 @@
1
- import type { ExtendedChain, LiFiStep } from '@lifi/types'
1
+ import type { ExtendedChain, LiFiStep, SignedPermit } from '@lifi/types'
2
2
  import type {
3
3
  Address,
4
4
  Client,
@@ -31,12 +31,16 @@ import type {
31
31
  } from '../types.js'
32
32
  import { waitForDestinationChainTransaction } from '../waitForDestinationChainTransaction.js'
33
33
  import { checkAllowance } from './checkAllowance.js'
34
- import { getNativePermit } from './getNativePermit.js'
35
34
  import { parseEVMErrors } from './parseEVMErrors.js'
36
- import { type PermitSignature, signPermitMessage } from './signPermitMessage.js'
35
+ import { encodeNativePermitData } from './permits/encodeNativePermitData.js'
36
+ import { encodePermit2Data } from './permits/encodePermit2Data.js'
37
+ import { signPermit2Message } from './permits/signPermit2Message.js'
38
+ import type { NativePermitSignature } from './permits/types.js'
39
+ import { prettifyPermit2Data } from './permits/utils.js'
37
40
  import { switchChain } from './switchChain.js'
38
41
  import { isRelayerStep } from './typeguards.js'
39
- import { getMaxPriorityFeePerGas } from './utils.js'
42
+ import type { Call, EVMPermitStep, TransactionMethodType } from './types.js'
43
+ import { convertExtendedChain, getMaxPriorityFeePerGas } from './utils.js'
40
44
  import {
41
45
  type WalletCallReceipt,
42
46
  waitForBatchTransactionReceipt,
@@ -44,13 +48,6 @@ import {
44
48
  import { waitForRelayedTransactionReceipt } from './waitForRelayedTransactionReceipt.js'
45
49
  import { waitForTransactionReceipt } from './waitForTransactionReceipt.js'
46
50
 
47
- export type Call = {
48
- data?: Hex
49
- to?: Address
50
- value?: bigint
51
- chainId?: number
52
- }
53
-
54
51
  export interface EVMStepExecutorOptions extends StepExecutorOptions {
55
52
  client: Client
56
53
  }
@@ -86,7 +83,9 @@ export class EVMStepExecutor extends BaseStepExecutor {
86
83
  )(undefined)) as GetAddressesReturnType
87
84
  accountAddress = accountAddresses?.[0]
88
85
  }
89
- if (accountAddress !== step.action.fromAddress) {
86
+ if (
87
+ accountAddress?.toLowerCase() !== step.action.fromAddress?.toLowerCase()
88
+ ) {
90
89
  let processToUpdate = process
91
90
  if (!processToUpdate) {
92
91
  // We need to create some process if we don't have one so we can show the error
@@ -121,8 +120,7 @@ export class EVMStepExecutor extends BaseStepExecutor {
121
120
  process,
122
121
  fromChain,
123
122
  toChain,
124
- atomicBatchSupported,
125
- isRelayerTransaction,
123
+ txType,
126
124
  txHash,
127
125
  isBridgeExecution,
128
126
  }: {
@@ -130,32 +128,34 @@ export class EVMStepExecutor extends BaseStepExecutor {
130
128
  process: Process
131
129
  fromChain: ExtendedChain
132
130
  toChain: ExtendedChain
133
- atomicBatchSupported: boolean
134
- isRelayerTransaction: boolean
131
+ txType: TransactionMethodType
135
132
  txHash: Hash
136
133
  isBridgeExecution: boolean
137
134
  }) => {
138
135
  let transactionReceipt: TransactionReceipt | WalletCallReceipt | undefined
139
136
 
140
- if (atomicBatchSupported) {
141
- transactionReceipt = await waitForBatchTransactionReceipt(
142
- this.client,
143
- txHash
144
- )
145
- } else if (isRelayerTransaction) {
146
- transactionReceipt = await waitForRelayedTransactionReceipt(txHash)
147
- } else {
148
- transactionReceipt = await waitForTransactionReceipt({
149
- client: this.client,
150
- chainId: fromChain.id,
151
- txHash,
152
- onReplaced: (response) => {
153
- this.statusManager.updateProcess(step, process.type, 'PENDING', {
154
- txHash: response.transaction.hash,
155
- txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${response.transaction.hash}`,
156
- })
157
- },
158
- })
137
+ switch (txType) {
138
+ case 'batched':
139
+ transactionReceipt = await waitForBatchTransactionReceipt(
140
+ this.client,
141
+ txHash
142
+ )
143
+ break
144
+ case 'relayed':
145
+ transactionReceipt = await waitForRelayedTransactionReceipt(txHash)
146
+ break
147
+ default:
148
+ transactionReceipt = await waitForTransactionReceipt({
149
+ client: this.client,
150
+ chainId: fromChain.id,
151
+ txHash,
152
+ onReplaced: (response) => {
153
+ this.statusManager.updateProcess(step, process.type, 'PENDING', {
154
+ txHash: response.transaction.hash,
155
+ txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${response.transaction.hash}`,
156
+ })
157
+ },
158
+ })
159
159
  }
160
160
 
161
161
  // Update pending process if the transaction hash from the receipt is different.
@@ -239,44 +239,23 @@ export class EVMStepExecutor extends BaseStepExecutor {
239
239
  // Check if step requires permit signature and will be used with relayer service
240
240
  const isRelayerTransaction = isRelayerStep(step)
241
241
 
242
- // Check if token requires approval
243
- // Native tokens (like ETH) don't need approval since they're not ERC20 tokens
244
- // We should support different permit types:
245
- // 1. Native permits (EIP-2612)
246
- // 2. Permit2 - Universal permit implementation by Uniswap (limited to certain chains)
247
- // 3. Standard ERC20 approval
248
- const nativePermit = await getNativePermit(
249
- this.client,
250
- fromChain,
251
- step.action.fromToken.address as Address
252
- )
253
- // Check if proxy contract is available and token supports native permits, not available for atomic batch
254
- const nativePermitSupported =
255
- nativePermit.supported &&
256
- !!fromChain.permit2Proxy &&
257
- !atomicBatchSupported &&
258
- !isRelayerTransaction && // TODO: remove once we support ERC-2771
259
- !isFromNativeToken
260
242
  // Check if chain has Permit2 contract deployed. Permit2 should not be available for atomic batch.
261
243
  const permit2Supported =
262
244
  !!fromChain.permit2 &&
263
245
  !!fromChain.permit2Proxy &&
264
246
  !atomicBatchSupported &&
265
247
  !isFromNativeToken
266
- // Token supports either native permits or Permit2
267
- const permitSupported = permit2Supported || nativePermitSupported
268
248
 
269
249
  const checkForAllowance =
270
- // No existing swap/bridgetransaction is pending
250
+ // No existing swap/bridge transaction is pending
271
251
  !existingProcess?.txHash &&
272
252
  // Token is not native (address is not zero)
273
- !isFromNativeToken &&
274
- // Token doesn't support native permits
275
- !nativePermitSupported
253
+ !isFromNativeToken
276
254
 
255
+ let nativePermitSignature: NativePermitSignature | undefined
277
256
  if (checkForAllowance) {
278
257
  // Check if token needs approval and get approval transaction or message data when available
279
- const data = await checkAllowance({
258
+ const allowanceResult = await checkAllowance({
280
259
  client: this.client,
281
260
  chain: fromChain,
282
261
  step,
@@ -287,17 +266,22 @@ export class EVMStepExecutor extends BaseStepExecutor {
287
266
  permit2Supported,
288
267
  })
289
268
 
290
- if (data) {
269
+ if (allowanceResult.status === 'BATCH_APPROVAL') {
291
270
  // Create approval transaction call
292
271
  // No value needed since we're only approving ERC20 tokens
293
272
  if (atomicBatchSupported) {
294
- calls.push({
295
- chainId: step.action.fromToken.chainId,
296
- to: step.action.fromToken.address as Address,
297
- data,
298
- })
273
+ calls.push(allowanceResult.data)
299
274
  }
300
275
  }
276
+ if (allowanceResult.status === 'NATIVE_PERMIT') {
277
+ nativePermitSignature = allowanceResult.data
278
+ }
279
+ if (
280
+ allowanceResult.status === 'ACTION_REQUIRED' &&
281
+ !this.allowUserInteraction
282
+ ) {
283
+ return step
284
+ }
301
285
  }
302
286
 
303
287
  let process = this.statusManager.findProcess(step, currentProcessType)
@@ -324,14 +308,14 @@ export class EVMStepExecutor extends BaseStepExecutor {
324
308
 
325
309
  // Wait for exiting transaction
326
310
  const txHash = process.txHash as Hash
311
+ const txType = process.txType as TransactionMethodType
327
312
 
328
313
  await this.waitForTransaction({
329
314
  step,
330
315
  process,
331
316
  fromChain,
332
317
  toChain,
333
- atomicBatchSupported,
334
- isRelayerTransaction,
318
+ txType,
335
319
  txHash,
336
320
  isBridgeExecution,
337
321
  })
@@ -339,9 +323,11 @@ export class EVMStepExecutor extends BaseStepExecutor {
339
323
  return step
340
324
  }
341
325
 
326
+ const permitRequired =
327
+ !atomicBatchSupported && !nativePermitSignature && permit2Supported
342
328
  process = this.statusManager.findOrCreateProcess({
343
329
  step,
344
- type: permitSupported ? 'PERMIT' : currentProcessType,
330
+ type: permitRequired ? 'PERMIT' : currentProcessType,
345
331
  status: 'STARTED',
346
332
  })
347
333
 
@@ -351,7 +337,7 @@ export class EVMStepExecutor extends BaseStepExecutor {
351
337
  // Create new transaction request
352
338
  if (!step.transactionRequest) {
353
339
  const { execution, ...stepBase } = step
354
- let updatedStep: LiFiStep
340
+ let updatedStep: LiFiStep | EVMPermitStep
355
341
  if (isRelayerTransaction) {
356
342
  const updatedRelayedStep = await getRelayerQuote({
357
343
  fromChain: stepBase.action.fromChainId,
@@ -365,8 +351,8 @@ export class EVMStepExecutor extends BaseStepExecutor {
365
351
  allowBridges: [stepBase.tool],
366
352
  })
367
353
  updatedStep = {
368
- ...updatedRelayedStep.data.quote.step,
369
- ...updatedRelayedStep.data.quote,
354
+ ...updatedRelayedStep.quote,
355
+ permits: updatedRelayedStep.permits,
370
356
  id: stepBase.id,
371
357
  }
372
358
  } else {
@@ -446,7 +432,7 @@ export class EVMStepExecutor extends BaseStepExecutor {
446
432
  }
447
433
 
448
434
  let txHash: Hash
449
- let isTransactionRelayed = false
435
+ let txType: TransactionMethodType = 'standard'
450
436
 
451
437
  if (atomicBatchSupported) {
452
438
  const transferCall: Call = {
@@ -466,99 +452,154 @@ export class EVMStepExecutor extends BaseStepExecutor {
466
452
  account: this.client.account!,
467
453
  calls,
468
454
  })) as Address
455
+ txType = 'batched'
456
+ } else if (isRelayerTransaction) {
457
+ const permitWitnessTransferFromData = step.permits.find(
458
+ (p) => p.permitType === 'PermitWitnessTransferFrom'
459
+ )
460
+
461
+ if (!permitWitnessTransferFromData) {
462
+ throw new TransactionError(
463
+ LiFiErrorCode.TransactionUnprepared,
464
+ 'Unable to prepare transaction. Permit data for transfer is not found.'
465
+ )
466
+ }
467
+
468
+ const permit2Signature = await signPermit2Message({
469
+ client: this.client,
470
+ chain: fromChain,
471
+ tokenAddress: step.action.fromToken.address as Address,
472
+ amount: BigInt(step.action.fromAmount),
473
+ data: transactionRequest.data as Hex,
474
+ permitData: prettifyPermit2Data(
475
+ permitWitnessTransferFromData.permitData
476
+ ),
477
+ witness: true,
478
+ })
479
+
480
+ this.statusManager.updateProcess(step, process.type, 'DONE')
481
+
482
+ process = this.statusManager.findOrCreateProcess({
483
+ step,
484
+ type: currentProcessType,
485
+ status: 'PENDING',
486
+ })
487
+
488
+ const signedPermits: SignedPermit[] = [
489
+ {
490
+ permitType: 'PermitWitnessTransferFrom',
491
+ permit: permit2Signature.values,
492
+ signature: permit2Signature.signature,
493
+ },
494
+ ]
495
+ // Add native permit if available as first element, order is important
496
+ if (nativePermitSignature) {
497
+ signedPermits.unshift({
498
+ permitType: 'Permit',
499
+ permit: nativePermitSignature.values,
500
+ signature: nativePermitSignature.signature,
501
+ })
502
+ }
503
+
504
+ const relayedTransaction = await relayTransaction({
505
+ tokenOwner: this.client.account!.address,
506
+ chainId: fromChain.id,
507
+ permits: signedPermits,
508
+ callData: transactionRequest.data! as Hex,
509
+ })
510
+ txHash = relayedTransaction.taskId as Hash
511
+ txType = 'relayed'
469
512
  } else {
470
- let permitSignature: PermitSignature | undefined
471
- if (permitSupported) {
472
- permitSignature = await signPermitMessage(this.client, {
473
- transactionRequest,
513
+ if (nativePermitSignature) {
514
+ transactionRequest.data = encodeNativePermitData(
515
+ step.action.fromToken.address as Address,
516
+ BigInt(step.action.fromAmount),
517
+ nativePermitSignature.values.deadline,
518
+ nativePermitSignature.signature,
519
+ transactionRequest.data as Hex
520
+ )
521
+ } else if (permit2Supported) {
522
+ const permit2Signature = await signPermit2Message({
523
+ client: this.client,
474
524
  chain: fromChain,
475
525
  tokenAddress: step.action.fromToken.address as Address,
476
526
  amount: BigInt(step.action.fromAmount),
477
- nativePermit,
478
- permitData: isRelayerTransaction ? step.permitData : undefined,
479
- useWitness: isRelayerTransaction,
527
+ data: transactionRequest.data as Hex,
480
528
  })
481
- transactionRequest.to = fromChain.permit2Proxy
482
529
  this.statusManager.updateProcess(step, process.type, 'DONE')
483
- }
484
- if (isRelayerTransaction && permitSignature) {
530
+
485
531
  process = this.statusManager.findOrCreateProcess({
486
532
  step,
487
533
  type: currentProcessType,
488
534
  status: 'PENDING',
489
535
  })
490
- const relayedTransaction = await relayTransaction({
491
- tokenOwner: this.client.account!.address,
492
- chainId: fromChain.id,
493
- permit: step.permit,
494
- witness: step.witness,
495
- signedPermitData: permitSignature.signature,
496
- callData: transactionRequest.data!,
497
- })
498
- txHash = relayedTransaction.data.taskId
499
- isTransactionRelayed = true
500
- } else {
501
- process = this.statusManager.findOrCreateProcess({
502
- step,
503
- type: currentProcessType,
504
- status: 'STARTED',
505
- })
506
- if (permitSignature) {
507
- // If we have a permit signature, we need to use updated data
508
- transactionRequest.data = permitSignature.data
509
- try {
510
- // Try to re-estimate the gas due to additional Permit data
511
- const estimatedGas = await estimateGas(this.client, {
512
- account: this.client.account!,
513
- to: transactionRequest.to as Address,
514
- data: transactionRequest.data as Hex,
515
- value: transactionRequest.value,
516
- })
517
- transactionRequest.gas =
518
- transactionRequest.gas && transactionRequest.gas > estimatedGas
519
- ? transactionRequest.gas
520
- : estimatedGas
521
- } catch {
522
- // Let the wallet estimate the gas in case of failure
523
- transactionRequest.gas = undefined
524
- }
525
- }
526
- process = this.statusManager.updateProcess(
527
- step,
528
- process.type,
529
- 'ACTION_REQUIRED'
536
+ transactionRequest.data = encodePermit2Data(
537
+ step.action.fromToken.address as Address,
538
+ BigInt(step.action.fromAmount),
539
+ permit2Signature.values.nonce,
540
+ permit2Signature.values.deadline,
541
+ transactionRequest.data as Hex,
542
+ permit2Signature.signature
530
543
  )
531
- txHash = await getAction(
532
- this.client,
533
- sendTransaction,
534
- 'sendTransaction'
535
- )({
536
- to: transactionRequest.to,
537
- account: this.client.account!,
538
- data: transactionRequest.data,
539
- value: transactionRequest.value,
540
- gas: transactionRequest.gas,
541
- gasPrice: transactionRequest.gasPrice,
542
- maxFeePerGas: transactionRequest.maxFeePerGas,
543
- maxPriorityFeePerGas: transactionRequest.maxPriorityFeePerGas,
544
- } as SendTransactionParameters)
545
544
  }
545
+
546
+ if (nativePermitSignature || permit2Supported) {
547
+ try {
548
+ // Target address should be the Permit2 proxy contract in case of native permit or Permit2
549
+ transactionRequest.to = fromChain.permit2Proxy
550
+ // Try to re-estimate the gas due to additional Permit data
551
+ const estimatedGas = await estimateGas(this.client, {
552
+ account: this.client.account!,
553
+ to: transactionRequest.to as Address,
554
+ data: transactionRequest.data as Hex,
555
+ value: transactionRequest.value,
556
+ })
557
+ transactionRequest.gas =
558
+ transactionRequest.gas && transactionRequest.gas > estimatedGas
559
+ ? transactionRequest.gas
560
+ : estimatedGas
561
+ } catch {
562
+ // Let the wallet estimate the gas in case of failure
563
+ transactionRequest.gas = undefined
564
+ } finally {
565
+ this.statusManager.updateProcess(step, process.type, 'DONE')
566
+ }
567
+ }
568
+ process = this.statusManager.updateProcess(
569
+ step,
570
+ process.type,
571
+ 'ACTION_REQUIRED'
572
+ )
573
+ txHash = await getAction(
574
+ this.client,
575
+ sendTransaction,
576
+ 'sendTransaction'
577
+ )({
578
+ to: transactionRequest.to as Address,
579
+ account: this.client.account!,
580
+ data: transactionRequest.data as Hex,
581
+ value: transactionRequest.value,
582
+ gas: transactionRequest.gas,
583
+ gasPrice: transactionRequest.gasPrice,
584
+ maxFeePerGas: transactionRequest.maxFeePerGas,
585
+ maxPriorityFeePerGas: transactionRequest.maxPriorityFeePerGas,
586
+ chain: convertExtendedChain(fromChain),
587
+ } as SendTransactionParameters)
546
588
  }
589
+
547
590
  process = this.statusManager.updateProcess(
548
591
  step,
549
592
  process.type,
550
593
  'PENDING',
551
- // When atomic batch is supported, txHash represents the batch hash rather than an individual transaction hash at this point
552
- atomicBatchSupported
553
- ? {
554
- atomicBatchSupported,
555
- }
556
- : isTransactionRelayed
557
- ? undefined
558
- : {
559
- txHash: txHash,
560
- txLink: `${fromChain.metamask.blockExplorerUrls[0]}tx/${txHash}`,
561
- }
594
+ // When atomic batch or relayer are supported, txHash represents the batch hash or taskId rather than an individual transaction hash
595
+ {
596
+ txHash,
597
+ txType,
598
+ txLink:
599
+ txType === 'standard'
600
+ ? `${fromChain.metamask.blockExplorerUrls[0]}tx/${txHash}`
601
+ : undefined,
602
+ }
562
603
  )
563
604
 
564
605
  await this.waitForTransaction({
@@ -566,9 +607,8 @@ export class EVMStepExecutor extends BaseStepExecutor {
566
607
  process,
567
608
  fromChain,
568
609
  toChain,
569
- atomicBatchSupported,
570
- isRelayerTransaction,
571
610
  txHash,
611
+ txType,
572
612
  isBridgeExecution,
573
613
  })
574
614
 
@@ -5,7 +5,16 @@ import type { StatusManager } from '../StatusManager.js'
5
5
  import type { ExecutionOptions, Process, ProcessType } from '../types.js'
6
6
  import { getAllowance } from './getAllowance.js'
7
7
  import { parseEVMErrors } from './parseEVMErrors.js'
8
+ import { getNativePermit } from './permits/getNativePermit.js'
9
+ import { signNativePermitMessage } from './permits/signNativePermitMessage.js'
10
+ import type {
11
+ NativePermitData,
12
+ NativePermitSignature,
13
+ } from './permits/types.js'
14
+ import { prettifyNativePermitData } from './permits/utils.js'
8
15
  import { setAllowance } from './setAllowance.js'
16
+ import { isRelayerStep } from './typeguards.js'
17
+ import type { Call } from './types.js'
9
18
  import { waitForTransactionReceipt } from './waitForTransactionReceipt.js'
10
19
 
11
20
  export type CheckAllowanceParams = {
@@ -19,6 +28,19 @@ export type CheckAllowanceParams = {
19
28
  permit2Supported?: boolean
20
29
  }
21
30
 
31
+ export type AllowanceResult =
32
+ | {
33
+ status: 'ACTION_REQUIRED' | 'DONE'
34
+ }
35
+ | {
36
+ status: 'BATCH_APPROVAL'
37
+ data: Call
38
+ }
39
+ | {
40
+ status: 'NATIVE_PERMIT'
41
+ data: NativePermitSignature
42
+ }
43
+
22
44
  export const checkAllowance = async ({
23
45
  client,
24
46
  chain,
@@ -28,7 +50,7 @@ export const checkAllowance = async ({
28
50
  allowUserInteraction = false,
29
51
  atomicBatchSupported = false,
30
52
  permit2Supported = false,
31
- }: CheckAllowanceParams): Promise<Hash | void> => {
53
+ }: CheckAllowanceParams): Promise<AllowanceResult> => {
32
54
  // Find existing or create new allowance process
33
55
  const allowanceProcess: Process = statusManager.findOrCreateProcess({
34
56
  step,
@@ -47,7 +69,7 @@ export const checkAllowance = async ({
47
69
  chain,
48
70
  statusManager
49
71
  )
50
- return
72
+ return { status: 'DONE' }
51
73
  }
52
74
 
53
75
  // Start new allowance check
@@ -68,15 +90,47 @@ export const checkAllowance = async ({
68
90
  // Return early if already approved
69
91
  if (fromAmount <= approved) {
70
92
  statusManager.updateProcess(step, allowanceProcess.type, 'DONE')
71
- return
93
+ return { status: 'DONE' }
72
94
  }
73
95
 
74
- if (!allowUserInteraction) {
75
- return
96
+ const isRelayerTransaction = isRelayerStep(step)
97
+
98
+ let nativePermitData: NativePermitData | undefined
99
+ if (isRelayerTransaction) {
100
+ const permitData = step.permits.find(
101
+ (p) => p.permitType === 'Permit'
102
+ )?.permitData
103
+ if (permitData) {
104
+ nativePermitData = prettifyNativePermitData(permitData)
105
+ }
106
+ } else {
107
+ nativePermitData = await getNativePermit(
108
+ client,
109
+ chain,
110
+ step.action.fromToken.address as Address,
111
+ fromAmount
112
+ )
76
113
  }
77
114
 
78
115
  statusManager.updateProcess(step, allowanceProcess.type, 'ACTION_REQUIRED')
79
116
 
117
+ if (!allowUserInteraction) {
118
+ return { status: 'ACTION_REQUIRED' }
119
+ }
120
+
121
+ // Check if proxy contract is available and token supports native permits, not available for atomic batch
122
+ const nativePermitSupported =
123
+ !!nativePermitData && !!chain.permit2Proxy && !atomicBatchSupported
124
+
125
+ if (nativePermitSupported && nativePermitData) {
126
+ const nativePermitSignature = await signNativePermitMessage(
127
+ client,
128
+ nativePermitData
129
+ )
130
+ statusManager.updateProcess(step, allowanceProcess.type, 'DONE')
131
+ return { status: 'NATIVE_PERMIT', data: nativePermitSignature }
132
+ }
133
+
80
134
  // Set new allowance
81
135
  const approveAmount = permit2Supported ? MaxUint256 : fromAmount
82
136
  const approveTxHash = await setAllowance(
@@ -90,7 +144,14 @@ export const checkAllowance = async ({
90
144
 
91
145
  if (atomicBatchSupported) {
92
146
  statusManager.updateProcess(step, allowanceProcess.type, 'DONE')
93
- return approveTxHash
147
+ return {
148
+ status: 'BATCH_APPROVAL',
149
+ data: {
150
+ to: step.action.fromToken.address as Address,
151
+ data: approveTxHash,
152
+ chainId: step.action.fromToken.chainId,
153
+ },
154
+ }
94
155
  }
95
156
 
96
157
  await waitForApprovalTransaction(
@@ -101,6 +162,8 @@ export const checkAllowance = async ({
101
162
  chain,
102
163
  statusManager
103
164
  )
165
+
166
+ return { status: 'DONE' }
104
167
  } catch (e: any) {
105
168
  const error = await parseEVMErrors(e, step, allowanceProcess)
106
169
  statusManager.updateProcess(step, allowanceProcess.type, 'FAILED', {
@@ -0,0 +1,74 @@
1
+ import type { ExtendedChain } from '@lifi/types'
2
+ import { ChainType } from '@lifi/types'
3
+ import type { Address } from 'viem'
4
+ import { config } from '../../config.js'
5
+ import { getAllowance } from './getAllowance.js'
6
+ import { getNativePermit } from './permits/getNativePermit.js'
7
+ import type { NativePermitData } from './permits/types.js'
8
+ import { getPublicClient } from './publicClient.js'
9
+ import type { EVMProvider } from './types.js'
10
+
11
+ export type PermitSupport = {
12
+ /** Whether the token supports EIP-2612 native permits */
13
+ nativePermitSupported: boolean
14
+ /** Whether Permit2 is available and has sufficient allowance */
15
+ permit2AllowanceSufficient: boolean
16
+ }
17
+
18
+ /**
19
+ * Checks what permit types are supported for a token on a specific chain.
20
+ * Checks in order:
21
+ * 1. Native permit (EIP-2612) support
22
+ * 2. Permit2 availability and allowance
23
+ *
24
+ * @param chain - The chain to check permit support on
25
+ * @param tokenAddress - The token address to check
26
+ * @param ownerAddress - The address that would sign the permit
27
+ * @param amount - The amount to check allowance against for Permit2
28
+ * @returns Object indicating which permit types are supported
29
+ */
30
+ export const checkPermitSupport = async ({
31
+ chain,
32
+ tokenAddress,
33
+ ownerAddress,
34
+ amount,
35
+ }: {
36
+ chain: ExtendedChain
37
+ tokenAddress: Address
38
+ ownerAddress: Address
39
+ amount: bigint
40
+ }): Promise<PermitSupport> => {
41
+ const provider = config.getProvider(ChainType.EVM) as EVMProvider | undefined
42
+
43
+ let client = await provider?.getWalletClient?.()
44
+
45
+ if (!client) {
46
+ client = await getPublicClient(chain.id)
47
+ }
48
+
49
+ let nativePermit: NativePermitData | undefined
50
+ // Try with wallet client first, fallback to public client
51
+ try {
52
+ nativePermit = await getNativePermit(client, chain, tokenAddress, amount)
53
+ } catch {
54
+ client = await getPublicClient(chain.id)
55
+ nativePermit = await getNativePermit(client, chain, tokenAddress, amount)
56
+ }
57
+
58
+ let permit2Allowance: bigint | undefined
59
+ // Check Permit2 allowance if available on chain
60
+ if (chain.permit2) {
61
+ permit2Allowance = await getAllowance(
62
+ chain.id,
63
+ tokenAddress,
64
+ ownerAddress,
65
+ chain.permit2 as Address
66
+ )
67
+ }
68
+
69
+ return {
70
+ nativePermitSupported: !!nativePermit,
71
+ permit2AllowanceSufficient:
72
+ !!permit2Allowance && permit2Allowance >= amount,
73
+ }
74
+ }