@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
@@ -0,0 +1,214 @@
1
+ import { hashTypedData } from 'viem'
2
+ import type { Address, TypedData, TypedDataDomain } from 'viem'
3
+ import { invariant } from '../../../utils/invariant.js'
4
+ import {
5
+ MaxSigDeadline,
6
+ MaxSignatureTransferAmount,
7
+ MaxUnorderedNonce,
8
+ } from './constants.js'
9
+ import { permit2Domain } from './domain.js'
10
+
11
+ export interface Witness {
12
+ witness: any
13
+ witnessTypeName: string
14
+ witnessType: { [key: string]: { name: string; type: string }[] }
15
+ }
16
+
17
+ export interface TokenPermissions {
18
+ token: Address
19
+ amount: bigint
20
+ }
21
+
22
+ export interface PermitTransferFrom {
23
+ permitted: TokenPermissions
24
+ spender: Address
25
+ nonce: bigint
26
+ deadline: bigint
27
+ }
28
+
29
+ export interface PermitBatchTransferFrom {
30
+ permitted: TokenPermissions[]
31
+ spender: Address
32
+ nonce: bigint
33
+ deadline: bigint
34
+ }
35
+
36
+ export type PermitTransferFromData = {
37
+ domain: TypedDataDomain
38
+ types: TypedData
39
+ values: PermitTransferFrom
40
+ }
41
+
42
+ export type PermitBatchTransferFromData = {
43
+ domain: TypedDataDomain
44
+ types: TypedData
45
+ values: PermitBatchTransferFrom
46
+ }
47
+
48
+ const TOKEN_PERMISSIONS = [
49
+ { name: 'token', type: 'address' },
50
+ { name: 'amount', type: 'uint256' },
51
+ ] as const
52
+
53
+ const PERMIT_TRANSFER_FROM_TYPES = {
54
+ TokenPermissions: TOKEN_PERMISSIONS,
55
+ PermitTransferFrom: [
56
+ { name: 'permitted', type: 'TokenPermissions' },
57
+ { name: 'spender', type: 'address' },
58
+ { name: 'nonce', type: 'uint256' },
59
+ { name: 'deadline', type: 'uint256' },
60
+ ],
61
+ } as const
62
+
63
+ const PERMIT_BATCH_TRANSFER_FROM_TYPES = {
64
+ TokenPermissions: TOKEN_PERMISSIONS,
65
+ PermitBatchTransferFrom: [
66
+ { name: 'permitted', type: 'TokenPermissions[]' },
67
+ { name: 'spender', type: 'address' },
68
+ { name: 'nonce', type: 'uint256' },
69
+ { name: 'deadline', type: 'uint256' },
70
+ ],
71
+ } as const
72
+
73
+ function isPermitTransferFrom(
74
+ permit: PermitTransferFrom | PermitBatchTransferFrom
75
+ ): permit is PermitTransferFrom {
76
+ return !Array.isArray(permit.permitted)
77
+ }
78
+
79
+ export function getPermitTransferData(
80
+ permit: PermitTransferFrom,
81
+ permit2Address: Address,
82
+ chainId: number,
83
+ witness?: Witness
84
+ ): PermitTransferFromData {
85
+ invariant(MaxSigDeadline >= permit.deadline, 'SIG_DEADLINE_OUT_OF_RANGE')
86
+ invariant(MaxUnorderedNonce >= permit.nonce, 'NONCE_OUT_OF_RANGE')
87
+
88
+ const domain = permit2Domain(permit2Address, chainId)
89
+
90
+ validateTokenPermissions(permit.permitted)
91
+
92
+ const types = witness
93
+ ? ({
94
+ TokenPermissions: TOKEN_PERMISSIONS,
95
+ ...witness.witnessType,
96
+ PermitWitnessTransferFrom: [
97
+ { name: 'permitted', type: 'TokenPermissions' },
98
+ { name: 'spender', type: 'address' },
99
+ { name: 'nonce', type: 'uint256' },
100
+ { name: 'deadline', type: 'uint256' },
101
+ { name: 'witness', type: witness.witnessTypeName },
102
+ ],
103
+ } as const)
104
+ : PERMIT_TRANSFER_FROM_TYPES
105
+
106
+ const values = witness
107
+ ? Object.assign(permit, { witness: witness.witness })
108
+ : permit
109
+
110
+ return {
111
+ domain,
112
+ types,
113
+ values,
114
+ }
115
+ }
116
+
117
+ export function getPermitBatchTransferData(
118
+ permit: PermitBatchTransferFrom,
119
+ permit2Address: Address,
120
+ chainId: number,
121
+ witness?: Witness
122
+ ): PermitBatchTransferFromData {
123
+ invariant(MaxSigDeadline >= permit.deadline, 'SIG_DEADLINE_OUT_OF_RANGE')
124
+ invariant(MaxUnorderedNonce >= permit.nonce, 'NONCE_OUT_OF_RANGE')
125
+
126
+ const domain = permit2Domain(permit2Address, chainId)
127
+
128
+ permit.permitted.forEach(validateTokenPermissions)
129
+
130
+ const types = witness
131
+ ? {
132
+ ...witness.witnessType,
133
+ TokenPermissions: TOKEN_PERMISSIONS,
134
+ PermitBatchWitnessTransferFrom: [
135
+ { name: 'permitted', type: 'TokenPermissions[]' },
136
+ { name: 'spender', type: 'address' },
137
+ { name: 'nonce', type: 'uint256' },
138
+ { name: 'deadline', type: 'uint256' },
139
+ { name: 'witness', type: witness.witnessTypeName },
140
+ ],
141
+ }
142
+ : PERMIT_BATCH_TRANSFER_FROM_TYPES
143
+
144
+ const values = witness
145
+ ? Object.assign(permit, { witness: witness.witness })
146
+ : permit
147
+
148
+ return {
149
+ domain,
150
+ types,
151
+ values,
152
+ }
153
+ }
154
+
155
+ // return the data to be sent in a eth_signTypedData RPC call
156
+ // for signing the given permit data
157
+ export function getPermitData(
158
+ permit: PermitTransferFrom | PermitBatchTransferFrom,
159
+ permit2Address: Address,
160
+ chainId: number,
161
+ witness?: Witness
162
+ ): PermitTransferFromData | PermitBatchTransferFromData {
163
+ if (isPermitTransferFrom(permit)) {
164
+ return getPermitTransferData(permit, permit2Address, chainId, witness)
165
+ }
166
+ return getPermitBatchTransferData(permit, permit2Address, chainId, witness)
167
+ }
168
+
169
+ export function hash(
170
+ permit: PermitTransferFrom | PermitBatchTransferFrom,
171
+ permit2Address: Address,
172
+ chainId: number,
173
+ witness?: Witness
174
+ ) {
175
+ if (isPermitTransferFrom(permit)) {
176
+ const { domain, types, values } = getPermitTransferData(
177
+ permit,
178
+ permit2Address,
179
+ chainId,
180
+ witness
181
+ )
182
+
183
+ return hashTypedData({
184
+ domain,
185
+ types,
186
+ primaryType: witness ? 'PermitWitnessTransferFrom' : 'PermitTransferFrom',
187
+ message: {
188
+ ...values,
189
+ },
190
+ })
191
+ }
192
+ const { domain, types, values } = getPermitBatchTransferData(
193
+ permit,
194
+ permit2Address,
195
+ chainId,
196
+ witness
197
+ )
198
+
199
+ return hashTypedData({
200
+ domain,
201
+ types,
202
+ primaryType: witness
203
+ ? 'PermitBatchWitnessTransferFrom'
204
+ : 'PermitBatchTransferFrom',
205
+ message: { ...values },
206
+ })
207
+ }
208
+
209
+ function validateTokenPermissions(permissions: TokenPermissions) {
210
+ invariant(
211
+ MaxSignatureTransferAmount >= permissions.amount,
212
+ 'AMOUNT_OUT_OF_RANGE'
213
+ )
214
+ }
@@ -1,4 +1,4 @@
1
- import type { Client, Hash, SendTransactionParameters } from 'viem'
1
+ import type { Address, Client, Hash, SendTransactionParameters } from 'viem'
2
2
  import { encodeFunctionData } from 'viem'
3
3
  import { sendTransaction } from 'viem/actions'
4
4
  import { isNativeTokenAddress } from '../../utils/isZeroAddress.js'
@@ -10,10 +10,10 @@ import { getMaxPriorityFeePerGas } from './utils.js'
10
10
 
11
11
  export const setAllowance = async (
12
12
  client: Client,
13
- tokenAddress: string,
14
- contractAddress: string,
13
+ tokenAddress: Address,
14
+ contractAddress: Address,
15
15
  amount: bigint,
16
- settings?: ExecutionOptions,
16
+ executionOptions?: ExecutionOptions,
17
17
  returnPopulatedTransaction?: boolean
18
18
  ): Promise<Hash> => {
19
19
  const data = encodeFunctionData({
@@ -35,9 +35,9 @@ export const setAllowance = async (
35
35
  : undefined,
36
36
  }
37
37
 
38
- if (settings?.updateTransactionRequestHook) {
38
+ if (executionOptions?.updateTransactionRequestHook) {
39
39
  const customizedTransactionRequest: TransactionParameters =
40
- await settings.updateTransactionRequestHook({
40
+ await executionOptions.updateTransactionRequestHook({
41
41
  requestType: 'approve',
42
42
  ...transactionRequest,
43
43
  })
@@ -56,7 +56,6 @@ export const setAllowance = async (
56
56
  gasPrice: transactionRequest.gasPrice,
57
57
  maxFeePerGas: transactionRequest.maxFeePerGas,
58
58
  maxPriorityFeePerGas: transactionRequest.maxPriorityFeePerGas,
59
- chain: null,
60
59
  } as SendTransactionParameters)
61
60
  }
62
61
 
@@ -81,16 +80,16 @@ export const setTokenAllowance = async ({
81
80
  }
82
81
  const approvedAmount = await getAllowance(
83
82
  token.chainId,
84
- token.address,
83
+ token.address as Address,
85
84
  walletClient.account!.address,
86
- spenderAddress
85
+ spenderAddress as Address
87
86
  )
88
87
 
89
88
  if (amount > approvedAmount) {
90
89
  const approveTx = await setAllowance(
91
90
  walletClient,
92
- token.address,
93
- spenderAddress,
91
+ token.address as Address,
92
+ spenderAddress as Address,
94
93
  amount
95
94
  )
96
95
 
@@ -117,15 +116,15 @@ export const revokeTokenApproval = async ({
117
116
  }
118
117
  const approvedAmount = await getAllowance(
119
118
  token.chainId,
120
- token.address,
119
+ token.address as Address,
121
120
  walletClient.account!.address,
122
- spenderAddress
121
+ spenderAddress as Address
123
122
  )
124
123
  if (approvedAmount > 0) {
125
124
  const approveTx = await setAllowance(
126
125
  walletClient,
127
- token.address,
128
- spenderAddress,
126
+ token.address as Address,
127
+ spenderAddress as Address,
129
128
  0n
130
129
  )
131
130
 
@@ -0,0 +1,248 @@
1
+ import type { ExtendedChain } from '@lifi/types'
2
+ import type { Client, Hex } from 'viem'
3
+ import { encodeFunctionData } from 'viem'
4
+ import { parseSignature } from 'viem'
5
+ import type { Address } from 'viem'
6
+ import { keccak256 } from 'viem'
7
+ import { readContract, signTypedData } from 'viem/actions'
8
+ import type { TransactionParameters } from '../types.js'
9
+ import { eip2612Types, permit2ProxyAbi } from './abi.js'
10
+ import { type NativePermitData, getNativePermit } from './getNativePermit.js'
11
+ import {
12
+ type PermitTransferFrom,
13
+ getPermitData,
14
+ } from './permit2/signatureTransfer.js'
15
+
16
+ export const signNativePermitMessage = async (
17
+ client: Client,
18
+ transactionRequest: TransactionParameters,
19
+ chain: ExtendedChain,
20
+ tokenAddress: Address,
21
+ amount: bigint,
22
+ nativePermit: NativePermitData
23
+ ) => {
24
+ const deadline = BigInt(Math.floor(Date.now() / 1000) + 30 * 60) // 30 minutes
25
+
26
+ const domain = {
27
+ name: nativePermit.name,
28
+ version: nativePermit.version,
29
+ chainId: chain.id,
30
+ verifyingContract: tokenAddress,
31
+ }
32
+
33
+ const message = {
34
+ owner: client.account!.address,
35
+ spender: chain.permit2Proxy as Address,
36
+ value: amount,
37
+ nonce: nativePermit.nonce,
38
+ deadline,
39
+ }
40
+
41
+ const signature = await signTypedData(client, {
42
+ account: client.account!,
43
+ domain,
44
+ types: eip2612Types,
45
+ primaryType: 'Permit',
46
+ message,
47
+ })
48
+
49
+ const { v, r, s } = parseSignature(signature)
50
+
51
+ const data = encodeFunctionData({
52
+ abi: permit2ProxyAbi,
53
+ functionName: 'callDiamondWithEIP2612Signature',
54
+ args: [
55
+ tokenAddress,
56
+ amount,
57
+ deadline,
58
+ Number(v),
59
+ r,
60
+ s,
61
+ transactionRequest.data as Hex,
62
+ ],
63
+ })
64
+
65
+ return {
66
+ signature,
67
+ data,
68
+ }
69
+ }
70
+
71
+ export const signPermit2Message = async (
72
+ client: Client,
73
+ transactionRequest: TransactionParameters,
74
+ chain: ExtendedChain,
75
+ tokenAddress: Address,
76
+ amount: bigint
77
+ ) => {
78
+ const nonce = await readContract(client, {
79
+ address: chain.permit2Proxy as Address,
80
+ abi: permit2ProxyAbi,
81
+ functionName: 'nextNonce',
82
+ args: [client.account!.address],
83
+ })
84
+
85
+ const permitTransferFrom: PermitTransferFrom = {
86
+ permitted: {
87
+ token: tokenAddress,
88
+ amount: amount,
89
+ },
90
+ spender: chain.permit2Proxy as Address,
91
+ nonce: nonce,
92
+ deadline: BigInt(Math.floor(Date.now() / 1000) + 30 * 60), // 30 minutes
93
+ }
94
+
95
+ const { domain, types, values } = getPermitData(
96
+ permitTransferFrom,
97
+ chain.permit2 as Address,
98
+ chain.id
99
+ )
100
+
101
+ const signature = await signTypedData(client, {
102
+ account: client.account!,
103
+ primaryType: 'PermitTransferFrom',
104
+ domain,
105
+ types,
106
+ message: { ...values },
107
+ })
108
+
109
+ const data = encodeFunctionData({
110
+ abi: permit2ProxyAbi,
111
+ functionName: 'callDiamondWithPermit2',
112
+ args: [
113
+ transactionRequest.data as Hex,
114
+ [
115
+ [tokenAddress, amount],
116
+ permitTransferFrom.nonce,
117
+ permitTransferFrom.deadline,
118
+ ],
119
+ signature as Hex,
120
+ ],
121
+ })
122
+
123
+ return {
124
+ signature,
125
+ data,
126
+ }
127
+ }
128
+
129
+ export const signPermit2WitnessMessage = async (
130
+ client: Client,
131
+ transactionRequest: TransactionParameters,
132
+ chain: ExtendedChain,
133
+ tokenAddress: Address,
134
+ amount: bigint
135
+ ) => {
136
+ const nonce = await readContract(client, {
137
+ address: chain.permit2Proxy as Address,
138
+ abi: permit2ProxyAbi,
139
+ functionName: 'nextNonce',
140
+ args: [client.account!.address],
141
+ })
142
+
143
+ const permitTransferFrom: PermitTransferFrom = {
144
+ permitted: {
145
+ token: tokenAddress,
146
+ amount: amount,
147
+ },
148
+ spender: chain.permit2Proxy as Address,
149
+ nonce: nonce,
150
+ deadline: BigInt(Math.floor(Date.now() / 1000) + 30 * 60), // 30 minutes
151
+ }
152
+
153
+ // Create witness data for the LI.FI call
154
+ const witness = {
155
+ witness: {
156
+ tokenReceiver: chain.permit2Proxy as Address,
157
+ diamondAddress: chain.diamondAddress as Address,
158
+ diamondCalldataHash: keccak256(transactionRequest.data as Hex),
159
+ },
160
+ witnessTypeName: 'LiFiCall',
161
+ witnessType: {
162
+ LiFiCall: [
163
+ { name: 'diamondAddress', type: 'address' },
164
+ { name: 'diamondCalldataHash', type: 'bytes32' },
165
+ ],
166
+ },
167
+ }
168
+
169
+ const { domain, types, values } = getPermitData(
170
+ permitTransferFrom,
171
+ chain.permit2 as Address,
172
+ chain.id,
173
+ witness
174
+ )
175
+
176
+ const signature = await signTypedData(client, {
177
+ account: client.account!,
178
+ primaryType: 'PermitWitnessTransferFrom',
179
+ domain,
180
+ types,
181
+ message: { ...values },
182
+ })
183
+
184
+ const data = encodeFunctionData({
185
+ abi: permit2ProxyAbi,
186
+ functionName: 'callDiamondWithPermit2Witness',
187
+ args: [
188
+ transactionRequest.data as Hex,
189
+ client.account!.address,
190
+ [
191
+ [tokenAddress, amount],
192
+ permitTransferFrom.nonce,
193
+ permitTransferFrom.deadline,
194
+ ],
195
+ signature as Hex,
196
+ ],
197
+ })
198
+
199
+ return {
200
+ signature,
201
+ data,
202
+ }
203
+ }
204
+
205
+ export const signPermitMessage = async (
206
+ client: Client,
207
+ transactionRequest: TransactionParameters,
208
+ chain: ExtendedChain,
209
+ tokenAddress: Address,
210
+ amount: bigint,
211
+ nativePermit?: NativePermitData,
212
+ useWitness = false
213
+ ) => {
214
+ let _nativePermit = nativePermit
215
+
216
+ if (!_nativePermit) {
217
+ _nativePermit = await getNativePermit(client, chain, tokenAddress)
218
+ }
219
+
220
+ if (_nativePermit.supported) {
221
+ return signNativePermitMessage(
222
+ client,
223
+ transactionRequest,
224
+ chain,
225
+ tokenAddress,
226
+ amount,
227
+ _nativePermit
228
+ )
229
+ }
230
+
231
+ if (useWitness) {
232
+ return signPermit2WitnessMessage(
233
+ client,
234
+ transactionRequest,
235
+ chain,
236
+ tokenAddress,
237
+ amount
238
+ )
239
+ }
240
+
241
+ return signPermit2Message(
242
+ client,
243
+ transactionRequest,
244
+ chain,
245
+ tokenAddress,
246
+ amount
247
+ )
248
+ }
@@ -1,17 +1,15 @@
1
1
  import { type BaseToken, ChainType } from '@lifi/types'
2
- import type { Client, Hash } from 'viem'
2
+ import type { Client } from 'viem'
3
3
  import type { SwitchChainHook } from '../types.js'
4
4
  import type { SDKProvider } from '../types.js'
5
5
 
6
6
  export interface EVMProviderOptions {
7
7
  getWalletClient?: () => Promise<Client>
8
8
  switchChain?: SwitchChainHook
9
- multisig?: MultisigConfig
10
9
  }
11
10
 
12
11
  export interface EVMProvider extends SDKProvider {
13
12
  setOptions(options: EVMProviderOptions): void
14
- multisig?: MultisigConfig
15
13
  }
16
14
 
17
15
  export function isEVM(provider: SDKProvider): provider is EVMProvider {
@@ -50,27 +48,3 @@ export interface RevokeApprovalRequest {
50
48
  token: BaseToken
51
49
  spenderAddress: string
52
50
  }
53
-
54
- export interface MultisigTxDetails {
55
- status: 'DONE' | 'FAILED' | 'PENDING' | 'CANCELLED'
56
- txHash?: Hash
57
- }
58
-
59
- export interface MultisigTransaction {
60
- to: string
61
- value?: bigint
62
- data: string
63
- }
64
-
65
- export interface MultisigConfig {
66
- isMultisigWalletClient: boolean
67
- getMultisigTransactionDetails: (
68
- txHash: Hash,
69
- fromChainId: number,
70
- updateIntermediateStatus?: () => void
71
- ) => Promise<MultisigTxDetails>
72
- sendBatchTransaction?: (
73
- batchTransactions: MultisigTransaction[]
74
- ) => Promise<Hash>
75
- shouldBatchTransactions?: boolean
76
- }
@@ -1,5 +1,5 @@
1
1
  import type { ChainId } from '@lifi/types'
2
- import type { Client, Transaction } from 'viem'
2
+ import type { Address, Client, Transaction } from 'viem'
3
3
  import { getBlock } from 'viem/actions'
4
4
  import { config } from '../../config.js'
5
5
  import { median } from '../../utils/median.js'
@@ -37,9 +37,10 @@ export const getMaxPriorityFeePerGas = async (
37
37
  // Multicall
38
38
  export const getMulticallAddress = async (
39
39
  chainId: ChainId
40
- ): Promise<string | undefined> => {
40
+ ): Promise<Address | undefined> => {
41
41
  const chains = await config.getChains()
42
- return chains.find((chain) => chain.id === chainId)?.multicallAddress
42
+ return chains.find((chain) => chain.id === chainId)
43
+ ?.multicallAddress as Address
43
44
  }
44
45
 
45
46
  // Modified viem retryDelay exponential backoff function.
@@ -0,0 +1,49 @@
1
+ import type {
2
+ Client,
3
+ Hash,
4
+ WalletCallReceipt as _WalletCallReceipt,
5
+ } from 'viem'
6
+ import { getCallsStatus } from 'viem/experimental'
7
+ import { LiFiErrorCode } from '../../errors/constants.js'
8
+ import { TransactionError } from '../../errors/errors.js'
9
+ import { waitForResult } from '../../utils/waitForResult.js'
10
+
11
+ export type WalletCallReceipt = _WalletCallReceipt<
12
+ bigint,
13
+ 'success' | 'reverted'
14
+ >
15
+
16
+ export const waitForBatchTransactionReceipt = async (
17
+ client: Client,
18
+ batchHash: Hash
19
+ ): Promise<WalletCallReceipt> => {
20
+ return waitForResult(async () => {
21
+ const callsDetails = await getCallsStatus(client, {
22
+ id: batchHash,
23
+ })
24
+
25
+ if (callsDetails.status === 'PENDING') {
26
+ return undefined
27
+ }
28
+
29
+ if (callsDetails.status === 'CONFIRMED') {
30
+ if (
31
+ !callsDetails.receipts?.length ||
32
+ !callsDetails.receipts.every((receipt) => receipt.transactionHash) ||
33
+ callsDetails.receipts.some((receipt) => receipt.status === 'reverted')
34
+ ) {
35
+ throw new TransactionError(
36
+ LiFiErrorCode.TransactionFailed,
37
+ 'Transaction was reverted.'
38
+ )
39
+ }
40
+ const transactionReceipt = callsDetails.receipts.at(-1)!
41
+ return transactionReceipt
42
+ }
43
+
44
+ throw new TransactionError(
45
+ LiFiErrorCode.TransactionFailed,
46
+ 'Transaction not found.'
47
+ )
48
+ }, 3000)
49
+ }
@@ -28,13 +28,16 @@ export const checkBalance = async (
28
28
  } else {
29
29
  const neeeded = formatUnits(neededBalance, token.decimals)
30
30
  const current = formatUnits(currentBalance, token.decimals)
31
- let _errorMessage = `Your ${token.symbol} balance is too low, you try to transfer ${neeeded} ${token.symbol}, but your wallet only holds ${current} ${token.symbol}. No funds have been sent.`
31
+ let errorMessage = `Your ${token.symbol} balance is too low, you try to transfer ${neeeded} ${token.symbol}, but your wallet only holds ${current} ${token.symbol}. No funds have been sent.`
32
32
 
33
33
  if (currentBalance !== 0n) {
34
- _errorMessage += `If the problem consists, please delete this transfer and start a new one with a maximum of ${current} ${token.symbol}.`
34
+ errorMessage += `If the problem consists, please delete this transfer and start a new one with a maximum of ${current} ${token.symbol}.`
35
35
  }
36
36
 
37
- throw new BalanceError('The balance is too low.')
37
+ throw new BalanceError(
38
+ 'The balance is too low.',
39
+ new Error(errorMessage)
40
+ )
38
41
  }
39
42
  }
40
43
  }
package/src/index.ts CHANGED
@@ -15,9 +15,6 @@ export { isEVM } from './core/EVM/types.js'
15
15
  export type {
16
16
  EVMProvider,
17
17
  EVMProviderOptions,
18
- MultisigConfig,
19
- MultisigTransaction,
20
- MultisigTxDetails,
21
18
  } from './core/EVM/types.js'
22
19
  export { StatusManager } from './core/StatusManager.js'
23
20
  export {