@lifi/sdk 3.6.0-beta.2 → 3.6.0-beta.4
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 +4 -4
- package/src/_cjs/core/EVM/EVMStepExecutor.js +250 -211
- package/src/_cjs/core/EVM/EVMStepExecutor.js.map +1 -1
- package/src/_cjs/core/EVM/getNativePermit.js +127 -59
- package/src/_cjs/core/EVM/getNativePermit.js.map +1 -1
- package/src/_cjs/core/EVM/parseEVMErrors.js +2 -1
- package/src/_cjs/core/EVM/parseEVMErrors.js.map +1 -1
- package/src/_cjs/core/EVM/signPermitMessage.js +1 -7
- package/src/_cjs/core/EVM/signPermitMessage.js.map +1 -1
- package/src/_cjs/core/EVM/typeguards.js +3 -3
- package/src/_cjs/core/EVM/typeguards.js.map +1 -1
- package/src/_cjs/core/Solana/SolanaStepExecutor.js +1 -13
- package/src/_cjs/core/Solana/SolanaStepExecutor.js.map +1 -1
- package/src/_cjs/core/Solana/parseSolanaErrors.js.map +1 -1
- package/src/_cjs/core/StatusManager.js +13 -9
- package/src/_cjs/core/StatusManager.js.map +1 -1
- package/src/_cjs/core/UTXO/UTXOStepExecutor.js +1 -13
- package/src/_cjs/core/UTXO/UTXOStepExecutor.js.map +1 -1
- package/src/_cjs/core/UTXO/getUTXOAPIPublicClient.js +3 -3
- package/src/_cjs/core/UTXO/getUTXOAPIPublicClient.js.map +1 -1
- package/src/_cjs/core/UTXO/parseUTXOErrors.js.map +1 -1
- package/src/_cjs/core/processMessages.js +22 -15
- package/src/_cjs/core/processMessages.js.map +1 -1
- package/src/_cjs/core/waitForDestinationChainTransaction.js +16 -1
- package/src/_cjs/core/waitForDestinationChainTransaction.js.map +1 -1
- package/src/_cjs/core/waitForTransactionStatus.js.map +1 -1
- package/src/_cjs/errors/SDKError.js.map +1 -1
- package/src/_cjs/index.js +2 -2
- package/src/_cjs/index.js.map +1 -1
- package/src/_cjs/utils/getTransactionMessage.js.map +1 -1
- package/src/_cjs/version.js +1 -1
- package/src/_esm/core/EVM/EVMStepExecutor.js +273 -233
- package/src/_esm/core/EVM/EVMStepExecutor.js.map +1 -1
- package/src/_esm/core/EVM/getNativePermit.js +147 -60
- package/src/_esm/core/EVM/getNativePermit.js.map +1 -1
- package/src/_esm/core/EVM/parseEVMErrors.js +2 -1
- package/src/_esm/core/EVM/parseEVMErrors.js.map +1 -1
- package/src/_esm/core/EVM/signPermitMessage.js +1 -7
- package/src/_esm/core/EVM/signPermitMessage.js.map +1 -1
- package/src/_esm/core/EVM/typeguards.js +2 -2
- package/src/_esm/core/EVM/typeguards.js.map +1 -1
- package/src/_esm/core/Solana/SolanaStepExecutor.js +1 -14
- package/src/_esm/core/Solana/SolanaStepExecutor.js.map +1 -1
- package/src/_esm/core/Solana/parseSolanaErrors.js.map +1 -1
- package/src/_esm/core/StatusManager.js +24 -18
- package/src/_esm/core/StatusManager.js.map +1 -1
- package/src/_esm/core/UTXO/UTXOStepExecutor.js +1 -14
- package/src/_esm/core/UTXO/UTXOStepExecutor.js.map +1 -1
- package/src/_esm/core/UTXO/getUTXOAPIPublicClient.js +3 -3
- package/src/_esm/core/UTXO/getUTXOAPIPublicClient.js.map +1 -1
- package/src/_esm/core/UTXO/parseUTXOErrors.js.map +1 -1
- package/src/_esm/core/processMessages.js +22 -15
- package/src/_esm/core/processMessages.js.map +1 -1
- package/src/_esm/core/waitForDestinationChainTransaction.js +17 -1
- package/src/_esm/core/waitForDestinationChainTransaction.js.map +1 -1
- package/src/_esm/core/waitForTransactionStatus.js.map +1 -1
- package/src/_esm/errors/SDKError.js.map +1 -1
- package/src/_esm/index.js +1 -1
- package/src/_esm/index.js.map +1 -1
- package/src/_esm/utils/getTransactionMessage.js.map +1 -1
- package/src/_esm/version.js +1 -1
- package/src/_types/core/EVM/EVMStepExecutor.d.ts +13 -3
- package/src/_types/core/EVM/EVMStepExecutor.d.ts.map +1 -1
- package/src/_types/core/EVM/checkAllowance.d.ts.map +1 -1
- package/src/_types/core/EVM/getNativePermit.d.ts +2 -0
- package/src/_types/core/EVM/getNativePermit.d.ts.map +1 -1
- package/src/_types/core/EVM/parseEVMErrors.d.ts +2 -1
- package/src/_types/core/EVM/parseEVMErrors.d.ts.map +1 -1
- package/src/_types/core/EVM/signPermitMessage.d.ts.map +1 -1
- package/src/_types/core/EVM/typeguards.d.ts +1 -1
- package/src/_types/core/EVM/typeguards.d.ts.map +1 -1
- package/src/_types/core/Solana/SolanaStepExecutor.d.ts.map +1 -1
- package/src/_types/core/Solana/parseSolanaErrors.d.ts +2 -1
- package/src/_types/core/Solana/parseSolanaErrors.d.ts.map +1 -1
- package/src/_types/core/StatusManager.d.ts +14 -11
- package/src/_types/core/StatusManager.d.ts.map +1 -1
- package/src/_types/core/UTXO/UTXOStepExecutor.d.ts.map +1 -1
- package/src/_types/core/UTXO/parseUTXOErrors.d.ts +2 -1
- package/src/_types/core/UTXO/parseUTXOErrors.d.ts.map +1 -1
- package/src/_types/core/processMessages.d.ts +3 -1
- package/src/_types/core/processMessages.d.ts.map +1 -1
- package/src/_types/core/types.d.ts +32 -1
- package/src/_types/core/types.d.ts.map +1 -1
- package/src/_types/core/waitForDestinationChainTransaction.d.ts +3 -3
- package/src/_types/core/waitForDestinationChainTransaction.d.ts.map +1 -1
- package/src/_types/core/waitForTransactionStatus.d.ts +2 -1
- package/src/_types/core/waitForTransactionStatus.d.ts.map +1 -1
- package/src/_types/errors/SDKError.d.ts +2 -1
- package/src/_types/errors/SDKError.d.ts.map +1 -1
- package/src/_types/index.d.ts +2 -2
- package/src/_types/index.d.ts.map +1 -1
- package/src/_types/utils/getTransactionMessage.d.ts +2 -1
- package/src/_types/utils/getTransactionMessage.d.ts.map +1 -1
- package/src/_types/version.d.ts +1 -1
- package/src/core/EVM/EVMStepExecutor.ts +353 -293
- package/src/core/EVM/checkAllowance.ts +2 -2
- package/src/core/EVM/getNativePermit.ts +219 -66
- package/src/core/EVM/parseEVMErrors.ts +6 -2
- package/src/core/EVM/signPermitMessage.ts +1 -8
- package/src/core/EVM/typeguards.ts +2 -2
- package/src/core/Solana/SolanaStepExecutor.ts +2 -16
- package/src/core/Solana/parseSolanaErrors.ts +2 -1
- package/src/core/StatusManager.ts +38 -26
- package/src/core/UTXO/UTXOStepExecutor.ts +2 -16
- package/src/core/UTXO/getUTXOAPIPublicClient.ts +3 -3
- package/src/core/UTXO/parseUTXOErrors.ts +2 -1
- package/src/core/processMessages.ts +25 -21
- package/src/core/types.ts +54 -1
- package/src/core/waitForDestinationChainTransaction.ts +21 -4
- package/src/core/waitForTransactionStatus.ts +2 -6
- package/src/errors/SDKError.ts +2 -1
- package/src/index.ts +6 -1
- package/src/utils/getTransactionMessage.ts +2 -1
- package/src/version.ts +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { ExtendedChain, LiFiStep
|
|
1
|
+
import type { ExtendedChain, LiFiStep } from '@lifi/types'
|
|
2
2
|
import type { Address, Client, Hash } from 'viem'
|
|
3
3
|
import { MaxUint256 } from '../../constants.js'
|
|
4
4
|
import type { StatusManager } from '../StatusManager.js'
|
|
5
|
-
import type { ExecutionOptions } from '../types.js'
|
|
5
|
+
import type { ExecutionOptions, Process, ProcessType } from '../types.js'
|
|
6
6
|
import { getAllowance } from './getAllowance.js'
|
|
7
7
|
import { parseEVMErrors } from './parseEVMErrors.js'
|
|
8
8
|
import { setAllowance } from './setAllowance.js'
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import type { ExtendedChain } from '@lifi/types'
|
|
2
|
-
import
|
|
2
|
+
import {
|
|
3
|
+
encodeAbiParameters,
|
|
4
|
+
keccak256,
|
|
5
|
+
pad,
|
|
6
|
+
parseAbiParameters,
|
|
7
|
+
toBytes,
|
|
8
|
+
toHex,
|
|
9
|
+
} from 'viem'
|
|
10
|
+
import type { Address, Client, Hex } from 'viem'
|
|
11
|
+
import type { TypedDataDomain } from 'viem'
|
|
3
12
|
import { multicall, readContract } from 'viem/actions'
|
|
4
13
|
import { eip2612Abi } from './abi.js'
|
|
5
14
|
import { getMulticallAddress } from './utils.js'
|
|
@@ -9,6 +18,136 @@ export type NativePermitData = {
|
|
|
9
18
|
version: string
|
|
10
19
|
nonce: bigint
|
|
11
20
|
supported: boolean
|
|
21
|
+
domain: TypedDataDomain
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* EIP-712 domain typehash with chainId
|
|
26
|
+
* @link https://eips.ethereum.org/EIPS/eip-712#specification
|
|
27
|
+
*
|
|
28
|
+
* keccak256(toBytes(
|
|
29
|
+
* 'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'
|
|
30
|
+
* ))
|
|
31
|
+
*/
|
|
32
|
+
const EIP712_DOMAIN_TYPEHASH =
|
|
33
|
+
'0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f' as Hex
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* EIP-712 domain typehash with salt (e.g. USDC.e on Polygon)
|
|
37
|
+
* @link https://eips.ethereum.org/EIPS/eip-712#specification
|
|
38
|
+
*
|
|
39
|
+
* keccak256(toBytes(
|
|
40
|
+
* 'EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)'
|
|
41
|
+
* ))
|
|
42
|
+
*/
|
|
43
|
+
const EIP712_DOMAIN_TYPEHASH_WITH_SALT =
|
|
44
|
+
'0x36c25de3e541d5d970f66e4210d728721220fff5c077cc6cd008b3a0c62adab7' as Hex
|
|
45
|
+
|
|
46
|
+
function makeDomainSeparator({
|
|
47
|
+
name,
|
|
48
|
+
version,
|
|
49
|
+
chainId,
|
|
50
|
+
verifyingContract,
|
|
51
|
+
withSalt = false,
|
|
52
|
+
}: {
|
|
53
|
+
name: string
|
|
54
|
+
version: string
|
|
55
|
+
chainId: bigint
|
|
56
|
+
verifyingContract: Address
|
|
57
|
+
withSalt?: boolean
|
|
58
|
+
}): Hex {
|
|
59
|
+
const nameHash = keccak256(toBytes(name))
|
|
60
|
+
const versionHash = keccak256(toBytes(version))
|
|
61
|
+
|
|
62
|
+
const encoded = withSalt
|
|
63
|
+
? encodeAbiParameters(
|
|
64
|
+
parseAbiParameters('bytes32, bytes32, bytes32, address, bytes32'),
|
|
65
|
+
[
|
|
66
|
+
EIP712_DOMAIN_TYPEHASH_WITH_SALT,
|
|
67
|
+
nameHash,
|
|
68
|
+
versionHash,
|
|
69
|
+
verifyingContract,
|
|
70
|
+
pad(toHex(chainId), { size: 32 }),
|
|
71
|
+
]
|
|
72
|
+
)
|
|
73
|
+
: encodeAbiParameters(
|
|
74
|
+
parseAbiParameters('bytes32, bytes32, bytes32, uint256, address'),
|
|
75
|
+
[
|
|
76
|
+
EIP712_DOMAIN_TYPEHASH,
|
|
77
|
+
nameHash,
|
|
78
|
+
versionHash,
|
|
79
|
+
chainId,
|
|
80
|
+
verifyingContract,
|
|
81
|
+
]
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
return keccak256(encoded)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// TODO: Add support for EIP-5267 when adoption increases
|
|
88
|
+
// This EIP provides a standard way to query domain separator and permit type hash
|
|
89
|
+
// via eip712Domain() function, which would simplify permit validation
|
|
90
|
+
// https://eips.ethereum.org/EIPS/eip-5267
|
|
91
|
+
function validateDomainSeparator({
|
|
92
|
+
name,
|
|
93
|
+
version,
|
|
94
|
+
chainId,
|
|
95
|
+
verifyingContract,
|
|
96
|
+
domainSeparator,
|
|
97
|
+
}: {
|
|
98
|
+
name: string
|
|
99
|
+
version: string
|
|
100
|
+
chainId: bigint
|
|
101
|
+
verifyingContract: Address
|
|
102
|
+
domainSeparator: Hex
|
|
103
|
+
}): { isValid: boolean; domain: TypedDataDomain } {
|
|
104
|
+
if (!name || !domainSeparator) {
|
|
105
|
+
return {
|
|
106
|
+
isValid: false,
|
|
107
|
+
domain: {},
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
for (const withSalt of [false, true]) {
|
|
112
|
+
const computedDS = makeDomainSeparator({
|
|
113
|
+
name,
|
|
114
|
+
version,
|
|
115
|
+
chainId,
|
|
116
|
+
verifyingContract,
|
|
117
|
+
withSalt,
|
|
118
|
+
})
|
|
119
|
+
if (domainSeparator.toLowerCase() === computedDS.toLowerCase()) {
|
|
120
|
+
return {
|
|
121
|
+
isValid: true,
|
|
122
|
+
domain: withSalt
|
|
123
|
+
? {
|
|
124
|
+
name,
|
|
125
|
+
version,
|
|
126
|
+
verifyingContract,
|
|
127
|
+
salt: pad(toHex(chainId), { size: 32 }),
|
|
128
|
+
}
|
|
129
|
+
: {
|
|
130
|
+
name,
|
|
131
|
+
version,
|
|
132
|
+
chainId,
|
|
133
|
+
verifyingContract,
|
|
134
|
+
},
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
isValid: false,
|
|
141
|
+
domain: {},
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const defaultPermit: NativePermitData = {
|
|
146
|
+
name: '',
|
|
147
|
+
version: '1',
|
|
148
|
+
nonce: 0n,
|
|
149
|
+
supported: false,
|
|
150
|
+
domain: {},
|
|
12
151
|
}
|
|
13
152
|
|
|
14
153
|
/**
|
|
@@ -27,88 +166,102 @@ export const getNativePermit = async (
|
|
|
27
166
|
try {
|
|
28
167
|
const multicallAddress = await getMulticallAddress(chain.id)
|
|
29
168
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
await multicall(client, {
|
|
33
|
-
contracts: [
|
|
34
|
-
{
|
|
35
|
-
address: tokenAddress,
|
|
36
|
-
abi: eip2612Abi,
|
|
37
|
-
functionName: 'name',
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
address: tokenAddress,
|
|
41
|
-
abi: eip2612Abi,
|
|
42
|
-
functionName: 'DOMAIN_SEPARATOR',
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
address: tokenAddress,
|
|
46
|
-
abi: eip2612Abi,
|
|
47
|
-
functionName: 'nonces',
|
|
48
|
-
args: [client.account!.address],
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
address: tokenAddress,
|
|
52
|
-
abi: eip2612Abi,
|
|
53
|
-
functionName: 'version',
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
multicallAddress,
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
const supported =
|
|
60
|
-
nameResult.status === 'success' &&
|
|
61
|
-
domainSeparatorResult.status === 'success' &&
|
|
62
|
-
noncesResult.status === 'success' &&
|
|
63
|
-
!!nameResult.result &&
|
|
64
|
-
!!domainSeparatorResult.result &&
|
|
65
|
-
noncesResult.result !== undefined
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
name: nameResult.result!,
|
|
69
|
-
version: versionResult.result ?? '1',
|
|
70
|
-
nonce: noncesResult.result!,
|
|
71
|
-
supported,
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Fallback to individual calls
|
|
76
|
-
const [name, domainSeparator, nonce, version] = await Promise.all([
|
|
77
|
-
readContract(client, {
|
|
169
|
+
const contractCalls = [
|
|
170
|
+
{
|
|
78
171
|
address: tokenAddress,
|
|
79
172
|
abi: eip2612Abi,
|
|
80
173
|
functionName: 'name',
|
|
81
|
-
}
|
|
82
|
-
|
|
174
|
+
},
|
|
175
|
+
{
|
|
83
176
|
address: tokenAddress,
|
|
84
177
|
abi: eip2612Abi,
|
|
85
178
|
functionName: 'DOMAIN_SEPARATOR',
|
|
86
|
-
}
|
|
87
|
-
|
|
179
|
+
},
|
|
180
|
+
{
|
|
88
181
|
address: tokenAddress,
|
|
89
182
|
abi: eip2612Abi,
|
|
90
183
|
functionName: 'nonces',
|
|
91
184
|
args: [client.account!.address],
|
|
92
|
-
}
|
|
93
|
-
|
|
185
|
+
},
|
|
186
|
+
{
|
|
94
187
|
address: tokenAddress,
|
|
95
188
|
abi: eip2612Abi,
|
|
96
189
|
functionName: 'version',
|
|
97
|
-
}
|
|
98
|
-
]
|
|
190
|
+
},
|
|
191
|
+
] as const
|
|
192
|
+
|
|
193
|
+
if (multicallAddress) {
|
|
194
|
+
const [nameResult, domainSeparatorResult, noncesResult, versionResult] =
|
|
195
|
+
await multicall(client, {
|
|
196
|
+
contracts: contractCalls,
|
|
197
|
+
multicallAddress,
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
if (
|
|
201
|
+
nameResult.status !== 'success' ||
|
|
202
|
+
domainSeparatorResult.status !== 'success' ||
|
|
203
|
+
noncesResult.status !== 'success' ||
|
|
204
|
+
!nameResult.result ||
|
|
205
|
+
!domainSeparatorResult.result ||
|
|
206
|
+
noncesResult.result === undefined
|
|
207
|
+
) {
|
|
208
|
+
return defaultPermit
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const { isValid, domain } = validateDomainSeparator({
|
|
212
|
+
name: nameResult.result,
|
|
213
|
+
version: versionResult.result ?? '1',
|
|
214
|
+
chainId: BigInt(chain.id),
|
|
215
|
+
verifyingContract: tokenAddress,
|
|
216
|
+
domainSeparator: domainSeparatorResult.result,
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
return {
|
|
220
|
+
name: nameResult.result,
|
|
221
|
+
version: versionResult.result ?? '1',
|
|
222
|
+
nonce: noncesResult.result,
|
|
223
|
+
supported: isValid,
|
|
224
|
+
domain,
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const [nameResult, domainSeparatorResult, noncesResult, versionResult] =
|
|
229
|
+
(await Promise.allSettled(
|
|
230
|
+
contractCalls.map((call) => readContract(client, call))
|
|
231
|
+
)) as [
|
|
232
|
+
PromiseSettledResult<string>,
|
|
233
|
+
PromiseSettledResult<Hex>,
|
|
234
|
+
PromiseSettledResult<bigint>,
|
|
235
|
+
PromiseSettledResult<string>,
|
|
236
|
+
]
|
|
237
|
+
|
|
238
|
+
if (
|
|
239
|
+
nameResult.status !== 'fulfilled' ||
|
|
240
|
+
domainSeparatorResult.status !== 'fulfilled' ||
|
|
241
|
+
noncesResult.status !== 'fulfilled'
|
|
242
|
+
) {
|
|
243
|
+
return defaultPermit
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const name = nameResult.value
|
|
247
|
+
const version =
|
|
248
|
+
versionResult.status === 'fulfilled' ? versionResult.value : '1'
|
|
249
|
+
const { isValid, domain } = validateDomainSeparator({
|
|
250
|
+
name,
|
|
251
|
+
version,
|
|
252
|
+
chainId: BigInt(chain.id),
|
|
253
|
+
verifyingContract: tokenAddress,
|
|
254
|
+
domainSeparator: domainSeparatorResult.value,
|
|
255
|
+
})
|
|
99
256
|
|
|
100
257
|
return {
|
|
101
258
|
name,
|
|
102
|
-
version
|
|
103
|
-
nonce,
|
|
104
|
-
supported:
|
|
259
|
+
version,
|
|
260
|
+
nonce: noncesResult.value,
|
|
261
|
+
supported: isValid,
|
|
262
|
+
domain,
|
|
105
263
|
}
|
|
106
264
|
} catch {
|
|
107
|
-
return
|
|
108
|
-
name: '',
|
|
109
|
-
version: '1',
|
|
110
|
-
nonce: 0n,
|
|
111
|
-
supported: false,
|
|
112
|
-
}
|
|
265
|
+
return defaultPermit
|
|
113
266
|
}
|
|
114
267
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { LiFiStep
|
|
1
|
+
import type { LiFiStep } from '@lifi/types'
|
|
2
2
|
import { SDKError } from '../../errors/SDKError.js'
|
|
3
3
|
import { BaseError } from '../../errors/baseError.js'
|
|
4
4
|
import { ErrorMessage, LiFiErrorCode } from '../../errors/constants.js'
|
|
5
5
|
import { TransactionError, UnknownError } from '../../errors/errors.js'
|
|
6
6
|
import { fetchTxErrorDetails } from '../../utils/fetchTxErrorDetails.js'
|
|
7
|
+
import type { Process } from '../types.js'
|
|
7
8
|
|
|
8
9
|
export const parseEVMErrors = async (
|
|
9
10
|
e: Error,
|
|
@@ -26,7 +27,10 @@ const handleSpecificErrors = async (
|
|
|
26
27
|
step?: LiFiStep,
|
|
27
28
|
process?: Process
|
|
28
29
|
) => {
|
|
29
|
-
if (
|
|
30
|
+
if (
|
|
31
|
+
e.name === 'UserRejectedRequestError' ||
|
|
32
|
+
e.cause?.name === 'UserRejectedRequestError'
|
|
33
|
+
) {
|
|
30
34
|
return new TransactionError(LiFiErrorCode.SignatureRejected, e.message, e)
|
|
31
35
|
}
|
|
32
36
|
// Safe Wallet via WalletConnect returns -32000 code when user rejects the signature
|
|
@@ -28,13 +28,6 @@ export const signNativePermitMessage = async (
|
|
|
28
28
|
): Promise<PermitSignature> => {
|
|
29
29
|
const deadline = BigInt(Math.floor(Date.now() / 1000) + 30 * 60) // 30 minutes
|
|
30
30
|
|
|
31
|
-
const domain = {
|
|
32
|
-
name: nativePermit.name,
|
|
33
|
-
version: nativePermit.version,
|
|
34
|
-
chainId: chain.id,
|
|
35
|
-
verifyingContract: tokenAddress,
|
|
36
|
-
}
|
|
37
|
-
|
|
38
31
|
const message = {
|
|
39
32
|
owner: client.account!.address,
|
|
40
33
|
spender: chain.permit2Proxy as Address,
|
|
@@ -49,7 +42,7 @@ export const signNativePermitMessage = async (
|
|
|
49
42
|
'signTypedData'
|
|
50
43
|
)({
|
|
51
44
|
account: client.account!,
|
|
52
|
-
domain,
|
|
45
|
+
domain: nativePermit.domain,
|
|
53
46
|
types: eip2612Types,
|
|
54
47
|
primaryType: 'Permit',
|
|
55
48
|
message,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { LiFiStepExtended } from '../types.js'
|
|
2
2
|
import type { EVMPermitStep } from './types.js'
|
|
3
3
|
|
|
4
|
-
export function
|
|
4
|
+
export function isRelayerStep(step: LiFiStepExtended): step is EVMPermitStep {
|
|
5
5
|
const evmStep = step as EVMPermitStep
|
|
6
|
-
return 'permit' in evmStep
|
|
6
|
+
return 'permit' in evmStep && 'permitData' in evmStep && 'witness' in evmStep
|
|
7
7
|
}
|
|
@@ -217,24 +217,10 @@ export class SolanaStepExecutor extends BaseStepExecutor {
|
|
|
217
217
|
}
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
-
// Wait for the transaction status on the destination chain
|
|
221
|
-
const transactionHash = process.txHash
|
|
222
|
-
if (!transactionHash) {
|
|
223
|
-
throw new Error('Transaction hash is undefined.')
|
|
224
|
-
}
|
|
225
|
-
if (isBridgeExecution) {
|
|
226
|
-
process = this.statusManager.findOrCreateProcess({
|
|
227
|
-
step,
|
|
228
|
-
type: 'RECEIVING_CHAIN',
|
|
229
|
-
status: 'PENDING',
|
|
230
|
-
chainId: toChain.id,
|
|
231
|
-
})
|
|
232
|
-
}
|
|
233
|
-
|
|
234
220
|
await waitForDestinationChainTransaction(
|
|
235
221
|
step,
|
|
236
|
-
process
|
|
237
|
-
|
|
222
|
+
process,
|
|
223
|
+
fromChain,
|
|
238
224
|
toChain,
|
|
239
225
|
this.statusManager
|
|
240
226
|
)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { LiFiStep
|
|
1
|
+
import type { LiFiStep } from '@lifi/types'
|
|
2
2
|
import { SDKError } from '../../errors/SDKError.js'
|
|
3
3
|
import { BaseError } from '../../errors/baseError.js'
|
|
4
4
|
import { ErrorMessage, LiFiErrorCode } from '../../errors/constants.js'
|
|
5
5
|
import { TransactionError, UnknownError } from '../../errors/errors.js'
|
|
6
|
+
import type { Process } from '../types.js'
|
|
6
7
|
|
|
7
8
|
export const parseSolanaErrors = async (
|
|
8
9
|
e: Error,
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
+
import type { ChainId, LiFiStep } from '@lifi/types'
|
|
2
|
+
import { executionState } from './executionState.js'
|
|
3
|
+
import { getProcessMessage } from './processMessages.js'
|
|
1
4
|
import type {
|
|
2
|
-
ChainId,
|
|
3
5
|
Execution,
|
|
4
6
|
ExecutionStatus,
|
|
5
|
-
|
|
7
|
+
LiFiStepExtended,
|
|
6
8
|
Process,
|
|
7
9
|
ProcessStatus,
|
|
8
10
|
ProcessType,
|
|
9
|
-
} from '
|
|
10
|
-
import { executionState } from './executionState.js'
|
|
11
|
-
import { getProcessMessage } from './processMessages.js'
|
|
12
|
-
import type { LiFiStepExtended } from './types.js'
|
|
11
|
+
} from './types.js'
|
|
13
12
|
|
|
14
13
|
export type FindOrCreateProcessProps = {
|
|
15
14
|
step: LiFiStepExtended
|
|
@@ -80,17 +79,38 @@ export class StatusManager {
|
|
|
80
79
|
return step
|
|
81
80
|
}
|
|
82
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Finds a process of the specified type in the step's execution
|
|
84
|
+
* @param step The step to search in
|
|
85
|
+
* @param type The process type to find
|
|
86
|
+
* @param status Optional status to update the process with if found
|
|
87
|
+
* @returns The found process or undefined if not found
|
|
88
|
+
*/
|
|
89
|
+
findProcess(
|
|
90
|
+
step: LiFiStepExtended,
|
|
91
|
+
type: ProcessType,
|
|
92
|
+
status?: ProcessStatus
|
|
93
|
+
): Process | undefined {
|
|
94
|
+
if (!step.execution?.process) {
|
|
95
|
+
throw new Error("Execution hasn't been initialized.")
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const process = step.execution.process.find((p) => p.type === type)
|
|
99
|
+
|
|
100
|
+
if (process && status && process.status !== status) {
|
|
101
|
+
process.status = status
|
|
102
|
+
this.updateStepInRoute(step)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return process
|
|
106
|
+
}
|
|
107
|
+
|
|
83
108
|
/**
|
|
84
109
|
* Create and push a new process into the execution.
|
|
85
|
-
* @param step
|
|
86
|
-
* @param
|
|
87
|
-
* @param
|
|
88
|
-
* @param
|
|
89
|
-
* @param root0
|
|
90
|
-
* @param root0.step
|
|
91
|
-
* @param root0.type
|
|
92
|
-
* @param root0.chainId
|
|
93
|
-
* @param root0.status
|
|
110
|
+
* @param step The step that should contain the new process.
|
|
111
|
+
* @param type Type of the process. Used to identify already existing processes.
|
|
112
|
+
* @param chainId Chain Id of the process.
|
|
113
|
+
* @param status By default created procces is set to the STARTED status. We can override new process with the needed status.
|
|
94
114
|
* @returns Returns process.
|
|
95
115
|
*/
|
|
96
116
|
findOrCreateProcess = ({
|
|
@@ -99,17 +119,9 @@ export class StatusManager {
|
|
|
99
119
|
chainId,
|
|
100
120
|
status,
|
|
101
121
|
}: FindOrCreateProcessProps): Process => {
|
|
102
|
-
|
|
103
|
-
throw new Error("Execution hasn't been initialized.")
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const process = step.execution.process.find((p) => p.type === type)
|
|
122
|
+
const process = this.findProcess(step, type, status)
|
|
107
123
|
|
|
108
124
|
if (process) {
|
|
109
|
-
if (status && process.status !== status) {
|
|
110
|
-
process.status = status
|
|
111
|
-
this.updateStepInRoute(step)
|
|
112
|
-
}
|
|
113
125
|
return process
|
|
114
126
|
}
|
|
115
127
|
|
|
@@ -121,7 +133,7 @@ export class StatusManager {
|
|
|
121
133
|
chainId: chainId,
|
|
122
134
|
}
|
|
123
135
|
|
|
124
|
-
step.execution
|
|
136
|
+
step.execution!.process.push(newProcess)
|
|
125
137
|
this.updateStepInRoute(step)
|
|
126
138
|
return newProcess
|
|
127
139
|
}
|
|
@@ -143,7 +155,7 @@ export class StatusManager {
|
|
|
143
155
|
if (!step.execution) {
|
|
144
156
|
throw new Error("Can't update an empty step execution.")
|
|
145
157
|
}
|
|
146
|
-
const currentProcess =
|
|
158
|
+
const currentProcess = this.findProcess(step, type)
|
|
147
159
|
|
|
148
160
|
if (!currentProcess) {
|
|
149
161
|
throw new Error("Can't find a process for the given type.")
|
|
@@ -263,24 +263,10 @@ export class UTXOStepExecutor extends BaseStepExecutor {
|
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
-
// Wait for the transaction status on the destination chain
|
|
267
|
-
const transactionHash = process.txHash
|
|
268
|
-
if (!transactionHash) {
|
|
269
|
-
throw new Error('Transaction hash is undefined.')
|
|
270
|
-
}
|
|
271
|
-
if (isBridgeExecution) {
|
|
272
|
-
process = this.statusManager.findOrCreateProcess({
|
|
273
|
-
step,
|
|
274
|
-
type: 'RECEIVING_CHAIN',
|
|
275
|
-
status: 'PENDING',
|
|
276
|
-
chainId: toChain.id,
|
|
277
|
-
})
|
|
278
|
-
}
|
|
279
|
-
|
|
280
266
|
await waitForDestinationChainTransaction(
|
|
281
267
|
step,
|
|
282
|
-
process
|
|
283
|
-
|
|
268
|
+
process,
|
|
269
|
+
fromChain,
|
|
284
270
|
toChain,
|
|
285
271
|
this.statusManager,
|
|
286
272
|
10_000
|
|
@@ -49,15 +49,15 @@ export const getUTXOAPIPublicClient = async (chainId: number) => {
|
|
|
49
49
|
key: 'blockchair',
|
|
50
50
|
includeChainToURL: true,
|
|
51
51
|
}),
|
|
52
|
-
utxo('https://rpc.ankr.com/http/btc_blockbook/api/v2', {
|
|
53
|
-
key: 'ankr',
|
|
54
|
-
}),
|
|
55
52
|
utxo('https://api.blockcypher.com/v1/btc/main', {
|
|
56
53
|
key: 'blockcypher',
|
|
57
54
|
}),
|
|
58
55
|
utxo('https://mempool.space/api', {
|
|
59
56
|
key: 'mempool',
|
|
60
57
|
}),
|
|
58
|
+
utxo('https://rpc.ankr.com/http/btc_blockbook/api/v2', {
|
|
59
|
+
key: 'ankr',
|
|
60
|
+
}),
|
|
61
61
|
]),
|
|
62
62
|
}).extend(UTXOAPIActions)
|
|
63
63
|
publicAPIClients[chainId] = client
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { LiFiStep
|
|
1
|
+
import type { LiFiStep } from '@lifi/types'
|
|
2
2
|
import { SDKError } from '../../errors/SDKError.js'
|
|
3
3
|
import { BaseError } from '../../errors/baseError.js'
|
|
4
4
|
import { ErrorMessage, LiFiErrorCode } from '../../errors/constants.js'
|
|
5
5
|
import { TransactionError, UnknownError } from '../../errors/errors.js'
|
|
6
|
+
import type { Process } from '../types.js'
|
|
6
7
|
|
|
7
8
|
export const parseUTXOErrors = async (
|
|
8
9
|
e: Error,
|
|
@@ -1,38 +1,42 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
StatusMessage,
|
|
5
|
-
Substatus,
|
|
6
|
-
} from '@lifi/types'
|
|
1
|
+
import type { StatusMessage, Substatus } from '@lifi/types'
|
|
2
|
+
import type { ProcessStatus } from './types.js'
|
|
3
|
+
import type { ProcessType } from './types.js'
|
|
7
4
|
|
|
8
5
|
const processMessages: Record<
|
|
9
6
|
ProcessType,
|
|
10
7
|
Partial<Record<ProcessStatus, string>>
|
|
11
8
|
> = {
|
|
12
9
|
TOKEN_ALLOWANCE: {
|
|
13
|
-
STARTED: 'Setting token allowance
|
|
14
|
-
PENDING: 'Waiting for token allowance
|
|
15
|
-
DONE: 'Token allowance set
|
|
10
|
+
STARTED: 'Setting token allowance',
|
|
11
|
+
PENDING: 'Waiting for token allowance',
|
|
12
|
+
DONE: 'Token allowance set',
|
|
16
13
|
},
|
|
17
14
|
SWITCH_CHAIN: {
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
ACTION_REQUIRED: 'Chain switch required',
|
|
16
|
+
PENDING: 'Waiting for chain switch',
|
|
17
|
+
DONE: 'Chain switched',
|
|
20
18
|
},
|
|
21
19
|
SWAP: {
|
|
22
|
-
STARTED: 'Preparing swap transaction
|
|
23
|
-
ACTION_REQUIRED: 'Please sign the transaction
|
|
24
|
-
PENDING: 'Waiting for swap transaction
|
|
25
|
-
DONE: 'Swap completed
|
|
20
|
+
STARTED: 'Preparing swap transaction',
|
|
21
|
+
ACTION_REQUIRED: 'Please sign the transaction',
|
|
22
|
+
PENDING: 'Waiting for swap transaction',
|
|
23
|
+
DONE: 'Swap completed',
|
|
26
24
|
},
|
|
27
25
|
CROSS_CHAIN: {
|
|
28
|
-
STARTED: 'Preparing bridge transaction
|
|
29
|
-
ACTION_REQUIRED: 'Please sign the transaction
|
|
30
|
-
PENDING: 'Waiting for bridge transaction
|
|
31
|
-
DONE: 'Bridge transaction confirmed
|
|
26
|
+
STARTED: 'Preparing bridge transaction',
|
|
27
|
+
ACTION_REQUIRED: 'Please sign the transaction',
|
|
28
|
+
PENDING: 'Waiting for bridge transaction',
|
|
29
|
+
DONE: 'Bridge transaction confirmed',
|
|
32
30
|
},
|
|
33
31
|
RECEIVING_CHAIN: {
|
|
34
|
-
PENDING: 'Waiting for destination chain
|
|
35
|
-
DONE: 'Bridge completed
|
|
32
|
+
PENDING: 'Waiting for destination chain',
|
|
33
|
+
DONE: 'Bridge completed',
|
|
34
|
+
},
|
|
35
|
+
PERMIT: {
|
|
36
|
+
STARTED: 'Preparing transaction',
|
|
37
|
+
ACTION_REQUIRED: 'Sign permit message',
|
|
38
|
+
PENDING: 'Waiting for permit message',
|
|
39
|
+
DONE: 'Permit message signed',
|
|
36
40
|
},
|
|
37
41
|
TRANSACTION: {},
|
|
38
42
|
}
|