@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.
- package/package.json +3 -3
- package/src/_cjs/core/EVM/EVMStepExecutor.js +12 -11
- package/src/_cjs/core/EVM/EVMStepExecutor.js.map +1 -1
- package/src/_cjs/core/EVM/checkAllowance.js +5 -10
- package/src/_cjs/core/EVM/checkAllowance.js.map +1 -1
- package/src/_cjs/core/EVM/multisig.js +4 -3
- package/src/_cjs/core/EVM/multisig.js.map +1 -1
- package/src/_cjs/core/EVM/parseEVMErrors.js +38 -0
- package/src/_cjs/core/EVM/parseEVMErrors.js.map +1 -0
- package/src/_cjs/core/EVM/publicClient.js +8 -3
- package/src/_cjs/core/EVM/publicClient.js.map +1 -1
- package/src/_cjs/core/EVM/setAllowance.js +2 -3
- package/src/_cjs/core/EVM/setAllowance.js.map +1 -1
- package/src/_cjs/core/EVM/switchChain.js +4 -3
- package/src/_cjs/core/EVM/switchChain.js.map +1 -1
- package/src/_cjs/core/Solana/SolanaStepExecutor.js +42 -24
- package/src/_cjs/core/Solana/SolanaStepExecutor.js.map +1 -1
- package/src/_cjs/core/Solana/connection.js.map +1 -1
- package/src/_cjs/core/Solana/parseSolanaErrors.js +33 -0
- package/src/_cjs/core/Solana/parseSolanaErrors.js.map +1 -0
- package/src/_cjs/core/checkBalance.js +2 -2
- package/src/_cjs/core/checkBalance.js.map +1 -1
- package/src/_cjs/core/stepComparison.js +3 -3
- package/src/_cjs/core/stepComparison.js.map +1 -1
- package/src/_cjs/core/waitForReceivingTransaction.js +1 -1
- package/src/_cjs/core/waitForReceivingTransaction.js.map +1 -1
- package/src/_cjs/errors/SDKError.js +48 -0
- package/src/_cjs/errors/SDKError.js.map +1 -0
- package/src/_cjs/errors/baseError.js +30 -0
- package/src/_cjs/errors/baseError.js.map +1 -0
- package/src/_cjs/errors/constants.js +48 -0
- package/src/_cjs/errors/constants.js.map +1 -0
- package/src/_cjs/errors/errors.js +48 -0
- package/src/_cjs/errors/errors.js.map +1 -0
- package/src/_cjs/errors/httpError.js +101 -0
- package/src/_cjs/errors/httpError.js.map +1 -0
- package/src/_cjs/errors/index.js +11 -0
- package/src/_cjs/errors/index.js.map +1 -0
- package/src/_cjs/errors/utils/baseErrorRootCause.js +21 -0
- package/src/_cjs/errors/utils/baseErrorRootCause.js.map +1 -0
- package/src/_cjs/errors/utils/rootCause.js +12 -0
- package/src/_cjs/errors/utils/rootCause.js.map +1 -0
- package/src/_cjs/helpers.js +13 -8
- package/src/_cjs/helpers.js.map +1 -1
- package/src/_cjs/index.js +2 -4
- package/src/_cjs/index.js.map +1 -1
- package/src/_cjs/request.js +37 -34
- package/src/_cjs/request.js.map +1 -1
- package/src/_cjs/services/api.js +61 -132
- package/src/_cjs/services/api.js.map +1 -1
- package/src/_cjs/services/balance.js +1 -1
- package/src/_cjs/services/balance.js.map +1 -1
- package/src/_cjs/types/request.js +3 -0
- package/src/_cjs/types/request.js.map +1 -0
- package/src/_cjs/utils/errors.js +0 -183
- package/src/_cjs/utils/errors.js.map +1 -1
- package/src/_cjs/utils/index.js +1 -2
- package/src/_cjs/utils/index.js.map +1 -1
- package/src/_cjs/version.js +1 -1
- package/src/_cjs/version.js.map +1 -1
- package/src/_esm/core/EVM/EVMStepExecutor.js +8 -7
- package/src/_esm/core/EVM/EVMStepExecutor.js.map +1 -1
- package/src/_esm/core/EVM/checkAllowance.js +5 -10
- package/src/_esm/core/EVM/checkAllowance.js.map +1 -1
- package/src/_esm/core/EVM/multisig.js +2 -1
- package/src/_esm/core/EVM/multisig.js.map +1 -1
- package/src/_esm/core/EVM/parseEVMErrors.js +35 -0
- package/src/_esm/core/EVM/parseEVMErrors.js.map +1 -0
- package/src/_esm/core/EVM/publicClient.js +9 -4
- package/src/_esm/core/EVM/publicClient.js.map +1 -1
- package/src/_esm/core/EVM/setAllowance.js +3 -5
- package/src/_esm/core/EVM/setAllowance.js.map +1 -1
- package/src/_esm/core/EVM/switchChain.js +2 -1
- package/src/_esm/core/EVM/switchChain.js.map +1 -1
- package/src/_esm/core/Solana/SolanaStepExecutor.js +52 -25
- package/src/_esm/core/Solana/SolanaStepExecutor.js.map +1 -1
- package/src/_esm/core/Solana/connection.js +2 -3
- package/src/_esm/core/Solana/connection.js.map +1 -1
- package/src/_esm/core/Solana/parseSolanaErrors.js +29 -0
- package/src/_esm/core/Solana/parseSolanaErrors.js.map +1 -0
- package/src/_esm/core/checkBalance.js +2 -2
- package/src/_esm/core/checkBalance.js.map +1 -1
- package/src/_esm/core/stepComparison.js +3 -3
- package/src/_esm/core/stepComparison.js.map +1 -1
- package/src/_esm/core/waitForReceivingTransaction.js +1 -1
- package/src/_esm/core/waitForReceivingTransaction.js.map +1 -1
- package/src/_esm/errors/SDKError.js +47 -0
- package/src/_esm/errors/SDKError.js.map +1 -0
- package/src/_esm/errors/baseError.js +28 -0
- package/src/_esm/errors/baseError.js.map +1 -0
- package/src/_esm/errors/constants.js +45 -0
- package/src/_esm/errors/constants.js.map +1 -0
- package/src/_esm/errors/errors.js +38 -0
- package/src/_esm/errors/errors.js.map +1 -0
- package/src/_esm/errors/httpError.js +97 -0
- package/src/_esm/errors/httpError.js.map +1 -0
- package/src/_esm/errors/index.js +8 -0
- package/src/_esm/errors/index.js.map +1 -0
- package/src/_esm/errors/utils/baseErrorRootCause.js +16 -0
- package/src/_esm/errors/utils/baseErrorRootCause.js.map +1 -0
- package/src/_esm/errors/utils/rootCause.js +8 -0
- package/src/_esm/errors/utils/rootCause.js.map +1 -0
- package/src/_esm/helpers.js +16 -9
- package/src/_esm/helpers.js.map +1 -1
- package/src/_esm/index.js +2 -2
- package/src/_esm/index.js.map +1 -1
- package/src/_esm/request.js +38 -35
- package/src/_esm/request.js.map +1 -1
- package/src/_esm/services/api.js +61 -133
- package/src/_esm/services/api.js.map +1 -1
- package/src/_esm/services/balance.js +4 -4
- package/src/_esm/services/balance.js.map +1 -1
- package/src/_esm/types/request.js +2 -0
- package/src/_esm/types/request.js.map +1 -0
- package/src/_esm/utils/errors.js +1 -173
- package/src/_esm/utils/errors.js.map +1 -1
- package/src/_esm/utils/index.js +1 -2
- package/src/_esm/utils/index.js.map +1 -1
- package/src/_esm/version.js +1 -1
- package/src/_esm/version.js.map +1 -1
- package/src/_types/core/EVM/EVMStepExecutor.d.ts.map +1 -1
- package/src/_types/core/EVM/checkAllowance.d.ts.map +1 -1
- package/src/_types/core/EVM/multisig.d.ts.map +1 -1
- package/src/_types/core/EVM/parseEVMErrors.d.ts +4 -0
- package/src/_types/core/EVM/parseEVMErrors.d.ts.map +1 -0
- package/src/_types/core/EVM/publicClient.d.ts.map +1 -1
- package/src/_types/core/EVM/setAllowance.d.ts +1 -2
- package/src/_types/core/EVM/setAllowance.d.ts.map +1 -1
- package/src/_types/core/EVM/switchChain.d.ts.map +1 -1
- package/src/_types/core/EVM/types.d.ts +3 -0
- package/src/_types/core/EVM/types.d.ts.map +1 -1
- package/src/_types/core/Solana/SolanaStepExecutor.d.ts.map +1 -1
- package/src/_types/core/Solana/connection.d.ts +2 -3
- package/src/_types/core/Solana/connection.d.ts.map +1 -1
- package/src/_types/core/Solana/parseSolanaErrors.d.ts +4 -0
- package/src/_types/core/Solana/parseSolanaErrors.d.ts.map +1 -0
- package/src/_types/core/stepComparison.d.ts.map +1 -1
- package/src/_types/core/types.d.ts +3 -0
- package/src/_types/core/types.d.ts.map +1 -1
- package/src/_types/errors/SDKError.d.ts +12 -0
- package/src/_types/errors/SDKError.d.ts.map +1 -0
- package/src/_types/errors/baseError.d.ts +7 -0
- package/src/_types/errors/baseError.d.ts.map +1 -0
- package/src/_types/errors/constants.d.ts +43 -0
- package/src/_types/errors/constants.d.ts.map +1 -0
- package/src/_types/errors/errors.d.ts +24 -0
- package/src/_types/errors/errors.d.ts.map +1 -0
- package/src/_types/errors/httpError.d.ts +21 -0
- package/src/_types/errors/httpError.d.ts.map +1 -0
- package/src/_types/errors/index.d.ts +8 -0
- package/src/_types/errors/index.d.ts.map +1 -0
- package/src/_types/errors/utils/baseErrorRootCause.d.ts +4 -0
- package/src/_types/errors/utils/baseErrorRootCause.d.ts.map +1 -0
- package/src/_types/errors/utils/rootCause.d.ts +2 -0
- package/src/_types/errors/utils/rootCause.d.ts.map +1 -0
- package/src/_types/helpers.d.ts +5 -4
- package/src/_types/helpers.d.ts.map +1 -1
- package/src/_types/index.d.ts +2 -2
- package/src/_types/index.d.ts.map +1 -1
- package/src/_types/request.d.ts +1 -5
- package/src/_types/request.d.ts.map +1 -1
- package/src/_types/services/api.d.ts.map +1 -1
- package/src/_types/services/balance.d.ts +3 -3
- package/src/_types/types/request.d.ts +4 -0
- package/src/_types/types/request.d.ts.map +1 -0
- package/src/_types/utils/errors.d.ts +0 -109
- package/src/_types/utils/errors.d.ts.map +1 -1
- package/src/_types/utils/index.d.ts +1 -2
- package/src/_types/utils/index.d.ts.map +1 -1
- package/src/_types/version.d.ts +1 -1
- package/src/_types/version.d.ts.map +1 -1
- package/src/core/EVM/EVMStepExecutor.ts +14 -12
- package/src/core/EVM/checkAllowance.ts +5 -10
- package/src/core/EVM/multisig.ts +2 -1
- package/src/core/EVM/parseEVMErrors.ts +60 -0
- package/src/core/EVM/publicClient.ts +9 -4
- package/src/core/EVM/setAllowance.ts +2 -6
- package/src/core/EVM/switchChain.ts +2 -1
- package/src/core/EVM/types.ts +3 -0
- package/src/core/Solana/SolanaStepExecutor.ts +67 -34
- package/src/core/Solana/connection.ts +2 -3
- package/src/core/Solana/parseSolanaErrors.ts +45 -0
- package/src/core/checkBalance.ts +2 -2
- package/src/core/stepComparison.ts +3 -4
- package/src/core/types.ts +3 -0
- package/src/core/waitForReceivingTransaction.ts +1 -1
- package/src/errors/SDKError.ts +25 -0
- package/src/errors/baseError.ts +22 -0
- package/src/errors/constants.ts +45 -0
- package/src/errors/errors.ts +44 -0
- package/src/errors/httpError.ts +93 -0
- package/src/errors/index.ts +7 -0
- package/src/errors/utils/baseErrorRootCause.ts +18 -0
- package/src/errors/utils/rootCause.ts +7 -0
- package/src/helpers.ts +23 -16
- package/src/index.ts +2 -2
- package/src/request.ts +52 -38
- package/src/services/api.ts +109 -157
- package/src/services/balance.ts +4 -4
- package/src/types/request.ts +3 -0
- package/src/utils/errors.ts +0 -233
- package/src/utils/index.ts +1 -2
- package/src/version.ts +1 -1
- package/src/_cjs/utils/parseBackendError.js +0 -27
- package/src/_cjs/utils/parseBackendError.js.map +0 -1
- package/src/_cjs/utils/parseError.js +0 -69
- package/src/_cjs/utils/parseError.js.map +0 -1
- package/src/_esm/utils/parseBackendError.js +0 -24
- package/src/_esm/utils/parseBackendError.js.map +0 -1
- package/src/_esm/utils/parseError.js +0 -100
- package/src/_esm/utils/parseError.js.map +0 -1
- package/src/_types/utils/parseBackendError.d.ts +0 -3
- package/src/_types/utils/parseBackendError.d.ts.map +0 -1
- package/src/_types/utils/parseError.d.ts +0 -35
- package/src/_types/utils/parseError.d.ts.map +0 -1
- package/src/utils/parseBackendError.ts +0 -50
- 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
|
+
}
|
package/src/core/checkBalance.ts
CHANGED
|
@@ -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 '../
|
|
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.'
|
|
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
|
|
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
|
-
|
|
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
|
@@ -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 '../
|
|
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,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
|
+
}
|
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
|
|
14
|
-
|
|
15
|
-
|
|
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 {
|
|
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
|
|
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
|
|
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
|
-
|
|
65
|
-
|
|
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
|
-
|
|
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 './
|
|
30
|
-
export {
|
|
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 './
|
|
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
|
-
|
|
11
|
-
retries
|
|
12
|
-
|
|
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
|
|
24
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
try {
|
|
39
|
+
if (apiKey) {
|
|
40
|
+
options.headers = {
|
|
41
|
+
...options.headers,
|
|
42
|
+
'x-lifi-api-key': apiKey,
|
|
42
43
|
}
|
|
44
|
+
}
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
46
|
+
if (userId) {
|
|
47
|
+
options.headers = {
|
|
48
|
+
...options.headers,
|
|
49
|
+
'x-lifi-userid': userId,
|
|
49
50
|
}
|
|
51
|
+
}
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
53
|
+
if (widgetVersion) {
|
|
54
|
+
options.headers = {
|
|
55
|
+
...options.headers,
|
|
56
|
+
'x-lifi-widget': widgetVersion,
|
|
56
57
|
}
|
|
58
|
+
}
|
|
57
59
|
|
|
58
|
-
|
|
60
|
+
if (version) {
|
|
59
61
|
options.headers = {
|
|
60
62
|
...options.headers,
|
|
61
|
-
'x-lifi-
|
|
63
|
+
'x-lifi-sdk': version,
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
66
|
|
|
65
|
-
|
|
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
|
-
|
|
71
|
-
return data
|
|
82
|
+
return await response.json()
|
|
72
83
|
} catch (error) {
|
|
73
|
-
if (options.retries > 0 && (error as HTTPError)
|
|
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
|
-
|
|
88
|
+
|
|
89
|
+
await (error as HTTPError).buildAdditionalDetails?.()
|
|
90
|
+
|
|
91
|
+
throw new SDKError(error as HTTPError)
|
|
78
92
|
}
|
|
79
93
|
}
|