@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.
Files changed (114) hide show
  1. package/package.json +4 -4
  2. package/src/_cjs/core/EVM/EVMStepExecutor.js +250 -211
  3. package/src/_cjs/core/EVM/EVMStepExecutor.js.map +1 -1
  4. package/src/_cjs/core/EVM/getNativePermit.js +127 -59
  5. package/src/_cjs/core/EVM/getNativePermit.js.map +1 -1
  6. package/src/_cjs/core/EVM/parseEVMErrors.js +2 -1
  7. package/src/_cjs/core/EVM/parseEVMErrors.js.map +1 -1
  8. package/src/_cjs/core/EVM/signPermitMessage.js +1 -7
  9. package/src/_cjs/core/EVM/signPermitMessage.js.map +1 -1
  10. package/src/_cjs/core/EVM/typeguards.js +3 -3
  11. package/src/_cjs/core/EVM/typeguards.js.map +1 -1
  12. package/src/_cjs/core/Solana/SolanaStepExecutor.js +1 -13
  13. package/src/_cjs/core/Solana/SolanaStepExecutor.js.map +1 -1
  14. package/src/_cjs/core/Solana/parseSolanaErrors.js.map +1 -1
  15. package/src/_cjs/core/StatusManager.js +13 -9
  16. package/src/_cjs/core/StatusManager.js.map +1 -1
  17. package/src/_cjs/core/UTXO/UTXOStepExecutor.js +1 -13
  18. package/src/_cjs/core/UTXO/UTXOStepExecutor.js.map +1 -1
  19. package/src/_cjs/core/UTXO/getUTXOAPIPublicClient.js +3 -3
  20. package/src/_cjs/core/UTXO/getUTXOAPIPublicClient.js.map +1 -1
  21. package/src/_cjs/core/UTXO/parseUTXOErrors.js.map +1 -1
  22. package/src/_cjs/core/processMessages.js +22 -15
  23. package/src/_cjs/core/processMessages.js.map +1 -1
  24. package/src/_cjs/core/waitForDestinationChainTransaction.js +16 -1
  25. package/src/_cjs/core/waitForDestinationChainTransaction.js.map +1 -1
  26. package/src/_cjs/core/waitForTransactionStatus.js.map +1 -1
  27. package/src/_cjs/errors/SDKError.js.map +1 -1
  28. package/src/_cjs/index.js +2 -2
  29. package/src/_cjs/index.js.map +1 -1
  30. package/src/_cjs/utils/getTransactionMessage.js.map +1 -1
  31. package/src/_cjs/version.js +1 -1
  32. package/src/_esm/core/EVM/EVMStepExecutor.js +273 -233
  33. package/src/_esm/core/EVM/EVMStepExecutor.js.map +1 -1
  34. package/src/_esm/core/EVM/getNativePermit.js +147 -60
  35. package/src/_esm/core/EVM/getNativePermit.js.map +1 -1
  36. package/src/_esm/core/EVM/parseEVMErrors.js +2 -1
  37. package/src/_esm/core/EVM/parseEVMErrors.js.map +1 -1
  38. package/src/_esm/core/EVM/signPermitMessage.js +1 -7
  39. package/src/_esm/core/EVM/signPermitMessage.js.map +1 -1
  40. package/src/_esm/core/EVM/typeguards.js +2 -2
  41. package/src/_esm/core/EVM/typeguards.js.map +1 -1
  42. package/src/_esm/core/Solana/SolanaStepExecutor.js +1 -14
  43. package/src/_esm/core/Solana/SolanaStepExecutor.js.map +1 -1
  44. package/src/_esm/core/Solana/parseSolanaErrors.js.map +1 -1
  45. package/src/_esm/core/StatusManager.js +24 -18
  46. package/src/_esm/core/StatusManager.js.map +1 -1
  47. package/src/_esm/core/UTXO/UTXOStepExecutor.js +1 -14
  48. package/src/_esm/core/UTXO/UTXOStepExecutor.js.map +1 -1
  49. package/src/_esm/core/UTXO/getUTXOAPIPublicClient.js +3 -3
  50. package/src/_esm/core/UTXO/getUTXOAPIPublicClient.js.map +1 -1
  51. package/src/_esm/core/UTXO/parseUTXOErrors.js.map +1 -1
  52. package/src/_esm/core/processMessages.js +22 -15
  53. package/src/_esm/core/processMessages.js.map +1 -1
  54. package/src/_esm/core/waitForDestinationChainTransaction.js +17 -1
  55. package/src/_esm/core/waitForDestinationChainTransaction.js.map +1 -1
  56. package/src/_esm/core/waitForTransactionStatus.js.map +1 -1
  57. package/src/_esm/errors/SDKError.js.map +1 -1
  58. package/src/_esm/index.js +1 -1
  59. package/src/_esm/index.js.map +1 -1
  60. package/src/_esm/utils/getTransactionMessage.js.map +1 -1
  61. package/src/_esm/version.js +1 -1
  62. package/src/_types/core/EVM/EVMStepExecutor.d.ts +13 -3
  63. package/src/_types/core/EVM/EVMStepExecutor.d.ts.map +1 -1
  64. package/src/_types/core/EVM/checkAllowance.d.ts.map +1 -1
  65. package/src/_types/core/EVM/getNativePermit.d.ts +2 -0
  66. package/src/_types/core/EVM/getNativePermit.d.ts.map +1 -1
  67. package/src/_types/core/EVM/parseEVMErrors.d.ts +2 -1
  68. package/src/_types/core/EVM/parseEVMErrors.d.ts.map +1 -1
  69. package/src/_types/core/EVM/signPermitMessage.d.ts.map +1 -1
  70. package/src/_types/core/EVM/typeguards.d.ts +1 -1
  71. package/src/_types/core/EVM/typeguards.d.ts.map +1 -1
  72. package/src/_types/core/Solana/SolanaStepExecutor.d.ts.map +1 -1
  73. package/src/_types/core/Solana/parseSolanaErrors.d.ts +2 -1
  74. package/src/_types/core/Solana/parseSolanaErrors.d.ts.map +1 -1
  75. package/src/_types/core/StatusManager.d.ts +14 -11
  76. package/src/_types/core/StatusManager.d.ts.map +1 -1
  77. package/src/_types/core/UTXO/UTXOStepExecutor.d.ts.map +1 -1
  78. package/src/_types/core/UTXO/parseUTXOErrors.d.ts +2 -1
  79. package/src/_types/core/UTXO/parseUTXOErrors.d.ts.map +1 -1
  80. package/src/_types/core/processMessages.d.ts +3 -1
  81. package/src/_types/core/processMessages.d.ts.map +1 -1
  82. package/src/_types/core/types.d.ts +32 -1
  83. package/src/_types/core/types.d.ts.map +1 -1
  84. package/src/_types/core/waitForDestinationChainTransaction.d.ts +3 -3
  85. package/src/_types/core/waitForDestinationChainTransaction.d.ts.map +1 -1
  86. package/src/_types/core/waitForTransactionStatus.d.ts +2 -1
  87. package/src/_types/core/waitForTransactionStatus.d.ts.map +1 -1
  88. package/src/_types/errors/SDKError.d.ts +2 -1
  89. package/src/_types/errors/SDKError.d.ts.map +1 -1
  90. package/src/_types/index.d.ts +2 -2
  91. package/src/_types/index.d.ts.map +1 -1
  92. package/src/_types/utils/getTransactionMessage.d.ts +2 -1
  93. package/src/_types/utils/getTransactionMessage.d.ts.map +1 -1
  94. package/src/_types/version.d.ts +1 -1
  95. package/src/core/EVM/EVMStepExecutor.ts +353 -293
  96. package/src/core/EVM/checkAllowance.ts +2 -2
  97. package/src/core/EVM/getNativePermit.ts +219 -66
  98. package/src/core/EVM/parseEVMErrors.ts +6 -2
  99. package/src/core/EVM/signPermitMessage.ts +1 -8
  100. package/src/core/EVM/typeguards.ts +2 -2
  101. package/src/core/Solana/SolanaStepExecutor.ts +2 -16
  102. package/src/core/Solana/parseSolanaErrors.ts +2 -1
  103. package/src/core/StatusManager.ts +38 -26
  104. package/src/core/UTXO/UTXOStepExecutor.ts +2 -16
  105. package/src/core/UTXO/getUTXOAPIPublicClient.ts +3 -3
  106. package/src/core/UTXO/parseUTXOErrors.ts +2 -1
  107. package/src/core/processMessages.ts +25 -21
  108. package/src/core/types.ts +54 -1
  109. package/src/core/waitForDestinationChainTransaction.ts +21 -4
  110. package/src/core/waitForTransactionStatus.ts +2 -6
  111. package/src/errors/SDKError.ts +2 -1
  112. package/src/index.ts +6 -1
  113. package/src/utils/getTransactionMessage.ts +2 -1
  114. package/src/version.ts +1 -1
@@ -1,8 +1,8 @@
1
- import type { ExtendedChain, LiFiStep, Process, ProcessType } from '@lifi/types'
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 type { Address, Client } from 'viem'
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
- if (multicallAddress) {
31
- const [nameResult, domainSeparatorResult, noncesResult, versionResult] =
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
- readContract(client, {
174
+ },
175
+ {
83
176
  address: tokenAddress,
84
177
  abi: eip2612Abi,
85
178
  functionName: 'DOMAIN_SEPARATOR',
86
- }),
87
- readContract(client, {
179
+ },
180
+ {
88
181
  address: tokenAddress,
89
182
  abi: eip2612Abi,
90
183
  functionName: 'nonces',
91
184
  args: [client.account!.address],
92
- }),
93
- readContract(client, {
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: version ?? '1',
103
- nonce,
104
- supported: !!name && !!domainSeparator && nonce !== undefined,
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, Process } from '@lifi/types'
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 (e.cause?.name === 'UserRejectedRequestError') {
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 isEVMPermitStep(step: LiFiStepExtended): step is EVMPermitStep {
4
+ export function isRelayerStep(step: LiFiStepExtended): step is EVMPermitStep {
5
5
  const evmStep = step as EVMPermitStep
6
- return 'permit' in evmStep || 'permitData' in evmStep || 'witness' 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.type,
237
- transactionHash,
222
+ process,
223
+ fromChain,
238
224
  toChain,
239
225
  this.statusManager
240
226
  )
@@ -1,8 +1,9 @@
1
- import type { LiFiStep, Process } from '@lifi/types'
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
- LiFiStep,
7
+ LiFiStepExtended,
6
8
  Process,
7
9
  ProcessStatus,
8
10
  ProcessType,
9
- } from '@lifi/types'
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.step The step that should contain the new process.
86
- * @param step.type Type of the process. Used to identify already existing processes.
87
- * @param step.chainId Chain Id of the process.
88
- * @param step.status By default created procces is set to the STARTED status. We can override new process with the needed status.
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
- if (!step.execution?.process) {
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.process.push(newProcess)
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 = step?.execution?.process.find((p) => p.type === type)
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.type,
283
- transactionHash,
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, Process } from '@lifi/types'
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
- ProcessStatus,
3
- ProcessType,
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
- PENDING: 'Chain switch required.',
19
- DONE: 'Chain switched successfully.',
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
  }