@lifi/sdk 3.0.2-beta.0 → 3.1.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 (217) hide show
  1. package/package.json +3 -3
  2. package/src/_cjs/core/EVM/EVMStepExecutor.js +12 -11
  3. package/src/_cjs/core/EVM/EVMStepExecutor.js.map +1 -1
  4. package/src/_cjs/core/EVM/checkAllowance.js +5 -10
  5. package/src/_cjs/core/EVM/checkAllowance.js.map +1 -1
  6. package/src/_cjs/core/EVM/multisig.js +4 -3
  7. package/src/_cjs/core/EVM/multisig.js.map +1 -1
  8. package/src/_cjs/core/EVM/parseEVMErrors.js +38 -0
  9. package/src/_cjs/core/EVM/parseEVMErrors.js.map +1 -0
  10. package/src/_cjs/core/EVM/publicClient.js +8 -3
  11. package/src/_cjs/core/EVM/publicClient.js.map +1 -1
  12. package/src/_cjs/core/EVM/setAllowance.js +2 -3
  13. package/src/_cjs/core/EVM/setAllowance.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 +42 -24
  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/parseSolanaErrors.js +33 -0
  20. package/src/_cjs/core/Solana/parseSolanaErrors.js.map +1 -0
  21. package/src/_cjs/core/checkBalance.js +2 -2
  22. package/src/_cjs/core/checkBalance.js.map +1 -1
  23. package/src/_cjs/core/stepComparison.js +3 -3
  24. package/src/_cjs/core/stepComparison.js.map +1 -1
  25. package/src/_cjs/core/waitForReceivingTransaction.js +1 -1
  26. package/src/_cjs/core/waitForReceivingTransaction.js.map +1 -1
  27. package/src/_cjs/errors/SDKError.js +48 -0
  28. package/src/_cjs/errors/SDKError.js.map +1 -0
  29. package/src/_cjs/errors/baseError.js +30 -0
  30. package/src/_cjs/errors/baseError.js.map +1 -0
  31. package/src/_cjs/errors/constants.js +48 -0
  32. package/src/_cjs/errors/constants.js.map +1 -0
  33. package/src/_cjs/errors/errors.js +48 -0
  34. package/src/_cjs/errors/errors.js.map +1 -0
  35. package/src/_cjs/errors/httpError.js +101 -0
  36. package/src/_cjs/errors/httpError.js.map +1 -0
  37. package/src/_cjs/errors/index.js +11 -0
  38. package/src/_cjs/errors/index.js.map +1 -0
  39. package/src/_cjs/errors/utils/baseErrorRootCause.js +21 -0
  40. package/src/_cjs/errors/utils/baseErrorRootCause.js.map +1 -0
  41. package/src/_cjs/errors/utils/rootCause.js +12 -0
  42. package/src/_cjs/errors/utils/rootCause.js.map +1 -0
  43. package/src/_cjs/helpers.js +13 -8
  44. package/src/_cjs/helpers.js.map +1 -1
  45. package/src/_cjs/index.js +2 -4
  46. package/src/_cjs/index.js.map +1 -1
  47. package/src/_cjs/request.js +37 -34
  48. package/src/_cjs/request.js.map +1 -1
  49. package/src/_cjs/services/api.js +61 -132
  50. package/src/_cjs/services/api.js.map +1 -1
  51. package/src/_cjs/services/balance.js +1 -1
  52. package/src/_cjs/services/balance.js.map +1 -1
  53. package/src/_cjs/types/request.js +3 -0
  54. package/src/_cjs/types/request.js.map +1 -0
  55. package/src/_cjs/utils/errors.js +0 -183
  56. package/src/_cjs/utils/errors.js.map +1 -1
  57. package/src/_cjs/utils/index.js +1 -2
  58. package/src/_cjs/utils/index.js.map +1 -1
  59. package/src/_cjs/version.js +1 -1
  60. package/src/_cjs/version.js.map +1 -1
  61. package/src/_esm/core/EVM/EVMStepExecutor.js +8 -7
  62. package/src/_esm/core/EVM/EVMStepExecutor.js.map +1 -1
  63. package/src/_esm/core/EVM/checkAllowance.js +5 -10
  64. package/src/_esm/core/EVM/checkAllowance.js.map +1 -1
  65. package/src/_esm/core/EVM/multisig.js +2 -1
  66. package/src/_esm/core/EVM/multisig.js.map +1 -1
  67. package/src/_esm/core/EVM/parseEVMErrors.js +35 -0
  68. package/src/_esm/core/EVM/parseEVMErrors.js.map +1 -0
  69. package/src/_esm/core/EVM/publicClient.js +9 -4
  70. package/src/_esm/core/EVM/publicClient.js.map +1 -1
  71. package/src/_esm/core/EVM/setAllowance.js +3 -5
  72. package/src/_esm/core/EVM/setAllowance.js.map +1 -1
  73. package/src/_esm/core/EVM/switchChain.js +2 -1
  74. package/src/_esm/core/EVM/switchChain.js.map +1 -1
  75. package/src/_esm/core/Solana/SolanaStepExecutor.js +52 -25
  76. package/src/_esm/core/Solana/SolanaStepExecutor.js.map +1 -1
  77. package/src/_esm/core/Solana/connection.js +2 -3
  78. package/src/_esm/core/Solana/connection.js.map +1 -1
  79. package/src/_esm/core/Solana/parseSolanaErrors.js +29 -0
  80. package/src/_esm/core/Solana/parseSolanaErrors.js.map +1 -0
  81. package/src/_esm/core/checkBalance.js +2 -2
  82. package/src/_esm/core/checkBalance.js.map +1 -1
  83. package/src/_esm/core/stepComparison.js +3 -3
  84. package/src/_esm/core/stepComparison.js.map +1 -1
  85. package/src/_esm/core/waitForReceivingTransaction.js +1 -1
  86. package/src/_esm/core/waitForReceivingTransaction.js.map +1 -1
  87. package/src/_esm/errors/SDKError.js +47 -0
  88. package/src/_esm/errors/SDKError.js.map +1 -0
  89. package/src/_esm/errors/baseError.js +28 -0
  90. package/src/_esm/errors/baseError.js.map +1 -0
  91. package/src/_esm/errors/constants.js +45 -0
  92. package/src/_esm/errors/constants.js.map +1 -0
  93. package/src/_esm/errors/errors.js +38 -0
  94. package/src/_esm/errors/errors.js.map +1 -0
  95. package/src/_esm/errors/httpError.js +97 -0
  96. package/src/_esm/errors/httpError.js.map +1 -0
  97. package/src/_esm/errors/index.js +8 -0
  98. package/src/_esm/errors/index.js.map +1 -0
  99. package/src/_esm/errors/utils/baseErrorRootCause.js +16 -0
  100. package/src/_esm/errors/utils/baseErrorRootCause.js.map +1 -0
  101. package/src/_esm/errors/utils/rootCause.js +8 -0
  102. package/src/_esm/errors/utils/rootCause.js.map +1 -0
  103. package/src/_esm/helpers.js +16 -9
  104. package/src/_esm/helpers.js.map +1 -1
  105. package/src/_esm/index.js +2 -2
  106. package/src/_esm/index.js.map +1 -1
  107. package/src/_esm/request.js +38 -35
  108. package/src/_esm/request.js.map +1 -1
  109. package/src/_esm/services/api.js +61 -133
  110. package/src/_esm/services/api.js.map +1 -1
  111. package/src/_esm/services/balance.js +4 -4
  112. package/src/_esm/services/balance.js.map +1 -1
  113. package/src/_esm/types/request.js +2 -0
  114. package/src/_esm/types/request.js.map +1 -0
  115. package/src/_esm/utils/errors.js +1 -173
  116. package/src/_esm/utils/errors.js.map +1 -1
  117. package/src/_esm/utils/index.js +1 -2
  118. package/src/_esm/utils/index.js.map +1 -1
  119. package/src/_esm/version.js +1 -1
  120. package/src/_esm/version.js.map +1 -1
  121. package/src/_types/core/EVM/EVMStepExecutor.d.ts.map +1 -1
  122. package/src/_types/core/EVM/checkAllowance.d.ts.map +1 -1
  123. package/src/_types/core/EVM/multisig.d.ts.map +1 -1
  124. package/src/_types/core/EVM/parseEVMErrors.d.ts +4 -0
  125. package/src/_types/core/EVM/parseEVMErrors.d.ts.map +1 -0
  126. package/src/_types/core/EVM/publicClient.d.ts.map +1 -1
  127. package/src/_types/core/EVM/setAllowance.d.ts +1 -2
  128. package/src/_types/core/EVM/setAllowance.d.ts.map +1 -1
  129. package/src/_types/core/EVM/switchChain.d.ts.map +1 -1
  130. package/src/_types/core/EVM/types.d.ts +3 -0
  131. package/src/_types/core/EVM/types.d.ts.map +1 -1
  132. package/src/_types/core/Solana/SolanaStepExecutor.d.ts.map +1 -1
  133. package/src/_types/core/Solana/connection.d.ts +2 -3
  134. package/src/_types/core/Solana/connection.d.ts.map +1 -1
  135. package/src/_types/core/Solana/parseSolanaErrors.d.ts +4 -0
  136. package/src/_types/core/Solana/parseSolanaErrors.d.ts.map +1 -0
  137. package/src/_types/core/stepComparison.d.ts.map +1 -1
  138. package/src/_types/core/types.d.ts +3 -0
  139. package/src/_types/core/types.d.ts.map +1 -1
  140. package/src/_types/errors/SDKError.d.ts +12 -0
  141. package/src/_types/errors/SDKError.d.ts.map +1 -0
  142. package/src/_types/errors/baseError.d.ts +7 -0
  143. package/src/_types/errors/baseError.d.ts.map +1 -0
  144. package/src/_types/errors/constants.d.ts +43 -0
  145. package/src/_types/errors/constants.d.ts.map +1 -0
  146. package/src/_types/errors/errors.d.ts +24 -0
  147. package/src/_types/errors/errors.d.ts.map +1 -0
  148. package/src/_types/errors/httpError.d.ts +21 -0
  149. package/src/_types/errors/httpError.d.ts.map +1 -0
  150. package/src/_types/errors/index.d.ts +8 -0
  151. package/src/_types/errors/index.d.ts.map +1 -0
  152. package/src/_types/errors/utils/baseErrorRootCause.d.ts +4 -0
  153. package/src/_types/errors/utils/baseErrorRootCause.d.ts.map +1 -0
  154. package/src/_types/errors/utils/rootCause.d.ts +2 -0
  155. package/src/_types/errors/utils/rootCause.d.ts.map +1 -0
  156. package/src/_types/helpers.d.ts +5 -4
  157. package/src/_types/helpers.d.ts.map +1 -1
  158. package/src/_types/index.d.ts +2 -2
  159. package/src/_types/index.d.ts.map +1 -1
  160. package/src/_types/request.d.ts +1 -5
  161. package/src/_types/request.d.ts.map +1 -1
  162. package/src/_types/services/api.d.ts.map +1 -1
  163. package/src/_types/services/balance.d.ts +3 -3
  164. package/src/_types/types/request.d.ts +4 -0
  165. package/src/_types/types/request.d.ts.map +1 -0
  166. package/src/_types/utils/errors.d.ts +0 -109
  167. package/src/_types/utils/errors.d.ts.map +1 -1
  168. package/src/_types/utils/index.d.ts +1 -2
  169. package/src/_types/utils/index.d.ts.map +1 -1
  170. package/src/_types/version.d.ts +1 -1
  171. package/src/_types/version.d.ts.map +1 -1
  172. package/src/core/EVM/EVMStepExecutor.ts +14 -12
  173. package/src/core/EVM/checkAllowance.ts +5 -10
  174. package/src/core/EVM/multisig.ts +2 -1
  175. package/src/core/EVM/parseEVMErrors.ts +60 -0
  176. package/src/core/EVM/publicClient.ts +9 -4
  177. package/src/core/EVM/setAllowance.ts +2 -6
  178. package/src/core/EVM/switchChain.ts +2 -1
  179. package/src/core/EVM/types.ts +3 -0
  180. package/src/core/Solana/SolanaStepExecutor.ts +67 -34
  181. package/src/core/Solana/connection.ts +2 -3
  182. package/src/core/Solana/parseSolanaErrors.ts +45 -0
  183. package/src/core/checkBalance.ts +2 -2
  184. package/src/core/stepComparison.ts +3 -4
  185. package/src/core/types.ts +3 -0
  186. package/src/core/waitForReceivingTransaction.ts +1 -1
  187. package/src/errors/SDKError.ts +25 -0
  188. package/src/errors/baseError.ts +22 -0
  189. package/src/errors/constants.ts +45 -0
  190. package/src/errors/errors.ts +44 -0
  191. package/src/errors/httpError.ts +93 -0
  192. package/src/errors/index.ts +7 -0
  193. package/src/errors/utils/baseErrorRootCause.ts +18 -0
  194. package/src/errors/utils/rootCause.ts +7 -0
  195. package/src/helpers.ts +23 -16
  196. package/src/index.ts +2 -2
  197. package/src/request.ts +52 -38
  198. package/src/services/api.ts +109 -157
  199. package/src/services/balance.ts +4 -4
  200. package/src/types/request.ts +3 -0
  201. package/src/utils/errors.ts +0 -233
  202. package/src/utils/index.ts +1 -2
  203. package/src/version.ts +1 -1
  204. package/src/_cjs/utils/parseBackendError.js +0 -27
  205. package/src/_cjs/utils/parseBackendError.js.map +0 -1
  206. package/src/_cjs/utils/parseError.js +0 -69
  207. package/src/_cjs/utils/parseError.js.map +0 -1
  208. package/src/_esm/utils/parseBackendError.js +0 -24
  209. package/src/_esm/utils/parseBackendError.js.map +0 -1
  210. package/src/_esm/utils/parseError.js +0 -100
  211. package/src/_esm/utils/parseError.js.map +0 -1
  212. package/src/_types/utils/parseBackendError.d.ts +0 -3
  213. package/src/_types/utils/parseBackendError.d.ts.map +0 -1
  214. package/src/_types/utils/parseError.d.ts +0 -35
  215. package/src/_types/utils/parseError.d.ts.map +0 -1
  216. package/src/utils/parseBackendError.ts +0 -50
  217. package/src/utils/parseError.ts +0 -210
@@ -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
+ }
@@ -1,7 +1,7 @@
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
5
  import { sleep } from './utils.js'
6
6
 
7
7
  export const checkBalance = async (
@@ -40,7 +40,7 @@ export const checkBalance = async (
40
40
  `start a new one with a maximum of ${current} ${token.symbol}.`
41
41
  }
42
42
 
43
- throw new BalanceError('The balance is too low.', errorMessage)
43
+ throw new BalanceError('The balance is too low.')
44
44
  }
45
45
  }
46
46
  }
@@ -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/types.ts CHANGED
@@ -114,5 +114,8 @@ export interface ExecutionOptions {
114
114
  updateRouteHook?: UpdateRouteHook
115
115
  updateTransactionRequestHook?: TransactionRequestUpdateHook
116
116
  executeInBackground?: boolean
117
+ /**
118
+ * @deprecated
119
+ */
117
120
  infiniteApproval?: boolean
118
121
  }
@@ -5,7 +5,7 @@ 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
11
  import { getSubstatusMessage } from './processMessages.js'
@@ -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'
package/src/request.ts CHANGED
@@ -1,16 +1,21 @@
1
1
  import { config } from './config.js'
2
- import { HTTPError } from './utils/errors.js'
2
+ import { HTTPError } from './errors/httpError.js'
3
3
  import { wait } from './utils/utils.js'
4
+ import { ValidationError } from './errors/errors.js'
5
+ import { SDKError } from './errors/SDKError.js'
6
+ import type { ExtendedRequestInit } from './types/request.js'
4
7
  import { version } from './version.js'
5
8
 
6
9
  export const requestSettings = {
7
10
  retries: 1,
8
11
  }
9
12
 
10
- interface ExtendedRequestInit extends RequestInit {
11
- retries?: number
12
- skipTrackingHeaders?: boolean
13
- }
13
+ const stripExtendRequestInitProperties = ({
14
+ retries,
15
+ ...rest
16
+ }: ExtendedRequestInit): RequestInit => ({
17
+ ...rest,
18
+ })
14
19
 
15
20
  export const request = async <T = Response>(
16
21
  url: RequestInfo | URL,
@@ -19,61 +24,70 @@ export const request = async <T = Response>(
19
24
  }
20
25
  ): Promise<T> => {
21
26
  const { userId, integrator, widgetVersion, apiKey } = config.get()
27
+
22
28
  if (!integrator) {
23
- throw new Error(
24
- 'Integrator not found. Please see documentation https://docs.li.fi/integrate-li.fi-js-sdk/set-up-the-sdk'
29
+ throw new SDKError(
30
+ new ValidationError(
31
+ 'You need to provide the Integrator property. Please see documentation https://docs.li.fi/integrate-li.fi-js-sdk/set-up-the-sdk'
32
+ )
25
33
  )
26
34
  }
35
+
27
36
  options.retries = options.retries ?? requestSettings.retries
28
- try {
29
- if (!options.skipTrackingHeaders) {
30
- if (apiKey) {
31
- options.headers = {
32
- ...options.headers,
33
- 'x-lifi-api-key': apiKey,
34
- }
35
- }
36
37
 
37
- if (userId) {
38
- options.headers = {
39
- ...options.headers,
40
- 'x-lifi-userid': userId,
41
- }
38
+ try {
39
+ if (apiKey) {
40
+ options.headers = {
41
+ ...options.headers,
42
+ 'x-lifi-api-key': apiKey,
42
43
  }
44
+ }
43
45
 
44
- if (widgetVersion) {
45
- options.headers = {
46
- ...options.headers,
47
- 'x-lifi-widget': widgetVersion,
48
- }
46
+ if (userId) {
47
+ options.headers = {
48
+ ...options.headers,
49
+ 'x-lifi-userid': userId,
49
50
  }
51
+ }
50
52
 
51
- if (version) {
52
- options.headers = {
53
- ...options.headers,
54
- 'x-lifi-sdk': version,
55
- }
53
+ if (widgetVersion) {
54
+ options.headers = {
55
+ ...options.headers,
56
+ 'x-lifi-widget': widgetVersion,
56
57
  }
58
+ }
57
59
 
58
- // integrator is mandatory during SDK initialization
60
+ if (version) {
59
61
  options.headers = {
60
62
  ...options.headers,
61
- 'x-lifi-integrator': integrator,
63
+ 'x-lifi-sdk': version,
62
64
  }
63
65
  }
64
66
 
65
- const response: Response = await fetch(url, options)
67
+ // integrator is mandatory during SDK initialization
68
+ options.headers = {
69
+ ...options.headers,
70
+ 'x-lifi-integrator': integrator,
71
+ }
72
+
73
+ const response: Response = await fetch(
74
+ url,
75
+ stripExtendRequestInitProperties(options)
76
+ )
77
+
66
78
  if (!response.ok) {
67
- throw new HTTPError(response)
79
+ throw new HTTPError(response, url, options)
68
80
  }
69
81
 
70
- const data: T = await response.json()
71
- return data
82
+ return await response.json()
72
83
  } catch (error) {
73
- if (options.retries > 0 && (error as HTTPError)?.status === 500) {
84
+ if (options.retries > 0 && (error as HTTPError).status === 500) {
74
85
  await wait(500)
75
86
  return request<T>(url, { ...options, retries: options.retries - 1 })
76
87
  }
77
- throw error
88
+
89
+ await (error as HTTPError).buildAdditionalDetails?.()
90
+
91
+ throw new SDKError(error as HTTPError)
78
92
  }
79
93
  }