@lifi/sdk 4.0.0-alpha.1 → 4.0.0-alpha.2
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/LICENSE +201 -165
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +16 -1
- package/src/version.ts +1 -1
- package/CHANGELOG.md +0 -1272
- package/package.json.tmp +0 -103
- package/src/actions/actions.unit.handlers.ts +0 -78
- package/src/actions/getChains.unit.spec.ts +0 -19
- package/src/actions/getConnections.unit.spec.ts +0 -45
- package/src/actions/getContractCallsQuote.unit.spec.ts +0 -323
- package/src/actions/getGasRecommendation.unit.spec.ts +0 -40
- package/src/actions/getNameServiceAddress.unit.spec.ts +0 -169
- package/src/actions/getQuote.int.spec.ts +0 -18
- package/src/actions/getQuote.unit.spec.ts +0 -154
- package/src/actions/getRelayedTransactionStatus.unit.spec.ts +0 -243
- package/src/actions/getRelayerQuote.unit.spec.ts +0 -220
- package/src/actions/getRoutes.unit.spec.ts +0 -112
- package/src/actions/getStatus.unit.spec.ts +0 -53
- package/src/actions/getStepTransaction.unit.spec.ts +0 -140
- package/src/actions/getToken.unit.spec.ts +0 -45
- package/src/actions/getTokenBalance.unit.spec.ts +0 -61
- package/src/actions/getTokenBalances.unit.spec.ts +0 -68
- package/src/actions/getTokenBalancesByChain.unit.spec.ts +0 -108
- package/src/actions/getTokens.unit.spec.ts +0 -16
- package/src/actions/getTools.unit.spec.ts +0 -20
- package/src/actions/getTransactionHistory.unit.spec.ts +0 -36
- package/src/actions/getWalletBalances.unit.spec.ts +0 -90
- package/src/actions/relayTransaction.unit.spec.ts +0 -229
- package/src/client/createClient.unit.spec.ts +0 -274
- package/src/client/getClientStorage.unit.spec.ts +0 -382
- package/src/core/StatusManager.unit.spec.ts +0 -298
- package/src/core/execution.unit.handlers.ts +0 -32
- package/src/core/execution.unit.mock.ts +0 -252
- package/src/core/execution.unit.spec.ts +0 -86
- package/src/core/stepComparison.unit.spec.ts +0 -89
- package/src/errors/SDKError.unit.spec.ts +0 -160
- package/src/errors/baseError.unit.spec.ts +0 -22
- package/src/errors/httpError.unit.spec.ts +0 -125
- package/src/errors/utils/baseErrorRootCause.unit.spec.ts +0 -89
- package/src/errors/utils/rootCause.unit.spec.ts +0 -36
- package/src/utils/checkPackageUpdates.unit.spec.ts +0 -71
- package/src/utils/convertQuoteToRoute.unit.spec.ts +0 -56
- package/src/utils/fetchTxErrorDetails.unit.spec.ts +0 -42
- package/src/utils/getTransactionMessage.unit.spec.ts +0 -38
- package/src/utils/isRoutesRequest.unit.spec.ts +0 -46
- package/src/utils/isStep.unit.spec.ts +0 -55
- package/src/utils/isToken.unit.spec.ts +0 -49
- package/src/utils/request.unit.spec.ts +0 -159
- package/src/utils/sleep.unit.spec.ts +0 -17
- package/src/utils/waitForResult.unit.spec.ts +0 -75
- package/src/utils/withDedupe.unit.spec.ts +0 -26
- package/tsconfig.json +0 -18
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest'
|
|
2
|
-
import { TransactionError } from '../errors/errors.js'
|
|
3
|
-
import type { LiFiStep, StatusManager } from '../index.js'
|
|
4
|
-
import { stepComparison } from './stepComparison.js'
|
|
5
|
-
|
|
6
|
-
describe('stepComparison', () => {
|
|
7
|
-
const mockStatusManager = {
|
|
8
|
-
updateStepInRoute: vi.fn((step) => step),
|
|
9
|
-
} as unknown as StatusManager
|
|
10
|
-
|
|
11
|
-
const oldStep: LiFiStep = {
|
|
12
|
-
id: 'test',
|
|
13
|
-
type: 'swap',
|
|
14
|
-
tool: 'test',
|
|
15
|
-
action: {
|
|
16
|
-
fromChainId: 1,
|
|
17
|
-
fromAmount: '1000',
|
|
18
|
-
fromToken: { address: '0x1', decimals: 18, chainId: 1 },
|
|
19
|
-
toChainId: 1,
|
|
20
|
-
toToken: { address: '0x2', decimals: 18, chainId: 1 },
|
|
21
|
-
slippage: 0.003,
|
|
22
|
-
},
|
|
23
|
-
estimate: {
|
|
24
|
-
toAmount: '2000',
|
|
25
|
-
toAmountMin: '1940',
|
|
26
|
-
},
|
|
27
|
-
} as any
|
|
28
|
-
|
|
29
|
-
const newStep: LiFiStep = {
|
|
30
|
-
...oldStep,
|
|
31
|
-
estimate: {
|
|
32
|
-
toAmount: '1950',
|
|
33
|
-
toAmountMin: '1940',
|
|
34
|
-
},
|
|
35
|
-
} as any
|
|
36
|
-
|
|
37
|
-
it('should return updated step if within slippage threshold', async () => {
|
|
38
|
-
const result = await stepComparison(
|
|
39
|
-
mockStatusManager,
|
|
40
|
-
oldStep,
|
|
41
|
-
newStep,
|
|
42
|
-
false
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
expect(result).toBeDefined()
|
|
46
|
-
expect(mockStatusManager.updateStepInRoute).toHaveBeenCalled()
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it('should throw error when rate changed and user declined', async () => {
|
|
50
|
-
const farNewStep = {
|
|
51
|
-
...oldStep,
|
|
52
|
-
estimate: {
|
|
53
|
-
toAmount: '100',
|
|
54
|
-
toAmountMin: '50',
|
|
55
|
-
},
|
|
56
|
-
} as any
|
|
57
|
-
|
|
58
|
-
await expect(
|
|
59
|
-
stepComparison(mockStatusManager, oldStep, farNewStep, false)
|
|
60
|
-
).rejects.toThrow(TransactionError)
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
it('should call acceptExchangeRateUpdateHook when user interaction allowed', async () => {
|
|
64
|
-
const acceptHook = vi.fn().mockResolvedValue(true)
|
|
65
|
-
|
|
66
|
-
const farNewStep = {
|
|
67
|
-
...oldStep,
|
|
68
|
-
estimate: {
|
|
69
|
-
toAmount: '100',
|
|
70
|
-
toAmountMin: '50',
|
|
71
|
-
},
|
|
72
|
-
} as any
|
|
73
|
-
|
|
74
|
-
const executionOptions = {
|
|
75
|
-
acceptExchangeRateUpdateHook: acceptHook,
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const result = await stepComparison(
|
|
79
|
-
mockStatusManager,
|
|
80
|
-
oldStep,
|
|
81
|
-
farNewStep,
|
|
82
|
-
true,
|
|
83
|
-
executionOptions
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
expect(acceptHook).toHaveBeenCalled()
|
|
87
|
-
expect(result).toBeDefined()
|
|
88
|
-
})
|
|
89
|
-
})
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { version } from '../version.js'
|
|
3
|
-
import { BaseError } from './baseError.js'
|
|
4
|
-
import { ErrorName, LiFiErrorCode } from './constants.js'
|
|
5
|
-
import { HTTPError } from './httpError.js'
|
|
6
|
-
import { SDKError } from './SDKError.js'
|
|
7
|
-
|
|
8
|
-
const url = 'http://some.where'
|
|
9
|
-
const options = { method: 'POST' }
|
|
10
|
-
const responseBody = { message: 'Oops' }
|
|
11
|
-
|
|
12
|
-
describe('SDKError', () => {
|
|
13
|
-
describe('when the cause is a http error', () => {
|
|
14
|
-
it('should present the causing errors stack trace for http errors', async () => {
|
|
15
|
-
expect.assertions(1)
|
|
16
|
-
|
|
17
|
-
const testFunction = async () => {
|
|
18
|
-
try {
|
|
19
|
-
const mockResponse = {
|
|
20
|
-
status: 400,
|
|
21
|
-
statusText: 'Bad Request',
|
|
22
|
-
json: () => Promise.resolve(responseBody),
|
|
23
|
-
} as Response
|
|
24
|
-
|
|
25
|
-
const httpError = new HTTPError(mockResponse, url, options)
|
|
26
|
-
|
|
27
|
-
await httpError.buildAdditionalDetails()
|
|
28
|
-
|
|
29
|
-
throw httpError
|
|
30
|
-
} catch (e: any) {
|
|
31
|
-
throw new SDKError(e)
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
await testFunction()
|
|
37
|
-
} catch (e: any) {
|
|
38
|
-
expect((e as SDKError).stack).toBe((e as SDKError).cause.stack)
|
|
39
|
-
}
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('should feature the causing http error message as part of its own message', async () => {
|
|
43
|
-
const mockResponse = {
|
|
44
|
-
status: 400,
|
|
45
|
-
statusText: 'Bad Request',
|
|
46
|
-
json: () => Promise.resolve(responseBody),
|
|
47
|
-
} as Response
|
|
48
|
-
|
|
49
|
-
const httpError = new HTTPError(mockResponse, url, options)
|
|
50
|
-
|
|
51
|
-
await httpError.buildAdditionalDetails()
|
|
52
|
-
|
|
53
|
-
const testFunction = () => {
|
|
54
|
-
throw new SDKError(httpError)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
expect(() => testFunction()).toThrowError(
|
|
58
|
-
`[HTTPError] [ValidationError] Request failed with status code 400 Bad Request. Oops\nLI.FI SDK version: ${version}`
|
|
59
|
-
)
|
|
60
|
-
})
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
describe('when the cause is a base error', () => {
|
|
64
|
-
it('should present the causing errors stack trace for base errors', () => {
|
|
65
|
-
expect.assertions(1)
|
|
66
|
-
|
|
67
|
-
const testFunction = () => {
|
|
68
|
-
try {
|
|
69
|
-
const baseError = new BaseError(
|
|
70
|
-
ErrorName.ValidationError,
|
|
71
|
-
LiFiErrorCode.ValidationError,
|
|
72
|
-
'problem validating'
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
throw baseError
|
|
76
|
-
} catch (e: any) {
|
|
77
|
-
throw new SDKError(e)
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
try {
|
|
82
|
-
testFunction()
|
|
83
|
-
} catch (e: any) {
|
|
84
|
-
expect((e as SDKError).stack).toBe((e as SDKError).cause.stack)
|
|
85
|
-
}
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it('should present the causing errors stack trace for base errors own causing error', () => {
|
|
89
|
-
expect.assertions(1)
|
|
90
|
-
|
|
91
|
-
const causingError = () => {
|
|
92
|
-
try {
|
|
93
|
-
throw new Error('this was the root cause')
|
|
94
|
-
} catch (e: any) {
|
|
95
|
-
throw new BaseError(
|
|
96
|
-
ErrorName.ValidationError,
|
|
97
|
-
LiFiErrorCode.ValidationError,
|
|
98
|
-
'problem validating',
|
|
99
|
-
e
|
|
100
|
-
)
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const testFunction = () => {
|
|
105
|
-
try {
|
|
106
|
-
causingError()
|
|
107
|
-
} catch (e: any) {
|
|
108
|
-
throw new SDKError(e)
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
try {
|
|
113
|
-
testFunction()
|
|
114
|
-
} catch (e: any) {
|
|
115
|
-
expect((e as SDKError).stack).toBe(
|
|
116
|
-
((e as SDKError).cause as SDKError).cause.stack
|
|
117
|
-
)
|
|
118
|
-
}
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
it('should feature the causing base error message as part of its own message', () => {
|
|
122
|
-
const testFunction = () => {
|
|
123
|
-
throw new SDKError(
|
|
124
|
-
new BaseError(
|
|
125
|
-
ErrorName.UnknownError,
|
|
126
|
-
LiFiErrorCode.InternalError,
|
|
127
|
-
'There was an error'
|
|
128
|
-
)
|
|
129
|
-
)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
expect(() => testFunction()).toThrowError(
|
|
133
|
-
`[UnknownError] There was an error\nLI.FI SDK version: ${version}`
|
|
134
|
-
)
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
it('should use a fail back error message if one is not defined on the base error', () => {
|
|
138
|
-
const testFunction = () => {
|
|
139
|
-
throw new SDKError(
|
|
140
|
-
new BaseError(ErrorName.BalanceError, LiFiErrorCode.BalanceError, '')
|
|
141
|
-
)
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
expect(() => testFunction()).toThrowError(
|
|
145
|
-
`Unknown error occurred\nLI.FI SDK version: ${version}`
|
|
146
|
-
)
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
it('should present the passed base error as the cause', () => {
|
|
150
|
-
const baseError = new BaseError(
|
|
151
|
-
ErrorName.UnknownError,
|
|
152
|
-
LiFiErrorCode.InternalError,
|
|
153
|
-
'There was an error'
|
|
154
|
-
)
|
|
155
|
-
const sdkError = new SDKError(baseError)
|
|
156
|
-
|
|
157
|
-
expect(sdkError.cause).toBe(baseError)
|
|
158
|
-
})
|
|
159
|
-
})
|
|
160
|
-
})
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { BaseError } from './baseError.js'
|
|
3
|
-
import { ErrorName, LiFiErrorCode } from './constants.js'
|
|
4
|
-
|
|
5
|
-
describe('baseError', () => {
|
|
6
|
-
it('should set the stack to the same as the deep rooted cause', () => {
|
|
7
|
-
const rootError = new Error()
|
|
8
|
-
rootError.stack = 'root stack trace'
|
|
9
|
-
|
|
10
|
-
const intermediateError = new Error()
|
|
11
|
-
intermediateError.cause = rootError
|
|
12
|
-
|
|
13
|
-
const errorChain = new BaseError(
|
|
14
|
-
ErrorName.UnknownError,
|
|
15
|
-
LiFiErrorCode.InternalError,
|
|
16
|
-
'There was an error',
|
|
17
|
-
intermediateError
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
expect(errorChain.stack).toBe(rootError.stack)
|
|
21
|
-
})
|
|
22
|
-
})
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { ErrorName, LiFiErrorCode } from './constants.js'
|
|
3
|
-
import { HTTPError } from './httpError.js'
|
|
4
|
-
|
|
5
|
-
const url = 'http://some.where'
|
|
6
|
-
const options = { method: 'POST' }
|
|
7
|
-
const responseBody = { message: 'Oops' }
|
|
8
|
-
|
|
9
|
-
describe('HTTPError', () => {
|
|
10
|
-
it.each([
|
|
11
|
-
[
|
|
12
|
-
'when status code is 400',
|
|
13
|
-
options,
|
|
14
|
-
400,
|
|
15
|
-
'Bad Request',
|
|
16
|
-
{
|
|
17
|
-
initialMessage: 'Request failed with status code 400 Bad Request',
|
|
18
|
-
type: ErrorName.ValidationError,
|
|
19
|
-
code: LiFiErrorCode.ValidationError,
|
|
20
|
-
jsonFunc: () => Promise.resolve(responseBody),
|
|
21
|
-
responseBody,
|
|
22
|
-
builtMessage:
|
|
23
|
-
'[ValidationError] Request failed with status code 400 Bad Request. Oops',
|
|
24
|
-
},
|
|
25
|
-
],
|
|
26
|
-
[
|
|
27
|
-
'when status code is 404',
|
|
28
|
-
options,
|
|
29
|
-
404,
|
|
30
|
-
'Not Found',
|
|
31
|
-
{
|
|
32
|
-
initialMessage: 'Request failed with status code 404 Not Found',
|
|
33
|
-
type: ErrorName.NotFoundError,
|
|
34
|
-
code: LiFiErrorCode.NotFound,
|
|
35
|
-
jsonFunc: () => Promise.resolve(responseBody),
|
|
36
|
-
responseBody,
|
|
37
|
-
builtMessage:
|
|
38
|
-
'[NotFoundError] Request failed with status code 404 Not Found. Oops',
|
|
39
|
-
},
|
|
40
|
-
],
|
|
41
|
-
[
|
|
42
|
-
'when status code is 409',
|
|
43
|
-
options,
|
|
44
|
-
409,
|
|
45
|
-
'Conflict',
|
|
46
|
-
{
|
|
47
|
-
initialMessage:
|
|
48
|
-
'Request failed with status code 409 Conflict\nThe slippage is larger than the defined threshold. Please request a new route to get a fresh quote.',
|
|
49
|
-
type: ErrorName.SlippageError,
|
|
50
|
-
code: LiFiErrorCode.SlippageError,
|
|
51
|
-
jsonFunc: () => Promise.resolve(responseBody),
|
|
52
|
-
responseBody,
|
|
53
|
-
builtMessage:
|
|
54
|
-
'[SlippageError] Request failed with status code 409 Conflict\nThe slippage is larger than the defined threshold. Please request a new route to get a fresh quote. Oops',
|
|
55
|
-
},
|
|
56
|
-
],
|
|
57
|
-
[
|
|
58
|
-
'when status code is 500',
|
|
59
|
-
options,
|
|
60
|
-
500,
|
|
61
|
-
'Internal Server Error',
|
|
62
|
-
{
|
|
63
|
-
initialMessage:
|
|
64
|
-
'Request failed with status code 500 Internal Server Error',
|
|
65
|
-
type: ErrorName.ServerError,
|
|
66
|
-
code: LiFiErrorCode.InternalError,
|
|
67
|
-
jsonFunc: () => Promise.resolve(responseBody),
|
|
68
|
-
responseBody,
|
|
69
|
-
builtMessage:
|
|
70
|
-
'[ServerError] Request failed with status code 500 Internal Server Error. Oops',
|
|
71
|
-
},
|
|
72
|
-
],
|
|
73
|
-
[
|
|
74
|
-
'when status code is undefined',
|
|
75
|
-
options,
|
|
76
|
-
undefined,
|
|
77
|
-
'',
|
|
78
|
-
{
|
|
79
|
-
initialMessage: 'Request failed with an unknown error',
|
|
80
|
-
type: ErrorName.ServerError,
|
|
81
|
-
code: LiFiErrorCode.InternalError,
|
|
82
|
-
jsonFunc: () => Promise.resolve(responseBody),
|
|
83
|
-
responseBody,
|
|
84
|
-
builtMessage:
|
|
85
|
-
'[ServerError] Request failed with an unknown error. Oops',
|
|
86
|
-
},
|
|
87
|
-
],
|
|
88
|
-
[
|
|
89
|
-
'when there is a problem processing the body',
|
|
90
|
-
options,
|
|
91
|
-
400,
|
|
92
|
-
'Bad Request',
|
|
93
|
-
{
|
|
94
|
-
initialMessage: 'Request failed with status code 400 Bad Request',
|
|
95
|
-
type: ErrorName.ValidationError,
|
|
96
|
-
code: LiFiErrorCode.ValidationError,
|
|
97
|
-
jsonFunc: () => Promise.reject(new Error('fail')),
|
|
98
|
-
responseBody: undefined,
|
|
99
|
-
builtMessage:
|
|
100
|
-
'[ValidationError] Request failed with status code 400 Bad Request',
|
|
101
|
-
},
|
|
102
|
-
],
|
|
103
|
-
])('should present correctly %s', async (_, requestOptions, statusCode, statusText, expected) => {
|
|
104
|
-
const mockResponse = {
|
|
105
|
-
status: statusCode,
|
|
106
|
-
statusText,
|
|
107
|
-
json: expected.jsonFunc,
|
|
108
|
-
} as Response
|
|
109
|
-
|
|
110
|
-
const error = new HTTPError(mockResponse, url, requestOptions)
|
|
111
|
-
|
|
112
|
-
expect(error.status).toEqual(statusCode)
|
|
113
|
-
expect(error.message).toEqual(expected.initialMessage)
|
|
114
|
-
expect(error.url).toEqual(url)
|
|
115
|
-
expect(error.fetchOptions).toEqual(requestOptions)
|
|
116
|
-
|
|
117
|
-
expect(error.type).toEqual(expected.type)
|
|
118
|
-
expect(error.code).toEqual(expected.code)
|
|
119
|
-
|
|
120
|
-
await error.buildAdditionalDetails()
|
|
121
|
-
|
|
122
|
-
expect(error.responseBody).toEqual(expected.responseBody)
|
|
123
|
-
expect(error.message).toEqual(expected.builtMessage)
|
|
124
|
-
})
|
|
125
|
-
})
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { BaseError } from '../baseError.js'
|
|
3
|
-
import { ErrorName, LiFiErrorCode } from '../constants.js'
|
|
4
|
-
import { HTTPError } from '../httpError.js'
|
|
5
|
-
import { SDKError } from '../SDKError.js'
|
|
6
|
-
import {
|
|
7
|
-
getRootCauseBaseError,
|
|
8
|
-
getRootCauseBaseErrorMessage,
|
|
9
|
-
} from './baseErrorRootCause.js'
|
|
10
|
-
|
|
11
|
-
const getErrorChain = () => {
|
|
12
|
-
const NonLiFiErrorChain = new Error('non lifi error')
|
|
13
|
-
NonLiFiErrorChain.cause = new Error('root cause')
|
|
14
|
-
return new SDKError(
|
|
15
|
-
new BaseError(
|
|
16
|
-
ErrorName.ValidationError,
|
|
17
|
-
LiFiErrorCode.ValidationError,
|
|
18
|
-
'something happened',
|
|
19
|
-
NonLiFiErrorChain
|
|
20
|
-
)
|
|
21
|
-
)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
describe('getRootCauseBaseError', () => {
|
|
25
|
-
it('should return the top level error when there is no root cause', () => {
|
|
26
|
-
const error = new Error('top level')
|
|
27
|
-
|
|
28
|
-
expect(getRootCauseBaseError(error).message).toEqual('top level')
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('should return the lowest BaseError in the cause chain', () => {
|
|
32
|
-
const errorChain = getErrorChain()
|
|
33
|
-
|
|
34
|
-
expect(getRootCauseBaseError(errorChain).message).toEqual(
|
|
35
|
-
'something happened'
|
|
36
|
-
)
|
|
37
|
-
})
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
describe('getRootCauseBaseErrorMessage', () => {
|
|
41
|
-
describe('when root cause is HTTP Error', () => {
|
|
42
|
-
it('should return the HTTP response message if present', async () => {
|
|
43
|
-
const mockResponse = {
|
|
44
|
-
status: 400,
|
|
45
|
-
statusText: 'Bad Request',
|
|
46
|
-
json: () =>
|
|
47
|
-
Promise.resolve({ message: 'something went wrong on the server' }),
|
|
48
|
-
} as Response
|
|
49
|
-
|
|
50
|
-
const httpError = new HTTPError(mockResponse, 'http://some.where', {})
|
|
51
|
-
|
|
52
|
-
await httpError.buildAdditionalDetails()
|
|
53
|
-
|
|
54
|
-
const errorChain = new SDKError(httpError)
|
|
55
|
-
|
|
56
|
-
expect(getRootCauseBaseErrorMessage(errorChain)).toEqual(
|
|
57
|
-
'something went wrong on the server'
|
|
58
|
-
)
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
it('should return the HTTP error message if response message not present', async () => {
|
|
62
|
-
const mockResponse = {
|
|
63
|
-
status: 400,
|
|
64
|
-
statusText: 'Bad Request',
|
|
65
|
-
json: () => Promise.resolve({}),
|
|
66
|
-
} as Response
|
|
67
|
-
|
|
68
|
-
const httpError = new HTTPError(mockResponse, 'http://some.where', {})
|
|
69
|
-
|
|
70
|
-
await httpError.buildAdditionalDetails()
|
|
71
|
-
|
|
72
|
-
const errorChain = new SDKError(httpError)
|
|
73
|
-
|
|
74
|
-
expect(getRootCauseBaseErrorMessage(errorChain)).toEqual(
|
|
75
|
-
'[ValidationError] Request failed with status code 400 Bad Request'
|
|
76
|
-
)
|
|
77
|
-
})
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
describe('when root cause is base Error', () => {
|
|
81
|
-
it('should return the BaseError message', () => {
|
|
82
|
-
const errorChain = getErrorChain()
|
|
83
|
-
|
|
84
|
-
expect(getRootCauseBaseErrorMessage(errorChain)).toEqual(
|
|
85
|
-
'something happened'
|
|
86
|
-
)
|
|
87
|
-
})
|
|
88
|
-
})
|
|
89
|
-
})
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { BaseError } from '../baseError.js'
|
|
3
|
-
import { ErrorName, LiFiErrorCode } from '../constants.js'
|
|
4
|
-
import { SDKError } from '../SDKError.js'
|
|
5
|
-
import { getRootCause } from './rootCause.js'
|
|
6
|
-
|
|
7
|
-
const getErrorChain = () => {
|
|
8
|
-
const NonLiFiErrorChain = new Error('non lifi error')
|
|
9
|
-
NonLiFiErrorChain.cause = new Error('root cause')
|
|
10
|
-
return new SDKError(
|
|
11
|
-
new BaseError(
|
|
12
|
-
ErrorName.ValidationError,
|
|
13
|
-
LiFiErrorCode.ValidationError,
|
|
14
|
-
'something happened',
|
|
15
|
-
NonLiFiErrorChain
|
|
16
|
-
)
|
|
17
|
-
)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
describe('getRootCause', () => {
|
|
21
|
-
it('should return the top level error when there is no root cause', () => {
|
|
22
|
-
const error = new Error('top level')
|
|
23
|
-
|
|
24
|
-
expect(getRootCause(error)!.message).toEqual('top level')
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('should return the root cause', () => {
|
|
28
|
-
const errorChain = getErrorChain()
|
|
29
|
-
|
|
30
|
-
expect(getRootCause(errorChain)!.message).toEqual('root cause')
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
it('should return undefined when passed undefined', () => {
|
|
34
|
-
expect(getRootCause(undefined)).toBeUndefined()
|
|
35
|
-
})
|
|
36
|
-
})
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
afterEach,
|
|
3
|
-
beforeEach,
|
|
4
|
-
describe,
|
|
5
|
-
expect,
|
|
6
|
-
it,
|
|
7
|
-
type Mock,
|
|
8
|
-
vi,
|
|
9
|
-
} from 'vitest'
|
|
10
|
-
import { checkPackageUpdates } from './checkPackageUpdates.js'
|
|
11
|
-
|
|
12
|
-
const latestVersion = '2.5.6'
|
|
13
|
-
|
|
14
|
-
describe('checkPackageUpdates', () => {
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
vi.spyOn(global, 'fetch').mockResolvedValue({
|
|
17
|
-
json: () => Promise.resolve({ version: latestVersion }),
|
|
18
|
-
} as Response)
|
|
19
|
-
|
|
20
|
-
vi.spyOn(console, 'warn').mockImplementation(() => {})
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
afterEach(() => {
|
|
24
|
-
vi.resetAllMocks()
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('should be able to check the version number against npm', async () => {
|
|
28
|
-
const packageName = '@lifi/sdk'
|
|
29
|
-
const currentVersion = '0.0.0'
|
|
30
|
-
|
|
31
|
-
await checkPackageUpdates(packageName, currentVersion)
|
|
32
|
-
|
|
33
|
-
expect(global.fetch as Mock).toBeCalledWith(
|
|
34
|
-
`https://registry.npmjs.org/${packageName}/latest`
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
expect(console.warn).toBeCalledWith(
|
|
38
|
-
`${packageName}: new package version is available. Please update as soon as possible to enjoy the newest features. Current version: ${currentVersion}. Latest version: ${latestVersion}.`
|
|
39
|
-
)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('should not report if version matchs the latest on npm', async () => {
|
|
43
|
-
const packageName = '@lifi/sdk'
|
|
44
|
-
const currentVersion = '2.5.6'
|
|
45
|
-
|
|
46
|
-
await checkPackageUpdates(packageName, currentVersion)
|
|
47
|
-
|
|
48
|
-
expect(global.fetch as Mock).toBeCalledWith(
|
|
49
|
-
`https://registry.npmjs.org/${packageName}/latest`
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
expect(console.warn).not.toBeCalled()
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('should fail sliently if it encounters a problem', async () => {
|
|
56
|
-
vi.spyOn(global, 'fetch').mockRejectedValue({
|
|
57
|
-
json: () => Promise.resolve({ version: latestVersion }),
|
|
58
|
-
} as Response)
|
|
59
|
-
|
|
60
|
-
const packageName = '@lifi/sdk'
|
|
61
|
-
const currentVersion = '0.0.0'
|
|
62
|
-
|
|
63
|
-
await checkPackageUpdates(packageName, currentVersion)
|
|
64
|
-
|
|
65
|
-
expect(global.fetch as Mock).toBeCalledWith(
|
|
66
|
-
`https://registry.npmjs.org/${packageName}/latest`
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
expect(console.warn).not.toBeCalled()
|
|
70
|
-
})
|
|
71
|
-
})
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { SDKError } from '../errors/SDKError.js'
|
|
3
|
-
import { convertQuoteToRoute } from './convertQuoteToRoute.js'
|
|
4
|
-
|
|
5
|
-
describe('convertQuoteToRoute', () => {
|
|
6
|
-
const validQuote = {
|
|
7
|
-
id: 'test-quote',
|
|
8
|
-
type: 'swap',
|
|
9
|
-
tool: 'test-tool',
|
|
10
|
-
action: {
|
|
11
|
-
fromToken: { address: '0x111', decimals: 18, chainId: 1 },
|
|
12
|
-
fromAmount: '1000000000000000000',
|
|
13
|
-
fromAddress: '0xaaa',
|
|
14
|
-
toToken: { address: '0x222', decimals: 18, chainId: 1 },
|
|
15
|
-
toAddress: '0xbbb',
|
|
16
|
-
},
|
|
17
|
-
estimate: {
|
|
18
|
-
fromAmount: '1000000000000000000',
|
|
19
|
-
toAmount: '2000000000000000000',
|
|
20
|
-
toAmountMin: '1900000000000000000',
|
|
21
|
-
fromAmountUSD: '100',
|
|
22
|
-
toAmountUSD: '200',
|
|
23
|
-
approvalAddress: '0x333',
|
|
24
|
-
},
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
it('should convert valid quote to route', () => {
|
|
28
|
-
const route = convertQuoteToRoute(validQuote as any)
|
|
29
|
-
|
|
30
|
-
expect(route.id).toBe('test-quote')
|
|
31
|
-
expect(route.fromChainId).toBe(1)
|
|
32
|
-
expect(route.toChainId).toBe(1)
|
|
33
|
-
expect(route.fromAmount).toBe('1000000000000000000')
|
|
34
|
-
expect(route.toAmount).toBe('2000000000000000000')
|
|
35
|
-
expect(route.fromAmountUSD).toBe('100')
|
|
36
|
-
expect(route.toAmountUSD).toBe('200')
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
it('should throw error when fromAmountUSD is missing', () => {
|
|
40
|
-
const invalidQuote = {
|
|
41
|
-
...validQuote,
|
|
42
|
-
estimate: { ...validQuote.estimate, fromAmountUSD: undefined },
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
expect(() => convertQuoteToRoute(invalidQuote as any)).toThrow(SDKError)
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it('should throw error when toAmountUSD is missing', () => {
|
|
49
|
-
const invalidQuote = {
|
|
50
|
-
...validQuote,
|
|
51
|
-
estimate: { ...validQuote.estimate, toAmountUSD: undefined },
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
expect(() => convertQuoteToRoute(invalidQuote as any)).toThrow(SDKError)
|
|
55
|
-
})
|
|
56
|
-
})
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
|
-
import { fetchTxErrorDetails } from './fetchTxErrorDetails.js'
|
|
3
|
-
|
|
4
|
-
// Mock fetch
|
|
5
|
-
global.fetch = vi.fn()
|
|
6
|
-
|
|
7
|
-
describe('fetchTxErrorDetails', () => {
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
vi.clearAllMocks()
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
it('should return response body on success', async () => {
|
|
13
|
-
const mockResponse = { error_message: 'Out of gas' }
|
|
14
|
-
;(global.fetch as any).mockResolvedValueOnce({
|
|
15
|
-
json: vi.fn().mockResolvedValueOnce(mockResponse),
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
const result = await fetchTxErrorDetails('0x123', 1)
|
|
19
|
-
|
|
20
|
-
expect(result).toEqual(mockResponse)
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it('should return undefined on error', async () => {
|
|
24
|
-
;(global.fetch as any).mockRejectedValueOnce(new Error('Network error'))
|
|
25
|
-
|
|
26
|
-
const result = await fetchTxErrorDetails('0x123', 1)
|
|
27
|
-
|
|
28
|
-
expect(result).toBeUndefined()
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('should call correct tenderly URL', async () => {
|
|
32
|
-
;(global.fetch as any).mockResolvedValueOnce({
|
|
33
|
-
json: vi.fn().mockResolvedValueOnce({}),
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
await fetchTxErrorDetails('0x123abc', 1)
|
|
37
|
-
|
|
38
|
-
expect(global.fetch).toHaveBeenCalledWith(
|
|
39
|
-
'https://api.tenderly.co/api/v1/public-contract/1/tx/0x123abc'
|
|
40
|
-
)
|
|
41
|
-
})
|
|
42
|
-
})
|