@lifi/sdk 3.0.1 → 3.1.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 (237) hide show
  1. package/package.json +4 -4
  2. package/src/_cjs/constants.js +2 -1
  3. package/src/_cjs/constants.js.map +1 -1
  4. package/src/_cjs/core/EVM/EVMStepExecutor.js +16 -15
  5. package/src/_cjs/core/EVM/EVMStepExecutor.js.map +1 -1
  6. package/src/_cjs/core/EVM/checkAllowance.js +3 -4
  7. package/src/_cjs/core/EVM/checkAllowance.js.map +1 -1
  8. package/src/_cjs/core/EVM/multisig.js +4 -3
  9. package/src/_cjs/core/EVM/multisig.js.map +1 -1
  10. package/src/_cjs/core/EVM/parseEVMErrors.js +38 -0
  11. package/src/_cjs/core/EVM/parseEVMErrors.js.map +1 -0
  12. package/src/_cjs/core/EVM/publicClient.js +8 -3
  13. package/src/_cjs/core/EVM/publicClient.js.map +1 -1
  14. package/src/_cjs/core/EVM/switchChain.js +4 -3
  15. package/src/_cjs/core/EVM/switchChain.js.map +1 -1
  16. package/src/_cjs/core/Solana/SolanaStepExecutor.js +54 -32
  17. package/src/_cjs/core/Solana/SolanaStepExecutor.js.map +1 -1
  18. package/src/_cjs/core/Solana/connection.js.map +1 -1
  19. package/src/_cjs/core/Solana/getSolanaBalance.js +1 -2
  20. package/src/_cjs/core/Solana/getSolanaBalance.js.map +1 -1
  21. package/src/_cjs/core/Solana/parseSolanaErrors.js +33 -0
  22. package/src/_cjs/core/Solana/parseSolanaErrors.js.map +1 -0
  23. package/src/_cjs/core/StatusManager.js +3 -3
  24. package/src/_cjs/core/StatusManager.js.map +1 -1
  25. package/src/_cjs/core/checkBalance.js +4 -5
  26. package/src/_cjs/core/checkBalance.js.map +1 -1
  27. package/src/_cjs/core/processMessages.js +61 -0
  28. package/src/_cjs/core/processMessages.js.map +1 -0
  29. package/src/_cjs/core/stepComparison.js +3 -3
  30. package/src/_cjs/core/stepComparison.js.map +1 -1
  31. package/src/_cjs/core/utils.js +6 -58
  32. package/src/_cjs/core/utils.js.map +1 -1
  33. package/src/_cjs/core/waitForReceivingTransaction.js +3 -3
  34. package/src/_cjs/core/waitForReceivingTransaction.js.map +1 -1
  35. package/src/_cjs/errors/SDKError.js +48 -0
  36. package/src/_cjs/errors/SDKError.js.map +1 -0
  37. package/src/_cjs/errors/baseError.js +30 -0
  38. package/src/_cjs/errors/baseError.js.map +1 -0
  39. package/src/_cjs/errors/constants.js +48 -0
  40. package/src/_cjs/errors/constants.js.map +1 -0
  41. package/src/_cjs/errors/errors.js +48 -0
  42. package/src/_cjs/errors/errors.js.map +1 -0
  43. package/src/_cjs/errors/httpError.js +101 -0
  44. package/src/_cjs/errors/httpError.js.map +1 -0
  45. package/src/_cjs/errors/index.js +11 -0
  46. package/src/_cjs/errors/index.js.map +1 -0
  47. package/src/_cjs/errors/utils/baseErrorRootCause.js +21 -0
  48. package/src/_cjs/errors/utils/baseErrorRootCause.js.map +1 -0
  49. package/src/_cjs/errors/utils/rootCause.js +12 -0
  50. package/src/_cjs/errors/utils/rootCause.js.map +1 -0
  51. package/src/_cjs/helpers.js +13 -8
  52. package/src/_cjs/helpers.js.map +1 -1
  53. package/src/_cjs/index.js +2 -4
  54. package/src/_cjs/index.js.map +1 -1
  55. package/src/_cjs/request.js +37 -34
  56. package/src/_cjs/request.js.map +1 -1
  57. package/src/_cjs/services/api.js +61 -132
  58. package/src/_cjs/services/api.js.map +1 -1
  59. package/src/_cjs/services/balance.js +1 -1
  60. package/src/_cjs/services/balance.js.map +1 -1
  61. package/src/_cjs/types/request.js +3 -0
  62. package/src/_cjs/types/request.js.map +1 -0
  63. package/src/_cjs/utils/errors.js +0 -182
  64. package/src/_cjs/utils/errors.js.map +1 -1
  65. package/src/_cjs/utils/index.js +1 -2
  66. package/src/_cjs/utils/index.js.map +1 -1
  67. package/src/_cjs/version.js +1 -1
  68. package/src/_cjs/version.js.map +1 -1
  69. package/src/_esm/constants.js +1 -0
  70. package/src/_esm/constants.js.map +1 -1
  71. package/src/_esm/core/EVM/EVMStepExecutor.js +9 -8
  72. package/src/_esm/core/EVM/EVMStepExecutor.js.map +1 -1
  73. package/src/_esm/core/EVM/checkAllowance.js +3 -4
  74. package/src/_esm/core/EVM/checkAllowance.js.map +1 -1
  75. package/src/_esm/core/EVM/multisig.js +2 -1
  76. package/src/_esm/core/EVM/multisig.js.map +1 -1
  77. package/src/_esm/core/EVM/parseEVMErrors.js +35 -0
  78. package/src/_esm/core/EVM/parseEVMErrors.js.map +1 -0
  79. package/src/_esm/core/EVM/publicClient.js +9 -4
  80. package/src/_esm/core/EVM/publicClient.js.map +1 -1
  81. package/src/_esm/core/EVM/switchChain.js +2 -1
  82. package/src/_esm/core/EVM/switchChain.js.map +1 -1
  83. package/src/_esm/core/Solana/SolanaStepExecutor.js +67 -36
  84. package/src/_esm/core/Solana/SolanaStepExecutor.js.map +1 -1
  85. package/src/_esm/core/Solana/connection.js +2 -3
  86. package/src/_esm/core/Solana/connection.js.map +1 -1
  87. package/src/_esm/core/Solana/getSolanaBalance.js +2 -3
  88. package/src/_esm/core/Solana/getSolanaBalance.js.map +1 -1
  89. package/src/_esm/core/Solana/parseSolanaErrors.js +29 -0
  90. package/src/_esm/core/Solana/parseSolanaErrors.js.map +1 -0
  91. package/src/_esm/core/StatusManager.js +1 -1
  92. package/src/_esm/core/StatusManager.js.map +1 -1
  93. package/src/_esm/core/checkBalance.js +4 -5
  94. package/src/_esm/core/checkBalance.js.map +1 -1
  95. package/src/_esm/core/processMessages.js +58 -0
  96. package/src/_esm/core/processMessages.js.map +1 -0
  97. package/src/_esm/core/stepComparison.js +3 -3
  98. package/src/_esm/core/stepComparison.js.map +1 -1
  99. package/src/_esm/core/utils.js +7 -58
  100. package/src/_esm/core/utils.js.map +1 -1
  101. package/src/_esm/core/waitForReceivingTransaction.js +2 -2
  102. package/src/_esm/core/waitForReceivingTransaction.js.map +1 -1
  103. package/src/_esm/errors/SDKError.js +47 -0
  104. package/src/_esm/errors/SDKError.js.map +1 -0
  105. package/src/_esm/errors/baseError.js +28 -0
  106. package/src/_esm/errors/baseError.js.map +1 -0
  107. package/src/_esm/errors/constants.js +45 -0
  108. package/src/_esm/errors/constants.js.map +1 -0
  109. package/src/_esm/errors/errors.js +38 -0
  110. package/src/_esm/errors/errors.js.map +1 -0
  111. package/src/_esm/errors/httpError.js +97 -0
  112. package/src/_esm/errors/httpError.js.map +1 -0
  113. package/src/_esm/errors/index.js +8 -0
  114. package/src/_esm/errors/index.js.map +1 -0
  115. package/src/_esm/errors/utils/baseErrorRootCause.js +16 -0
  116. package/src/_esm/errors/utils/baseErrorRootCause.js.map +1 -0
  117. package/src/_esm/errors/utils/rootCause.js +8 -0
  118. package/src/_esm/errors/utils/rootCause.js.map +1 -0
  119. package/src/_esm/helpers.js +16 -9
  120. package/src/_esm/helpers.js.map +1 -1
  121. package/src/_esm/index.js +2 -2
  122. package/src/_esm/index.js.map +1 -1
  123. package/src/_esm/request.js +38 -35
  124. package/src/_esm/request.js.map +1 -1
  125. package/src/_esm/services/api.js +61 -133
  126. package/src/_esm/services/api.js.map +1 -1
  127. package/src/_esm/services/balance.js +4 -4
  128. package/src/_esm/services/balance.js.map +1 -1
  129. package/src/_esm/types/request.js +2 -0
  130. package/src/_esm/types/request.js.map +1 -0
  131. package/src/_esm/utils/errors.js +1 -172
  132. package/src/_esm/utils/errors.js.map +1 -1
  133. package/src/_esm/utils/index.js +1 -2
  134. package/src/_esm/utils/index.js.map +1 -1
  135. package/src/_esm/version.js +1 -1
  136. package/src/_esm/version.js.map +1 -1
  137. package/src/_types/constants.d.ts +1 -0
  138. package/src/_types/constants.d.ts.map +1 -1
  139. package/src/_types/core/EVM/EVMStepExecutor.d.ts.map +1 -1
  140. package/src/_types/core/EVM/checkAllowance.d.ts.map +1 -1
  141. package/src/_types/core/EVM/multisig.d.ts.map +1 -1
  142. package/src/_types/core/EVM/parseEVMErrors.d.ts +4 -0
  143. package/src/_types/core/EVM/parseEVMErrors.d.ts.map +1 -0
  144. package/src/_types/core/EVM/publicClient.d.ts.map +1 -1
  145. package/src/_types/core/EVM/switchChain.d.ts.map +1 -1
  146. package/src/_types/core/Solana/SolanaStepExecutor.d.ts.map +1 -1
  147. package/src/_types/core/Solana/connection.d.ts +2 -3
  148. package/src/_types/core/Solana/connection.d.ts.map +1 -1
  149. package/src/_types/core/Solana/parseSolanaErrors.d.ts +4 -0
  150. package/src/_types/core/Solana/parseSolanaErrors.d.ts.map +1 -0
  151. package/src/_types/core/StatusManager.d.ts.map +1 -1
  152. package/src/_types/core/checkBalance.d.ts.map +1 -1
  153. package/src/_types/core/processMessages.d.ts +4 -0
  154. package/src/_types/core/processMessages.d.ts.map +1 -0
  155. package/src/_types/core/stepComparison.d.ts.map +1 -1
  156. package/src/_types/core/utils.d.ts +4 -5
  157. package/src/_types/core/utils.d.ts.map +1 -1
  158. package/src/_types/errors/SDKError.d.ts +12 -0
  159. package/src/_types/errors/SDKError.d.ts.map +1 -0
  160. package/src/_types/errors/baseError.d.ts +7 -0
  161. package/src/_types/errors/baseError.d.ts.map +1 -0
  162. package/src/_types/errors/constants.d.ts +43 -0
  163. package/src/_types/errors/constants.d.ts.map +1 -0
  164. package/src/_types/errors/errors.d.ts +24 -0
  165. package/src/_types/errors/errors.d.ts.map +1 -0
  166. package/src/_types/errors/httpError.d.ts +21 -0
  167. package/src/_types/errors/httpError.d.ts.map +1 -0
  168. package/src/_types/errors/index.d.ts +8 -0
  169. package/src/_types/errors/index.d.ts.map +1 -0
  170. package/src/_types/errors/utils/baseErrorRootCause.d.ts +4 -0
  171. package/src/_types/errors/utils/baseErrorRootCause.d.ts.map +1 -0
  172. package/src/_types/errors/utils/rootCause.d.ts +2 -0
  173. package/src/_types/errors/utils/rootCause.d.ts.map +1 -0
  174. package/src/_types/helpers.d.ts +5 -4
  175. package/src/_types/helpers.d.ts.map +1 -1
  176. package/src/_types/index.d.ts +2 -2
  177. package/src/_types/index.d.ts.map +1 -1
  178. package/src/_types/request.d.ts +1 -5
  179. package/src/_types/request.d.ts.map +1 -1
  180. package/src/_types/services/api.d.ts.map +1 -1
  181. package/src/_types/services/balance.d.ts +3 -3
  182. package/src/_types/types/request.d.ts +4 -0
  183. package/src/_types/types/request.d.ts.map +1 -0
  184. package/src/_types/utils/errors.d.ts +0 -108
  185. package/src/_types/utils/errors.d.ts.map +1 -1
  186. package/src/_types/utils/index.d.ts +1 -2
  187. package/src/_types/utils/index.d.ts.map +1 -1
  188. package/src/_types/version.d.ts +1 -1
  189. package/src/_types/version.d.ts.map +1 -1
  190. package/src/constants.ts +1 -0
  191. package/src/core/EVM/EVMStepExecutor.ts +15 -13
  192. package/src/core/EVM/checkAllowance.ts +3 -4
  193. package/src/core/EVM/multisig.ts +2 -1
  194. package/src/core/EVM/parseEVMErrors.ts +60 -0
  195. package/src/core/EVM/publicClient.ts +9 -4
  196. package/src/core/EVM/switchChain.ts +2 -1
  197. package/src/core/Solana/SolanaStepExecutor.ts +92 -52
  198. package/src/core/Solana/connection.ts +2 -3
  199. package/src/core/Solana/getSolanaBalance.ts +2 -3
  200. package/src/core/Solana/parseSolanaErrors.ts +45 -0
  201. package/src/core/StatusManager.ts +1 -1
  202. package/src/core/checkBalance.ts +4 -5
  203. package/src/core/processMessages.ts +81 -0
  204. package/src/core/stepComparison.ts +3 -4
  205. package/src/core/utils.ts +9 -84
  206. package/src/core/waitForReceivingTransaction.ts +2 -2
  207. package/src/errors/SDKError.ts +25 -0
  208. package/src/errors/baseError.ts +22 -0
  209. package/src/errors/constants.ts +45 -0
  210. package/src/errors/errors.ts +44 -0
  211. package/src/errors/httpError.ts +93 -0
  212. package/src/errors/index.ts +7 -0
  213. package/src/errors/utils/baseErrorRootCause.ts +18 -0
  214. package/src/errors/utils/rootCause.ts +7 -0
  215. package/src/helpers.ts +23 -16
  216. package/src/index.ts +2 -2
  217. package/src/request.ts +52 -38
  218. package/src/services/api.ts +109 -157
  219. package/src/services/balance.ts +4 -4
  220. package/src/types/request.ts +3 -0
  221. package/src/utils/errors.ts +0 -232
  222. package/src/utils/index.ts +1 -2
  223. package/src/version.ts +1 -1
  224. package/src/_cjs/utils/parseBackendError.js +0 -27
  225. package/src/_cjs/utils/parseBackendError.js.map +0 -1
  226. package/src/_cjs/utils/parseError.js +0 -69
  227. package/src/_cjs/utils/parseError.js.map +0 -1
  228. package/src/_esm/utils/parseBackendError.js +0 -24
  229. package/src/_esm/utils/parseBackendError.js.map +0 -1
  230. package/src/_esm/utils/parseError.js +0 -100
  231. package/src/_esm/utils/parseError.js.map +0 -1
  232. package/src/_types/utils/parseBackendError.d.ts +0 -3
  233. package/src/_types/utils/parseBackendError.d.ts.map +0 -1
  234. package/src/_types/utils/parseError.d.ts +0 -35
  235. package/src/_types/utils/parseError.d.ts.map +0 -1
  236. package/src/utils/parseBackendError.ts +0 -50
  237. package/src/utils/parseError.ts +0 -210
@@ -1,6 +1,6 @@
1
1
  import type { ChainId, Token, TokenAmount } from '@lifi/types'
2
2
  import { PublicKey } from '@solana/web3.js'
3
- import { wrappedSolAddress } from '../../constants.js'
3
+ import { SolSystemProgram } from '../../constants.js'
4
4
  import { getSolanaConnection } from './connection.js'
5
5
  import { TokenProgramAddress } from './types.js'
6
6
 
@@ -53,8 +53,7 @@ const getSolanaBalanceDefault = async (
53
53
  {} as Record<string, bigint>
54
54
  )
55
55
  : {}
56
- walletTokenAmounts[wrappedSolAddress] ??= 0n
57
- walletTokenAmounts[wrappedSolAddress] += solBalance
56
+ walletTokenAmounts[SolSystemProgram] = solBalance
58
57
  const tokenAmounts: TokenAmount[] = tokens.map((token) => {
59
58
  if (walletTokenAmounts[token.address]) {
60
59
  return {
@@ -0,0 +1,45 @@
1
+ import type { LiFiStep, Process } from '@lifi/types'
2
+ import { BaseError } from '../../errors/baseError.js'
3
+ import { ErrorMessage, LiFiErrorCode } from '../../errors/constants.js'
4
+ import { TransactionError, UnknownError } from '../../errors/errors.js'
5
+ import { SDKError } from '../../errors/SDKError.js'
6
+
7
+ export const parseSolanaErrors = async (
8
+ e: Error,
9
+ step?: LiFiStep,
10
+ process?: Process
11
+ ): Promise<SDKError> => {
12
+ if (e instanceof SDKError) {
13
+ e.step = e.step ?? step
14
+ e.process = e.process ?? process
15
+ return e
16
+ }
17
+
18
+ const baseError = handleSpecificErrors(e)
19
+
20
+ return new SDKError(baseError, step, process)
21
+ }
22
+
23
+ const handleSpecificErrors = (e: any) => {
24
+ if (e.name === 'WalletSignTransactionError') {
25
+ return new TransactionError(LiFiErrorCode.SignatureRejected, e.message, e)
26
+ }
27
+
28
+ if (e.name === 'SendTransactionError') {
29
+ return new TransactionError(LiFiErrorCode.TransactionFailed, e.message, e)
30
+ }
31
+
32
+ if (e.message?.includes('simulate')) {
33
+ return new TransactionError(
34
+ LiFiErrorCode.TransactionSimulationFailed,
35
+ e.message,
36
+ e
37
+ )
38
+ }
39
+
40
+ if (e instanceof BaseError) {
41
+ return e
42
+ }
43
+
44
+ return new UnknownError(e.message || ErrorMessage.UnknownError, e)
45
+ }
@@ -7,8 +7,8 @@ import type {
7
7
  ProcessType,
8
8
  } from '@lifi/types'
9
9
  import { executionState } from './executionState.js'
10
+ import { getProcessMessage } from './processMessages.js'
10
11
  import type { LiFiStepExtended } from './types.js'
11
- import { getProcessMessage } from './utils.js'
12
12
 
13
13
  type OptionalParameters = Partial<
14
14
  Pick<
@@ -1,7 +1,8 @@
1
1
  import type { LiFiStep } from '@lifi/types'
2
2
  import { formatUnits } from 'viem'
3
3
  import { getTokenBalance } from '../services/balance.js'
4
- import { BalanceError } from '../utils/errors.js'
4
+ import { BalanceError } from '../errors/errors.js'
5
+ import { sleep } from './utils.js'
5
6
 
6
7
  export const checkBalance = async (
7
8
  walletAddress: string,
@@ -15,9 +16,7 @@ export const checkBalance = async (
15
16
 
16
17
  if (currentBalance < neededBalance) {
17
18
  if (depth <= 3) {
18
- await new Promise((resolve) => {
19
- setTimeout(resolve, 200)
20
- })
19
+ await sleep(200)
21
20
  await checkBalance(walletAddress, step, depth + 1)
22
21
  } else if (
23
22
  (neededBalance * BigInt((1 - step.action.slippage) * 1_000_000_000)) /
@@ -41,7 +40,7 @@ export const checkBalance = async (
41
40
  `start a new one with a maximum of ${current} ${token.symbol}.`
42
41
  }
43
42
 
44
- throw new BalanceError('The balance is too low.', errorMessage)
43
+ throw new BalanceError('The balance is too low.')
45
44
  }
46
45
  }
47
46
  }
@@ -0,0 +1,81 @@
1
+ import {
2
+ type ProcessStatus,
3
+ type ProcessType,
4
+ type StatusMessage,
5
+ type Substatus,
6
+ } from '@lifi/types'
7
+
8
+ const processMessages: Record<
9
+ ProcessType,
10
+ Partial<Record<ProcessStatus, string>>
11
+ > = {
12
+ TOKEN_ALLOWANCE: {
13
+ STARTED: 'Setting token allowance.',
14
+ PENDING: 'Waiting for token allowance.',
15
+ DONE: 'Token allowance set.',
16
+ },
17
+ SWITCH_CHAIN: {
18
+ PENDING: 'Chain switch required.',
19
+ DONE: 'Chain switched successfully.',
20
+ },
21
+ SWAP: {
22
+ STARTED: 'Preparing swap transaction.',
23
+ ACTION_REQUIRED: 'Please sign the transaction.',
24
+ PENDING: 'Waiting for swap transaction.',
25
+ DONE: 'Swap completed.',
26
+ },
27
+ 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.',
32
+ },
33
+ RECEIVING_CHAIN: {
34
+ PENDING: 'Waiting for destination chain.',
35
+ DONE: 'Bridge completed.',
36
+ },
37
+ TRANSACTION: {},
38
+ }
39
+ const substatusMessages: Record<
40
+ StatusMessage,
41
+ Partial<Record<Substatus, string>>
42
+ > = {
43
+ PENDING: {
44
+ BRIDGE_NOT_AVAILABLE: 'Bridge communication is temporarily unavailable.',
45
+ CHAIN_NOT_AVAILABLE: 'RPC communication is temporarily unavailable.',
46
+ UNKNOWN_ERROR:
47
+ 'An unexpected error occurred. Please seek assistance in the LI.FI discord server.',
48
+ WAIT_SOURCE_CONFIRMATIONS:
49
+ 'The bridge deposit has been received. The bridge is waiting for more confirmations to start the off-chain logic.',
50
+ WAIT_DESTINATION_TRANSACTION:
51
+ 'The bridge off-chain logic is being executed. Wait for the transaction to appear on the destination chain.',
52
+ },
53
+ DONE: {
54
+ PARTIAL:
55
+ 'Some of the received tokens are not the requested destination tokens.',
56
+ REFUNDED: 'The tokens were refunded to the sender address.',
57
+ COMPLETED: 'The transfer is complete.',
58
+ },
59
+ FAILED: {},
60
+ INVALID: {},
61
+ NOT_FOUND: {},
62
+ }
63
+
64
+ export function getProcessMessage(
65
+ type: ProcessType,
66
+ status: ProcessStatus
67
+ ): string | undefined {
68
+ const processMessage = processMessages[type][status]
69
+ return processMessage
70
+ }
71
+
72
+ export function getSubstatusMessage(
73
+ status: StatusMessage,
74
+ substatus?: Substatus
75
+ ): string | undefined {
76
+ if (!substatus) {
77
+ return
78
+ }
79
+ const message = substatusMessages[status][substatus]
80
+ return message
81
+ }
@@ -1,5 +1,6 @@
1
1
  import type { LiFiStep } from '@lifi/types'
2
- import { LiFiErrorCode, TransactionError } from '../utils/errors.js'
2
+ import { LiFiErrorCode } from '../errors/constants.js'
3
+ import { TransactionError } from '../errors/errors.js'
3
4
  import type { StatusManager } from './StatusManager.js'
4
5
  import type { ExecutionOptions } from './types.js'
5
6
  import { checkStepSlippageThreshold } from './utils.js'
@@ -41,9 +42,7 @@ export const stepComparison = async (
41
42
  // The user declined the new exchange rate, so we are not going to proceed
42
43
  throw new TransactionError(
43
44
  LiFiErrorCode.ExchangeRateUpdateCanceled,
44
- 'Exchange rate has changed!',
45
- `Transaction was not sent, your funds are still in your wallet.
46
- The exchange rate has changed and the previous estimation can not be fulfilled due to value loss.`
45
+ `Exchange rate has changed!\nTransaction was not sent, your funds are still in your wallet.\nThe exchange rate has changed and the previous estimation can not be fulfilled due to value loss.`
47
46
  )
48
47
  }
49
48
 
package/src/core/utils.ts CHANGED
@@ -1,92 +1,11 @@
1
- import {
2
- type LiFiStep,
3
- type ProcessStatus,
4
- type ProcessType,
5
- type StatusMessage,
6
- type Substatus,
7
- } from '@lifi/types'
8
-
9
- const processMessages: Record<
10
- ProcessType,
11
- Partial<Record<ProcessStatus, string>>
12
- > = {
13
- TOKEN_ALLOWANCE: {
14
- STARTED: 'Setting token allowance.',
15
- PENDING: 'Waiting for token allowance.',
16
- DONE: 'Token allowance set.',
17
- },
18
- SWITCH_CHAIN: {
19
- PENDING: 'Chain switch required.',
20
- DONE: 'Chain switched successfully.',
21
- },
22
- SWAP: {
23
- STARTED: 'Preparing swap transaction.',
24
- ACTION_REQUIRED: 'Please sign the transaction.',
25
- PENDING: 'Waiting for swap transaction.',
26
- DONE: 'Swap completed.',
27
- },
28
- CROSS_CHAIN: {
29
- STARTED: 'Preparing bridge transaction.',
30
- ACTION_REQUIRED: 'Please sign the transaction.',
31
- PENDING: 'Waiting for bridge transaction.',
32
- DONE: 'Bridge transaction confirmed.',
33
- },
34
- RECEIVING_CHAIN: {
35
- PENDING: 'Waiting for destination chain.',
36
- DONE: 'Bridge completed.',
37
- },
38
- TRANSACTION: {},
39
- }
40
- const substatusMessages: Record<
41
- StatusMessage,
42
- Partial<Record<Substatus, string>>
43
- > = {
44
- PENDING: {
45
- BRIDGE_NOT_AVAILABLE: 'Bridge communication is temporarily unavailable.',
46
- CHAIN_NOT_AVAILABLE: 'RPC communication is temporarily unavailable.',
47
- UNKNOWN_ERROR:
48
- 'An unexpected error occurred. Please seek assistance in the LI.FI discord server.',
49
- WAIT_SOURCE_CONFIRMATIONS:
50
- 'The bridge deposit has been received. The bridge is waiting for more confirmations to start the off-chain logic.',
51
- WAIT_DESTINATION_TRANSACTION:
52
- 'The bridge off-chain logic is being executed. Wait for the transaction to appear on the destination chain.',
53
- },
54
- DONE: {
55
- PARTIAL:
56
- 'Some of the received tokens are not the requested destination tokens.',
57
- REFUNDED: 'The tokens were refunded to the sender address.',
58
- COMPLETED: 'The transfer is complete.',
59
- },
60
- FAILED: {},
61
- INVALID: {},
62
- NOT_FOUND: {},
63
- }
64
-
65
- export function getProcessMessage(
66
- type: ProcessType,
67
- status: ProcessStatus
68
- ): string | undefined {
69
- const processMessage = processMessages[type][status]
70
- return processMessage
71
- }
72
-
73
- export function getSubstatusMessage(
74
- status: StatusMessage,
75
- substatus?: Substatus
76
- ): string | undefined {
77
- if (!substatus) {
78
- return
79
- }
80
- const message = substatusMessages[status][substatus]
81
- return message
82
- }
1
+ import { type LiFiStep } from '@lifi/types'
83
2
 
84
3
  /**
85
4
  * Used to check if changed exchange rate is in the range of slippage threshold.
86
5
  * We use a slippage value as a threshold to trigger the rate change hook.
87
6
  * This can result in almost doubled slippage for the user and need to be revisited.
88
- * @param oldStep
89
- * @param newStep
7
+ * @param oldStep - old step
8
+ * @param newStep - new step
90
9
  * @returns Boolean
91
10
  */
92
11
  export function checkStepSlippageThreshold(
@@ -106,3 +25,9 @@ export function checkStepSlippageThreshold(
106
25
  }
107
26
  return actualSlippage <= setSlippage
108
27
  }
28
+
29
+ export function sleep(ms: number): Promise<null> {
30
+ return new Promise((resolve) => {
31
+ setTimeout(() => resolve(null), ms)
32
+ })
33
+ }
@@ -5,10 +5,10 @@ import type {
5
5
  StatusResponse,
6
6
  } from '@lifi/types'
7
7
  import { getStatus } from '../services/api.js'
8
- import { ServerError } from '../utils/errors.js'
8
+ import { ServerError } from '../errors/errors.js'
9
9
  import { repeatUntilDone } from '../utils/utils.js'
10
10
  import type { StatusManager } from './StatusManager.js'
11
- import { getSubstatusMessage } from './utils.js'
11
+ import { getSubstatusMessage } from './processMessages.js'
12
12
 
13
13
  const TRANSACTION_HASH_OBSERVERS: Record<string, Promise<StatusResponse>> = {}
14
14
 
@@ -0,0 +1,25 @@
1
+ import type { LiFiStep, Process } from '@lifi/types'
2
+ import { version } from '../version.js'
3
+ import type { BaseError } from './baseError.js'
4
+ import { type ErrorCode } from './constants.js'
5
+
6
+ // Note: SDKError is used to wrapper and present errors at the top level
7
+ // Where opportunity allows we also add the step and the process related to the error
8
+ export class SDKError extends Error {
9
+ step?: LiFiStep
10
+ process?: Process
11
+ code: ErrorCode
12
+ override name = 'SDKError'
13
+ override cause: BaseError
14
+
15
+ constructor(cause: BaseError, step?: LiFiStep, process?: Process) {
16
+ const errorMessage = `${cause.message ? `[${cause.name}] ${cause.message}` : 'Unknown error occurred'}\nLI.FI SDK version: ${version}`
17
+ super(errorMessage)
18
+ this.name = 'SDKError'
19
+ this.step = step
20
+ this.process = process
21
+ this.cause = cause
22
+ this.stack = this.cause.stack
23
+ this.code = cause.code
24
+ }
25
+ }
@@ -0,0 +1,22 @@
1
+ import type { ErrorCode, ErrorName } from './constants.js'
2
+ import { getRootCause } from './utils/rootCause.js'
3
+
4
+ // Note: we use the BaseErrors to capture errors at specific points in the code
5
+ // they can carry addition to help give more context
6
+ export class BaseError extends Error {
7
+ code: ErrorCode
8
+ override cause?: Error
9
+
10
+ constructor(name: ErrorName, code: number, message: string, cause?: Error) {
11
+ super(message)
12
+
13
+ this.name = name
14
+ this.code = code
15
+ this.cause = cause
16
+
17
+ const rootCause = getRootCause(this.cause)
18
+ if (rootCause && rootCause.stack) {
19
+ this.stack = rootCause.stack
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,45 @@
1
+ export enum ErrorName {
2
+ RPCError = 'RPCError',
3
+ ProviderError = 'ProviderError',
4
+ ServerError = 'ServerError',
5
+ TransactionError = 'TransactionError',
6
+ ValidationError = 'ValidationError',
7
+ BalanceError = 'BalanceError',
8
+ NotFoundError = 'NotFoundError',
9
+ UnknownError = 'UnknownError',
10
+ SlippageError = 'SlippageError',
11
+ HTTPError = 'HTTPError',
12
+ }
13
+
14
+ export type ErrorCode = LiFiErrorCode
15
+
16
+ export enum LiFiErrorCode {
17
+ InternalError = 1000,
18
+ ValidationError = 1001,
19
+ TransactionUnderpriced = 1002,
20
+ TransactionFailed = 1003,
21
+ Timeout = 1004,
22
+ ProviderUnavailable = 1005,
23
+ NotFound = 1006,
24
+ ChainSwitchError = 1007,
25
+ TransactionUnprepared = 1008,
26
+ GasLimitError = 1009,
27
+ TransactionCanceled = 1010,
28
+ SlippageError = 1011,
29
+ SignatureRejected = 1012,
30
+ BalanceError = 1013,
31
+ AllowanceRequired = 1014,
32
+ InsufficientFunds = 1015,
33
+ ExchangeRateUpdateCanceled = 1016,
34
+ WalletChangedDuringExecution = 1017,
35
+ TransactionExpired = 1018,
36
+ TransactionSimulationFailed = 1019,
37
+ }
38
+
39
+ export enum ErrorMessage {
40
+ UnknownError = 'Unknown error occurred.',
41
+ SlippageError = 'The slippage is larger than the defined threshold. Please request a new route to get a fresh quote.',
42
+ GasLimitLow = 'Gas limit is too low.',
43
+ TransactionUnderpriced = 'Transaction is underpriced.',
44
+ TransactionReverted = 'Transaction was reverted.',
45
+ }
@@ -0,0 +1,44 @@
1
+ import { ErrorName, LiFiErrorCode } from './constants.js'
2
+ import { BaseError } from './baseError.js'
3
+
4
+ export class RPCError extends BaseError {
5
+ constructor(code: LiFiErrorCode, message: string, cause?: Error) {
6
+ super(ErrorName.RPCError, code, message, cause)
7
+ }
8
+ }
9
+
10
+ export class ProviderError extends BaseError {
11
+ constructor(code: LiFiErrorCode, message: string, cause?: Error) {
12
+ super(ErrorName.ProviderError, code, message, cause)
13
+ }
14
+ }
15
+
16
+ export class TransactionError extends BaseError {
17
+ constructor(code: LiFiErrorCode, message: string, cause?: Error) {
18
+ super(ErrorName.TransactionError, code, message, cause)
19
+ }
20
+ }
21
+
22
+ export class UnknownError extends BaseError {
23
+ constructor(message: string, cause?: Error) {
24
+ super(ErrorName.UnknownError, LiFiErrorCode.InternalError, message, cause)
25
+ }
26
+ }
27
+
28
+ export class BalanceError extends BaseError {
29
+ constructor(message: string, cause?: Error) {
30
+ super(ErrorName.BalanceError, LiFiErrorCode.BalanceError, message, cause)
31
+ }
32
+ }
33
+
34
+ export class ServerError extends BaseError {
35
+ constructor(message: string) {
36
+ super(ErrorName.ServerError, LiFiErrorCode.InternalError, message)
37
+ }
38
+ }
39
+
40
+ export class ValidationError extends BaseError {
41
+ constructor(message: string) {
42
+ super(ErrorName.ValidationError, LiFiErrorCode.ValidationError, message)
43
+ }
44
+ }
@@ -0,0 +1,93 @@
1
+ import type { UnavailableRoutes } from '@lifi/types'
2
+ import { LiFiErrorCode } from './constants.js'
3
+ import { BaseError } from './baseError.js'
4
+ import type { ExtendedRequestInit } from '../types/request.js'
5
+ import { ErrorName, ErrorMessage } from './constants.js'
6
+
7
+ interface ServerErrorResponseBody {
8
+ code: number
9
+ message: string
10
+ errors?: UnavailableRoutes
11
+ }
12
+
13
+ const statusCodeToErrorClassificationMap = new Map([
14
+ [
15
+ 400,
16
+ { type: ErrorName.ValidationError, code: LiFiErrorCode.ValidationError },
17
+ ],
18
+ [404, { type: ErrorName.NotFoundError, code: LiFiErrorCode.NotFound }],
19
+ [
20
+ 409,
21
+ {
22
+ type: ErrorName.SlippageError,
23
+ code: LiFiErrorCode.SlippageError,
24
+ message: ErrorMessage.SlippageError,
25
+ },
26
+ ],
27
+ [500, { type: ErrorName.ServerError, code: LiFiErrorCode.InternalError }],
28
+ ])
29
+
30
+ const getErrorClassificationFromStatusCode = (code: number) =>
31
+ statusCodeToErrorClassificationMap.get(code) ?? {
32
+ type: ErrorName.ServerError,
33
+ code: LiFiErrorCode.InternalError,
34
+ }
35
+
36
+ const createInitialMessage = (response: Response) => {
37
+ const statusCode =
38
+ response.status || response.status === 0 ? response.status : ''
39
+ const title = response.statusText || ''
40
+ const status = `${statusCode} ${title}`.trim()
41
+ const reason = status ? `status code ${status}` : 'an unknown error'
42
+ return `Request failed with ${reason}`
43
+ }
44
+
45
+ export class HTTPError extends BaseError {
46
+ public response: Response
47
+ public status: number
48
+ public url: RequestInfo | URL
49
+ public fetchOptions: ExtendedRequestInit
50
+ public type?: ErrorName
51
+ public responseBody?: ServerErrorResponseBody
52
+
53
+ constructor(
54
+ response: Response,
55
+ url: RequestInfo | URL,
56
+ options: ExtendedRequestInit
57
+ ) {
58
+ const errorClassification = getErrorClassificationFromStatusCode(
59
+ response.status
60
+ )
61
+ const additionalMessage = errorClassification?.message
62
+ ? `\n${errorClassification.message}`
63
+ : ''
64
+ const message = createInitialMessage(response) + additionalMessage
65
+
66
+ super(ErrorName.HTTPError, errorClassification.code, message)
67
+
68
+ this.type = errorClassification.type
69
+ this.response = response
70
+ this.status = response.status
71
+ this.message = message
72
+ this.url = url
73
+ this.fetchOptions = options
74
+ }
75
+
76
+ async buildAdditionalDetails() {
77
+ if (this.type) {
78
+ this.message = `[${this.type}] ${this.message}`
79
+ }
80
+
81
+ try {
82
+ this.responseBody = await this.response.json()
83
+
84
+ const spacer = '\n '
85
+
86
+ if (this.responseBody) {
87
+ this.message += `${spacer}responseMessage: ${this.responseBody?.message.toString().replaceAll('\n', spacer)}`
88
+ }
89
+ } catch {}
90
+
91
+ return this
92
+ }
93
+ }
@@ -0,0 +1,7 @@
1
+ export * from './baseError.js'
2
+ export * from './constants.js'
3
+ export * from './errors.js'
4
+ export * from './httpError.js'
5
+ export * from './SDKError.js'
6
+ export * from './utils/rootCause.js'
7
+ export * from './utils/baseErrorRootCause.js'
@@ -0,0 +1,18 @@
1
+ import { BaseError } from '../baseError.js'
2
+ import { HTTPError } from '../httpError.js'
3
+
4
+ export const getRootCauseBaseError = (e: Error) => {
5
+ let rootCause = e
6
+ while (rootCause.cause && rootCause.cause instanceof BaseError) {
7
+ rootCause = rootCause.cause as BaseError
8
+ }
9
+ return rootCause as BaseError
10
+ }
11
+
12
+ export const getRootCauseBaseErrorMessage = (e: Error) => {
13
+ const rootCause = getRootCauseBaseError(e)
14
+
15
+ return rootCause instanceof HTTPError
16
+ ? (rootCause as HTTPError).responseBody?.message || rootCause.message
17
+ : rootCause.message
18
+ }
@@ -0,0 +1,7 @@
1
+ export const getRootCause = (e: Error | undefined) => {
2
+ let rootCause = e
3
+ while (rootCause?.cause) {
4
+ rootCause = rootCause.cause as Error
5
+ }
6
+ return rootCause
7
+ }
package/src/helpers.ts CHANGED
@@ -1,8 +1,7 @@
1
- import type { LiFiStep, Route } from '@lifi/types'
2
- import { request } from './request.js'
3
- import type { TenderlyResponse } from './types/index.js'
4
- import { ValidationError } from './utils/errors.js'
5
1
  import { name, version } from './version.js'
2
+ import { ValidationError } from './errors/errors.js'
3
+ import { SDKError } from './errors/SDKError.js'
4
+ import type { Route, LiFiStep } from '@lifi/types'
6
5
 
7
6
  export const checkPackageUpdates = async (
8
7
  packageName?: string,
@@ -10,12 +9,11 @@ export const checkPackageUpdates = async (
10
9
  ) => {
11
10
  try {
12
11
  const pkgName = packageName ?? name
13
- const response = await request<{ version: string }>(
14
- `https://registry.npmjs.org/${pkgName}/latest`,
15
- { skipTrackingHeaders: true }
16
- )
17
- const latestVersion = response.version
12
+ const response = await fetch(`https://registry.npmjs.org/${pkgName}/latest`)
13
+ const reponseBody = await response.json()
14
+ const latestVersion = reponseBody.version
18
15
  const currentVersion = packageVersion ?? version
16
+
19
17
  if (latestVersion > currentVersion) {
20
18
  console.warn(
21
19
  // eslint-disable-next-line max-len
@@ -30,16 +28,22 @@ export const checkPackageUpdates = async (
30
28
  /**
31
29
  * Converts a quote to Route
32
30
  * @param step - Step returned from the quote endpoint.
31
+ * @param txHash
32
+ * @param chainId
33
33
  * @returns - The route to be executed.
34
- * @throws {ValidationError} Throws a ValidationError if the step has missing values.
34
+ * @throws {BaseError} Throws a ValidationError if the step has missing values.
35
35
  */
36
36
  export const convertQuoteToRoute = (step: LiFiStep): Route => {
37
37
  if (!step.estimate.fromAmountUSD) {
38
- throw new ValidationError("Missing 'fromAmountUSD' in step estimate.")
38
+ throw new SDKError(
39
+ new ValidationError("Missing 'fromAmountUSD' in step estimate.")
40
+ )
39
41
  }
40
42
 
41
43
  if (!step.estimate.toAmountUSD) {
42
- throw new ValidationError("Missing 'toAmountUSD' in step estimate.")
44
+ throw new SDKError(
45
+ new ValidationError("Missing 'toAmountUSD' in step estimate.")
46
+ )
43
47
  }
44
48
 
45
49
  const route: Route = {
@@ -61,9 +65,12 @@ export const convertQuoteToRoute = (step: LiFiStep): Route => {
61
65
  }
62
66
 
63
67
  export const fetchTxErrorDetails = async (txHash: string, chainId: number) => {
64
- const response = await request<TenderlyResponse>(
65
- `https://api.tenderly.co/api/v1/public-contract/${chainId}/tx/${txHash}`
66
- )
68
+ try {
69
+ const response = await fetch(
70
+ `https://api.tenderly.co/api/v1/public-contract/${chainId}/tx/${txHash}`
71
+ )
72
+ const reponseBody = await response.json()
67
73
 
68
- return response
74
+ return reponseBody
75
+ } catch (_) {}
69
76
  }
package/src/index.ts CHANGED
@@ -26,5 +26,5 @@ export * from './services/api.js'
26
26
  export * from './services/balance.js'
27
27
  export * from './services/getNameServiceAddress.js'
28
28
  export * from './types/index.js'
29
- export * from './utils/errors.js'
30
- export { LiFiError, type ErrorCode } from './utils/errors.js'
29
+ export * from './errors/index.js'
30
+ export { type ErrorCode } from './errors/index.js'