@lifi/sdk 3.10.1 → 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.
Files changed (78) hide show
  1. package/package.json +1 -1
  2. package/src/_cjs/core/EVM/EVMStepExecutor.js +122 -131
  3. package/src/_cjs/core/EVM/EVMStepExecutor.js.map +1 -1
  4. package/src/_cjs/core/EVM/abi.js +1 -0
  5. package/src/_cjs/core/EVM/abi.js.map +1 -1
  6. package/src/_cjs/core/EVM/checkAllowance.js +126 -44
  7. package/src/_cjs/core/EVM/checkAllowance.js.map +1 -1
  8. package/src/_cjs/core/EVM/permits/getNativePermit.js +123 -16
  9. package/src/_cjs/core/EVM/permits/getNativePermit.js.map +1 -1
  10. package/src/_cjs/core/EVM/permits/isNativePermitValid.js +34 -0
  11. package/src/_cjs/core/EVM/permits/isNativePermitValid.js.map +1 -0
  12. package/src/_cjs/core/EVM/switchChain.js +8 -14
  13. package/src/_cjs/core/EVM/switchChain.js.map +1 -1
  14. package/src/_cjs/core/EVM/utils.js +10 -1
  15. package/src/_cjs/core/EVM/utils.js.map +1 -1
  16. package/src/_cjs/core/execution.js +1 -1
  17. package/src/_cjs/core/execution.js.map +1 -1
  18. package/src/_cjs/core/prepareRestart.js +5 -2
  19. package/src/_cjs/core/prepareRestart.js.map +1 -1
  20. package/src/_cjs/core/processMessages.js +4 -8
  21. package/src/_cjs/core/processMessages.js.map +1 -1
  22. package/src/_cjs/version.js +1 -1
  23. package/src/_cjs/version.js.map +1 -1
  24. package/src/_esm/core/EVM/EVMStepExecutor.js +136 -148
  25. package/src/_esm/core/EVM/EVMStepExecutor.js.map +1 -1
  26. package/src/_esm/core/EVM/abi.js +2 -0
  27. package/src/_esm/core/EVM/abi.js.map +1 -1
  28. package/src/_esm/core/EVM/checkAllowance.js +141 -45
  29. package/src/_esm/core/EVM/checkAllowance.js.map +1 -1
  30. package/src/_esm/core/EVM/permits/getNativePermit.js +144 -21
  31. package/src/_esm/core/EVM/permits/getNativePermit.js.map +1 -1
  32. package/src/_esm/core/EVM/permits/isNativePermitValid.js +41 -0
  33. package/src/_esm/core/EVM/permits/isNativePermitValid.js.map +1 -0
  34. package/src/_esm/core/EVM/switchChain.js +8 -15
  35. package/src/_esm/core/EVM/switchChain.js.map +1 -1
  36. package/src/_esm/core/EVM/utils.js +12 -0
  37. package/src/_esm/core/EVM/utils.js.map +1 -1
  38. package/src/_esm/core/execution.js +1 -1
  39. package/src/_esm/core/execution.js.map +1 -1
  40. package/src/_esm/core/prepareRestart.js +6 -3
  41. package/src/_esm/core/prepareRestart.js.map +1 -1
  42. package/src/_esm/core/processMessages.js +4 -8
  43. package/src/_esm/core/processMessages.js.map +1 -1
  44. package/src/_esm/version.js +1 -1
  45. package/src/_esm/version.js.map +1 -1
  46. package/src/_types/core/EVM/EVMStepExecutor.d.ts +3 -2
  47. package/src/_types/core/EVM/EVMStepExecutor.d.ts.map +1 -1
  48. package/src/_types/core/EVM/abi.d.ts +20 -0
  49. package/src/_types/core/EVM/abi.d.ts.map +1 -1
  50. package/src/_types/core/EVM/checkAllowance.d.ts +10 -7
  51. package/src/_types/core/EVM/checkAllowance.d.ts.map +1 -1
  52. package/src/_types/core/EVM/permits/getNativePermit.d.ts +2 -2
  53. package/src/_types/core/EVM/permits/getNativePermit.d.ts.map +1 -1
  54. package/src/_types/core/EVM/permits/isNativePermitValid.d.ts +6 -0
  55. package/src/_types/core/EVM/permits/isNativePermitValid.d.ts.map +1 -0
  56. package/src/_types/core/EVM/switchChain.d.ts +2 -2
  57. package/src/_types/core/EVM/switchChain.d.ts.map +1 -1
  58. package/src/_types/core/EVM/utils.d.ts +6 -1
  59. package/src/_types/core/EVM/utils.d.ts.map +1 -1
  60. package/src/_types/core/prepareRestart.d.ts +1 -1
  61. package/src/_types/core/prepareRestart.d.ts.map +1 -1
  62. package/src/_types/core/processMessages.d.ts.map +1 -1
  63. package/src/_types/core/types.d.ts +2 -2
  64. package/src/_types/core/types.d.ts.map +1 -1
  65. package/src/_types/version.d.ts +1 -1
  66. package/src/_types/version.d.ts.map +1 -1
  67. package/src/core/EVM/EVMStepExecutor.ts +203 -197
  68. package/src/core/EVM/abi.ts +2 -0
  69. package/src/core/EVM/checkAllowance.ts +206 -63
  70. package/src/core/EVM/permits/getNativePermit.ts +189 -22
  71. package/src/core/EVM/permits/isNativePermitValid.ts +57 -0
  72. package/src/core/EVM/switchChain.ts +14 -22
  73. package/src/core/EVM/utils.ts +17 -1
  74. package/src/core/execution.ts +1 -1
  75. package/src/core/prepareRestart.ts +6 -3
  76. package/src/core/processMessages.ts +4 -8
  77. package/src/core/types.ts +1 -2
  78. package/src/version.ts +1 -1
@@ -0,0 +1,57 @@
1
+ import type { SignedTypedData, TypedData } from '@lifi/types'
2
+
3
+ /**
4
+ * Checks if an existing native permit is valid for the given requirements
5
+ */
6
+ export const isNativePermitValid = (
7
+ permit: SignedTypedData,
8
+ typedData: TypedData
9
+ ): boolean => {
10
+ // Only check native permits (EIP-2612)
11
+ if (permit.primaryType !== 'Permit') {
12
+ return false
13
+ }
14
+
15
+ // Check if the permit is for the correct chain
16
+ if (
17
+ permit.domain.chainId !== typedData.domain.chainId ||
18
+ (permit.domain.salt && permit.domain.salt !== typedData.domain.salt)
19
+ ) {
20
+ return false
21
+ }
22
+
23
+ // Check if the permit message has the required fields
24
+ const message = permit.message as any
25
+ if (!message) {
26
+ return false
27
+ }
28
+
29
+ // Check spender
30
+ if (
31
+ message.spender?.toLowerCase() !== typedData.message.spender?.toLowerCase()
32
+ ) {
33
+ return false
34
+ }
35
+
36
+ // Check owner
37
+ if (message.owner?.toLowerCase() !== typedData.message.owner?.toLowerCase()) {
38
+ return false
39
+ }
40
+
41
+ // Check amount (value field in native permits)
42
+ const permitAmount = BigInt(message.value || 0)
43
+ if (permitAmount < BigInt(typedData.message.value || 0)) {
44
+ return false
45
+ }
46
+
47
+ // Check deadline (must have at least 5 minutes remaining)
48
+ const deadlineTimestamp = parseInt(message.deadline || 0, 10)
49
+ // Add 5 minutes bufferto the current timestamp
50
+ const allowedTimestamp = Math.floor(Date.now() / 1000) + 5 * 60
51
+
52
+ if (deadlineTimestamp <= allowedTimestamp) {
53
+ return false
54
+ }
55
+
56
+ return true
57
+ }
@@ -4,7 +4,7 @@ import { getAction } from 'viem/utils'
4
4
  import { LiFiErrorCode } from '../../errors/constants.js'
5
5
  import { ProviderError } from '../../errors/errors.js'
6
6
  import type { StatusManager } from '../StatusManager.js'
7
- import type { LiFiStepExtended, SwitchChainHook } from '../types.js'
7
+ import type { ExecutionOptions, LiFiStepExtended, Process } from '../types.js'
8
8
 
9
9
  /**
10
10
  * This method checks whether the wallet client is configured for the correct chain.
@@ -27,8 +27,10 @@ export const switchChain = async (
27
27
  client: Client,
28
28
  statusManager: StatusManager,
29
29
  step: LiFiStepExtended,
30
+ process: Process,
31
+ targetChainId: number,
30
32
  allowUserInteraction: boolean,
31
- switchChainHook?: SwitchChainHook
33
+ executionOptions?: ExecutionOptions
32
34
  ): Promise<Client | undefined> => {
33
35
  // if we are already on the correct chain we can proceed directly
34
36
  const currentChainId = (await getAction(
@@ -36,26 +38,22 @@ export const switchChain = async (
36
38
  getChainId,
37
39
  'getChainId'
38
40
  )(undefined)) as GetChainIdReturnType
39
- if (currentChainId === step.action.fromChainId) {
41
+ if (currentChainId === targetChainId) {
40
42
  return client
41
43
  }
42
44
 
43
- // -> set status message
44
- step.execution = statusManager.initExecutionObject(step)
45
- statusManager.updateExecution(step, 'ACTION_REQUIRED')
46
-
47
- let switchProcess = statusManager.findOrCreateProcess({
48
- step,
49
- type: 'SWITCH_CHAIN',
50
- status: 'ACTION_REQUIRED',
51
- })
52
-
53
45
  if (!allowUserInteraction) {
54
46
  return
55
47
  }
56
48
 
57
49
  try {
58
- const updatedClient = await switchChainHook?.(step.action.fromChainId)
50
+ if (!executionOptions?.switchChainHook) {
51
+ throw new ProviderError(
52
+ LiFiErrorCode.ChainSwitchError,
53
+ 'Chain switch hook is not provided.'
54
+ )
55
+ }
56
+ const updatedClient = await executionOptions.switchChainHook(targetChainId)
59
57
  let updatedChainId: number | undefined
60
58
  if (updatedClient) {
61
59
  updatedChainId = (await getAction(
@@ -64,22 +62,16 @@ export const switchChain = async (
64
62
  'getChainId'
65
63
  )(undefined)) as GetChainIdReturnType
66
64
  }
67
- if (updatedChainId !== step.action.fromChainId) {
65
+ if (updatedChainId !== targetChainId) {
68
66
  throw new ProviderError(
69
67
  LiFiErrorCode.ChainSwitchError,
70
68
  'Chain switch required.'
71
69
  )
72
70
  }
73
71
 
74
- switchProcess = statusManager.updateProcess(
75
- step,
76
- switchProcess.type,
77
- 'DONE'
78
- )
79
- statusManager.updateExecution(step, 'PENDING')
80
72
  return updatedClient
81
73
  } catch (error: any) {
82
- statusManager.updateProcess(step, switchProcess.type, 'FAILED', {
74
+ statusManager.updateProcess(step, process.type, 'FAILED', {
83
75
  error: {
84
76
  message: error.message,
85
77
  code: LiFiErrorCode.ChainSwitchError,
@@ -1,5 +1,6 @@
1
1
  import type { ChainId, ExtendedChain } from '@lifi/types'
2
- import type { Address, Chain, Client, Transaction } from 'viem'
2
+ import type { Address, Chain, Client, Hex, Transaction } from 'viem'
3
+ import { pad, toHex } from 'viem'
3
4
  import { getBlock } from 'viem/actions'
4
5
  import { config } from '../../config.js'
5
6
  import { median } from '../../utils/median.js'
@@ -100,3 +101,18 @@ export const retryDelay = ({ count }: { count: number; error: Error }) =>
100
101
  Math.min(~~(1 << count) * 200, 3000)
101
102
 
102
103
  export const retryCount = 30
104
+
105
+ /**
106
+ * Helper function to check if a domain salt matches a chainId.
107
+ * The salt is a padded hex string representation of the chainId.
108
+ */
109
+ export const isSaltMatchingChainId = (
110
+ salt: Hex | undefined,
111
+ chainId: number
112
+ ): boolean => {
113
+ if (!salt) {
114
+ return false
115
+ }
116
+ const paddedChainId = pad(toHex(chainId), { size: 32 })
117
+ return salt.toLowerCase() === paddedChainId.toLowerCase()
118
+ }
@@ -66,7 +66,7 @@ export const resumeRoute = async (
66
66
  }
67
67
  }
68
68
 
69
- await prepareRestart(route)
69
+ prepareRestart(route)
70
70
 
71
71
  return executeRoute(route, executionOptions)
72
72
  }
@@ -1,13 +1,16 @@
1
1
  import type { RouteExtended } from './types.js'
2
2
 
3
- export const prepareRestart = async (route: RouteExtended) => {
3
+ export const prepareRestart = (route: RouteExtended) => {
4
4
  for (let index = 0; index < route.steps.length; index++) {
5
5
  const step = route.steps[index]
6
6
  if (step.execution) {
7
- // Find the index of the last process that has tx hash
7
+ // Find the index of the last process that has tx hash, taskId, or signed messages
8
8
  const lastValidIndex = step.execution.process.findLastIndex(
9
9
  (process) =>
10
- (!!process.txHash || !!process.taskId) && process.status !== 'FAILED'
10
+ (!!process.txHash ||
11
+ !!process.taskId ||
12
+ !!process.signedTypedData?.length) &&
13
+ process.status !== 'FAILED'
11
14
  )
12
15
 
13
16
  // Keep all processes up to the one with tx hash
@@ -10,20 +10,17 @@ const processMessages: Record<
10
10
  PENDING: 'Waiting for token allowance',
11
11
  DONE: 'Token allowance set',
12
12
  },
13
- SWITCH_CHAIN: {
14
- ACTION_REQUIRED: 'Chain switch required',
15
- PENDING: 'Waiting for chain switch',
16
- DONE: 'Chain switched',
17
- },
18
13
  SWAP: {
19
14
  STARTED: 'Preparing swap transaction',
20
- ACTION_REQUIRED: 'Please sign the transaction',
15
+ ACTION_REQUIRED: 'Sign swap transaction',
16
+ MESSAGE_REQUIRED: 'Sign swap message',
21
17
  PENDING: 'Waiting for swap transaction',
22
18
  DONE: 'Swap completed',
23
19
  },
24
20
  CROSS_CHAIN: {
25
21
  STARTED: 'Preparing bridge transaction',
26
- ACTION_REQUIRED: 'Please sign the transaction',
22
+ ACTION_REQUIRED: 'Sign bridge transaction',
23
+ MESSAGE_REQUIRED: 'Sign bridge message',
27
24
  PENDING: 'Waiting for bridge transaction',
28
25
  DONE: 'Bridge transaction confirmed',
29
26
  },
@@ -37,7 +34,6 @@ const processMessages: Record<
37
34
  PENDING: 'Waiting for permit message',
38
35
  DONE: 'Permit message signed',
39
36
  },
40
- TRANSACTION: {},
41
37
  }
42
38
  const substatusMessages: Record<
43
39
  StatusMessage,
package/src/core/types.ts CHANGED
@@ -132,6 +132,7 @@ export type ExecutionStatus = 'ACTION_REQUIRED' | 'PENDING' | 'FAILED' | 'DONE'
132
132
  export type ProcessStatus =
133
133
  | 'STARTED'
134
134
  | 'ACTION_REQUIRED'
135
+ | 'MESSAGE_REQUIRED'
135
136
  | 'PENDING'
136
137
  | 'FAILED'
137
138
  | 'DONE'
@@ -140,11 +141,9 @@ export type ProcessStatus =
140
141
  export type ProcessType =
141
142
  | 'TOKEN_ALLOWANCE'
142
143
  | 'PERMIT'
143
- | 'SWITCH_CHAIN'
144
144
  | 'SWAP'
145
145
  | 'CROSS_CHAIN'
146
146
  | 'RECEIVING_CHAIN'
147
- | 'TRANSACTION'
148
147
 
149
148
  export type Process = {
150
149
  type: ProcessType
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export const name = '@lifi/sdk'
2
- export const version = '3.10.1'
2
+ export const version = '3.11.0-beta.0'