@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.
Files changed (56) hide show
  1. package/LICENSE +201 -165
  2. package/dist/cjs/version.d.ts +1 -1
  3. package/dist/cjs/version.js +1 -1
  4. package/dist/esm/version.d.ts +1 -1
  5. package/dist/esm/version.js +1 -1
  6. package/dist/types/version.d.ts +1 -1
  7. package/package.json +16 -1
  8. package/src/version.ts +1 -1
  9. package/CHANGELOG.md +0 -1272
  10. package/package.json.tmp +0 -103
  11. package/src/actions/actions.unit.handlers.ts +0 -78
  12. package/src/actions/getChains.unit.spec.ts +0 -19
  13. package/src/actions/getConnections.unit.spec.ts +0 -45
  14. package/src/actions/getContractCallsQuote.unit.spec.ts +0 -323
  15. package/src/actions/getGasRecommendation.unit.spec.ts +0 -40
  16. package/src/actions/getNameServiceAddress.unit.spec.ts +0 -169
  17. package/src/actions/getQuote.int.spec.ts +0 -18
  18. package/src/actions/getQuote.unit.spec.ts +0 -154
  19. package/src/actions/getRelayedTransactionStatus.unit.spec.ts +0 -243
  20. package/src/actions/getRelayerQuote.unit.spec.ts +0 -220
  21. package/src/actions/getRoutes.unit.spec.ts +0 -112
  22. package/src/actions/getStatus.unit.spec.ts +0 -53
  23. package/src/actions/getStepTransaction.unit.spec.ts +0 -140
  24. package/src/actions/getToken.unit.spec.ts +0 -45
  25. package/src/actions/getTokenBalance.unit.spec.ts +0 -61
  26. package/src/actions/getTokenBalances.unit.spec.ts +0 -68
  27. package/src/actions/getTokenBalancesByChain.unit.spec.ts +0 -108
  28. package/src/actions/getTokens.unit.spec.ts +0 -16
  29. package/src/actions/getTools.unit.spec.ts +0 -20
  30. package/src/actions/getTransactionHistory.unit.spec.ts +0 -36
  31. package/src/actions/getWalletBalances.unit.spec.ts +0 -90
  32. package/src/actions/relayTransaction.unit.spec.ts +0 -229
  33. package/src/client/createClient.unit.spec.ts +0 -274
  34. package/src/client/getClientStorage.unit.spec.ts +0 -382
  35. package/src/core/StatusManager.unit.spec.ts +0 -298
  36. package/src/core/execution.unit.handlers.ts +0 -32
  37. package/src/core/execution.unit.mock.ts +0 -252
  38. package/src/core/execution.unit.spec.ts +0 -86
  39. package/src/core/stepComparison.unit.spec.ts +0 -89
  40. package/src/errors/SDKError.unit.spec.ts +0 -160
  41. package/src/errors/baseError.unit.spec.ts +0 -22
  42. package/src/errors/httpError.unit.spec.ts +0 -125
  43. package/src/errors/utils/baseErrorRootCause.unit.spec.ts +0 -89
  44. package/src/errors/utils/rootCause.unit.spec.ts +0 -36
  45. package/src/utils/checkPackageUpdates.unit.spec.ts +0 -71
  46. package/src/utils/convertQuoteToRoute.unit.spec.ts +0 -56
  47. package/src/utils/fetchTxErrorDetails.unit.spec.ts +0 -42
  48. package/src/utils/getTransactionMessage.unit.spec.ts +0 -38
  49. package/src/utils/isRoutesRequest.unit.spec.ts +0 -46
  50. package/src/utils/isStep.unit.spec.ts +0 -55
  51. package/src/utils/isToken.unit.spec.ts +0 -49
  52. package/src/utils/request.unit.spec.ts +0 -159
  53. package/src/utils/sleep.unit.spec.ts +0 -17
  54. package/src/utils/waitForResult.unit.spec.ts +0 -75
  55. package/src/utils/withDedupe.unit.spec.ts +0 -26
  56. package/tsconfig.json +0 -18
package/package.json.tmp DELETED
@@ -1,103 +0,0 @@
1
- {
2
- "name": "@lifi/sdk",
3
- "version": "4.0.0-alpha.1",
4
- "description": "LI.FI SDK for Any-to-Any Cross-Chain-Swap",
5
- "homepage": "https://github.com/lifinance/sdk",
6
- "bugs": {
7
- "url": "https://github.com/lifinance/sdk/issues"
8
- },
9
- "repository": {
10
- "type": "git",
11
- "url": "https://github.com/lifinance/sdk.git",
12
- "directory": "packages/sdk"
13
- },
14
- "license": "Apache-2.0",
15
- "author": "Eugene Chybisov <eugene@li.finance>",
16
- "type": "module",
17
- "sideEffects": false,
18
- "main": "./dist/cjs/index.js",
19
- "module": "./dist/esm/index.js",
20
- "types": "./dist/types/index.d.ts",
21
- "typings": "./dist/types/index.d.ts",
22
- "exports": {
23
- ".": {
24
- "types": "./dist/types/index.d.ts",
25
- "import": "./dist/esm/index.js",
26
- "default": "./dist/cjs/index.js"
27
- },
28
- "./package.json": "./package.json"
29
- },
30
- "scripts": {
31
- "build": "pnpm clean && pnpm build:version && pnpm build:cjs && pnpm build:esm && pnpm build:types && pnpm build:clean",
32
- "build:cjs": "tsc --project ./tsconfig.json --module commonjs --outDir ./dist/cjs --removeComments --verbatimModuleSyntax false && mkdir -p ./dist/cjs && printf '{\"type\":\"commonjs\"}' > ./dist/cjs/package.json",
33
- "build:esm": "tsc --project ./tsconfig.json --module es2015 --outDir ./dist/esm && mkdir -p ./dist/esm && printf '{\"type\": \"module\",\"sideEffects\":false}' > ./dist/esm/package.json",
34
- "build:types": "tsc --project ./tsconfig.json --module esnext --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap",
35
- "build:prerelease": "node ../../scripts/prerelease.js && cpy '../../*.md' .",
36
- "build:postrelease": "node ../../scripts/postrelease.js && rm -rf *.md",
37
- "build:clean": "rm -rf tsconfig.tsbuildinfo ./dist/tsconfig.tsbuildinfo",
38
- "build:version": "node ../../scripts/version.js",
39
- "clean": "pnpm build:clean && rm -rf dist",
40
- "coverage": "vitest run --coverage",
41
- "test": "vitest --run --dangerouslyIgnoreUnhandledErrors",
42
- "test:cov": "pnpm test --coverage",
43
- "test:unit": "pnpm test .unit.spec.ts --passWithNoTests",
44
- "check:types": "tsc --noEmit",
45
- "check:circular-deps": "madge --circular $(find ./src -name '*.ts')",
46
- "check:circular-deps-graph": "madge --circular $(find ./src -name '*.ts') --image graph.svg",
47
- "watch": "tsc -w -p ./tsconfig.json"
48
- },
49
- "dependencies": {
50
- "@lifi/types": "^17.46.0",
51
- "viem": "^2.39.0"
52
- },
53
- "devDependencies": {
54
- "@lifi/data-types": "^6.40.0",
55
- "@vitest/coverage-v8": "^4.0.10",
56
- "cpy-cli": "^6.0.0",
57
- "madge": "^8.0.0",
58
- "msw": "^2.11.3",
59
- "typescript": "^5.9.3",
60
- "vitest": "^4.0.10"
61
- },
62
- "publishConfig": {
63
- "access": "public"
64
- },
65
- "files": [
66
- "dist/**",
67
- "!dist/**/*.tsbuildinfo",
68
- "src/**/*.ts",
69
- "!src/**/*.spec.ts",
70
- "!src/**/*.test.ts",
71
- "!src/**/*.mock.ts",
72
- "!src/**/*.spec.ts",
73
- "!src/**/*.handlers.ts",
74
- "!src/**/*.tsbuildinfo",
75
- "!**/__mocks__/**",
76
- "!*.tmp",
77
- "!*.env",
78
- "!tsconfig.json"
79
- ],
80
- "keywords": [
81
- "swap",
82
- "bridge",
83
- "bridge-aggregation",
84
- "cross-chain",
85
- "cross-chain-applications",
86
- "cross-chain-bridge",
87
- "dapp",
88
- "defi",
89
- "ethereum",
90
- "bitcoin",
91
- "solana",
92
- "sui",
93
- "tron",
94
- "lifi",
95
- "multi-chain",
96
- "sdk",
97
- "ethers",
98
- "viem",
99
- "wagmi",
100
- "web3",
101
- "web3-react"
102
- ]
103
- }
@@ -1,78 +0,0 @@
1
- import { findDefaultToken } from '@lifi/data-types'
2
- import { ChainId, CoinKey } from '@lifi/types'
3
- import { HttpResponse, http } from 'msw'
4
- import { setupServer } from 'msw/node'
5
- import { afterAll, afterEach, beforeAll, beforeEach, vi } from 'vitest'
6
- import { createClient } from '../client/createClient.js'
7
- import { requestSettings } from '../utils/request.js'
8
-
9
- const client = createClient({
10
- integrator: 'lifi-sdk',
11
- })
12
-
13
- export const handlers = [
14
- http.post(`${client.config.apiUrl}/advanced/routes`, async () => {
15
- return HttpResponse.json({})
16
- }),
17
- http.post(`${client.config.apiUrl}/advanced/possibilities`, async () =>
18
- HttpResponse.json({})
19
- ),
20
- http.get(`${client.config.apiUrl}/token`, async () => HttpResponse.json({})),
21
- http.get(`${client.config.apiUrl}/quote`, async () => HttpResponse.json({})),
22
- http.get(`${client.config.apiUrl}/status`, async () => HttpResponse.json({})),
23
- http.get(`${client.config.apiUrl}/chains`, async () =>
24
- HttpResponse.json({ chains: [{ id: 1 }] })
25
- ),
26
- http.get(`${client.config.apiUrl}/tools`, async () =>
27
- HttpResponse.json({ bridges: [], exchanges: [] })
28
- ),
29
- http.get(`${client.config.apiUrl}/tokens`, async () =>
30
- HttpResponse.json({
31
- tokens: {
32
- [ChainId.ETH]: [findDefaultToken(CoinKey.ETH, ChainId.ETH)],
33
- },
34
- })
35
- ),
36
- http.post(`${client.config.apiUrl}/advanced/stepTransaction`, async () =>
37
- HttpResponse.json({})
38
- ),
39
- http.get(`${client.config.apiUrl}/gas/suggestion/${ChainId.OPT}`, async () =>
40
- HttpResponse.json({})
41
- ),
42
- http.get(`${client.config.apiUrl}/connections`, async () =>
43
- HttpResponse.json({ connections: [] })
44
- ),
45
- http.get(`${client.config.apiUrl}/analytics/transfers`, async () =>
46
- HttpResponse.json({})
47
- ),
48
- ]
49
-
50
- /**
51
- * Sets up MSW server with common handlers for HTTP-based tests
52
- * Call this function at the top level of your test file
53
- */
54
- export const setupTestServer = () => {
55
- const server = setupServer(...handlers)
56
-
57
- beforeAll(() => {
58
- server.listen({
59
- onUnhandledRequest: 'warn',
60
- })
61
- requestSettings.retries = 0
62
- })
63
-
64
- beforeEach(() => {
65
- vi.clearAllMocks()
66
- })
67
-
68
- afterEach(() => server.resetHandlers())
69
-
70
- afterAll(() => {
71
- requestSettings.retries = 1
72
- server.close()
73
- })
74
-
75
- return server
76
- }
77
-
78
- export { client }
@@ -1,19 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest'
2
- import * as request from '../utils/request.js'
3
- import { client, setupTestServer } from './actions.unit.handlers.js'
4
- import { getChains } from './getChains.js'
5
-
6
- const mockedFetch = vi.spyOn(request, 'request')
7
-
8
- describe('getChains', () => {
9
- setupTestServer()
10
-
11
- describe('and the backend call is successful', () => {
12
- it('call the server once', async () => {
13
- const chains = await getChains(client)
14
-
15
- expect(chains[0]?.id).toEqual(1)
16
- expect(mockedFetch).toHaveBeenCalledTimes(1)
17
- })
18
- })
19
- })
@@ -1,45 +0,0 @@
1
- import { findDefaultToken } from '@lifi/data-types'
2
- import type { ConnectionsRequest } from '@lifi/types'
3
- import { ChainId, CoinKey } from '@lifi/types'
4
- import { HttpResponse, http } from 'msw'
5
- import { describe, expect, it, vi } from 'vitest'
6
- import * as request from '../utils/request.js'
7
- import { client, setupTestServer } from './actions.unit.handlers.js'
8
- import { getConnections } from './getConnections.js'
9
-
10
- const mockedFetch = vi.spyOn(request, 'request')
11
-
12
- describe('getConnections', () => {
13
- const server = setupTestServer()
14
-
15
- it('returns empty array in response', async () => {
16
- server.use(
17
- http.get(`${client.config.apiUrl}/connections`, async () =>
18
- HttpResponse.json({ connections: [] })
19
- )
20
- )
21
-
22
- const connectionRequest: ConnectionsRequest = {
23
- fromChain: ChainId.BSC,
24
- toChain: ChainId.OPT,
25
- fromToken: findDefaultToken(CoinKey.USDC, ChainId.BSC).address,
26
- toToken: findDefaultToken(CoinKey.USDC, ChainId.OPT).address,
27
- allowBridges: ['connext', 'uniswap', 'polygon'],
28
- allowExchanges: ['1inch', 'ParaSwap', 'SushiSwap'],
29
- denyBridges: ['Hop', 'Multichain'],
30
- preferBridges: ['Hyphen', 'Across'],
31
- denyExchanges: ['UbeSwap', 'BeamSwap'],
32
- preferExchanges: ['Evmoswap', 'Diffusion'],
33
- }
34
-
35
- const generatedURL =
36
- 'https://li.quest/v1/connections?fromChain=56&fromToken=0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d&toChain=10&toToken=0x0b2c639c533813f4aa9d7837caf62653d097ff85&allowBridges=connext&allowBridges=uniswap&allowBridges=polygon&denyBridges=Hop&denyBridges=Multichain&preferBridges=Hyphen&preferBridges=Across&allowExchanges=1inch&allowExchanges=ParaSwap&allowExchanges=SushiSwap&denyExchanges=UbeSwap&denyExchanges=BeamSwap&preferExchanges=Evmoswap&preferExchanges=Diffusion'
37
-
38
- await expect(getConnections(client, connectionRequest)).resolves.toEqual({
39
- connections: [],
40
- })
41
-
42
- expect((mockedFetch.mock.calls[0][1] as URL).href).toEqual(generatedURL)
43
- expect(mockedFetch).toHaveBeenCalledOnce()
44
- })
45
- })
@@ -1,323 +0,0 @@
1
- import type {
2
- ContractCallsQuoteRequest,
3
- LiFiStep,
4
- RequestOptions,
5
- } from '@lifi/types'
6
- import { ChainId } from '@lifi/types'
7
- import { HttpResponse, http } from 'msw'
8
- import { describe, expect, it } from 'vitest'
9
- import { ValidationError } from '../errors/errors.js'
10
- import { SDKError } from '../errors/SDKError.js'
11
- import { client, setupTestServer } from './actions.unit.handlers.js'
12
- import { getContractCallsQuote } from './getContractCallsQuote.js'
13
-
14
- describe('getContractCallsQuote', () => {
15
- const server = setupTestServer()
16
-
17
- const createMockContractCallsRequest = (
18
- overrides: Partial<ContractCallsQuoteRequest> = {}
19
- ): ContractCallsQuoteRequest => ({
20
- fromChain: ChainId.ETH,
21
- fromToken: '0xA0b86a33E6441c8C06DDD4f36e4C4C5B4c3B4c3B',
22
- fromAddress: '0x1234567890123456789012345678901234567890',
23
- toChain: ChainId.POL,
24
- toToken: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174',
25
- contractCalls: [
26
- {
27
- fromAmount: '1000000',
28
- fromTokenAddress: '0xA0b86a33E6441c8C06DDD4f36e4C4C5B4c3B4c3B',
29
- toContractAddress: '0x1234567890123456789012345678901234567890',
30
- toContractCallData: '0x1234567890abcdef',
31
- toContractGasLimit: '100000',
32
- },
33
- ],
34
- fromAmount: '1000000',
35
- ...overrides,
36
- })
37
-
38
- const mockLiFiStep: LiFiStep = {
39
- id: 'test-step-id',
40
- type: 'lifi',
41
- includedSteps: [],
42
- tool: 'test-tool',
43
- toolDetails: {
44
- key: 'test-tool',
45
- name: 'Test Tool',
46
- logoURI: 'https://example.com/logo.png',
47
- },
48
- action: {
49
- fromChainId: ChainId.ETH,
50
- toChainId: ChainId.POL,
51
- fromToken: {
52
- address: '0xA0b86a33E6441c8C06DDD4f36e4C4C5B4c3B4c3B',
53
- symbol: 'USDC',
54
- decimals: 6,
55
- chainId: ChainId.ETH,
56
- name: 'USD Coin',
57
- priceUSD: '1.00',
58
- },
59
- toToken: {
60
- address: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174',
61
- symbol: 'USDC',
62
- decimals: 6,
63
- chainId: ChainId.POL,
64
- name: 'USD Coin',
65
- priceUSD: '1.00',
66
- },
67
- fromAmount: '1000000',
68
- fromAddress: '0x1234567890123456789012345678901234567890',
69
- toAddress: '0x1234567890123456789012345678901234567890',
70
- },
71
- estimate: {
72
- fromAmount: '1000000',
73
- toAmount: '1000000',
74
- toAmountMin: '970000',
75
- approvalAddress: '0x1234567890123456789012345678901234567890',
76
- tool: 'test-tool',
77
- executionDuration: 30000,
78
- },
79
- transactionRequest: {
80
- to: '0x1234567890123456789012345678901234567890',
81
- data: '0x',
82
- value: '0',
83
- gasLimit: '100000',
84
- },
85
- }
86
-
87
- describe('success scenarios', () => {
88
- it('should get contract calls quote successfully with fromAmount', async () => {
89
- server.use(
90
- http.post(`${client.config.apiUrl}/quote/contractCalls`, async () => {
91
- return HttpResponse.json(mockLiFiStep)
92
- })
93
- )
94
-
95
- const request = createMockContractCallsRequest({
96
- fromAmount: '1000000',
97
- })
98
-
99
- const result = await getContractCallsQuote(client, request)
100
-
101
- expect(result).toEqual(mockLiFiStep)
102
- })
103
-
104
- it('should get contract calls quote successfully with toAmount', async () => {
105
- server.use(
106
- http.post(`${client.config.apiUrl}/quote/contractCalls`, async () => {
107
- return HttpResponse.json(mockLiFiStep)
108
- })
109
- )
110
-
111
- const request = createMockContractCallsRequest({
112
- toAmount: '1000000',
113
- fromAmount: undefined,
114
- })
115
-
116
- const result = await getContractCallsQuote(client, request)
117
-
118
- expect(result).toEqual(mockLiFiStep)
119
- })
120
-
121
- it('should pass request options correctly', async () => {
122
- const mockAbortController = new AbortController()
123
- const options: RequestOptions = {
124
- signal: mockAbortController.signal,
125
- }
126
-
127
- let capturedOptions: any
128
- server.use(
129
- http.post(
130
- `${client.config.apiUrl}/quote/contractCalls`,
131
- async ({ request }) => {
132
- capturedOptions = request
133
- return HttpResponse.json(mockLiFiStep)
134
- }
135
- )
136
- )
137
-
138
- const request = createMockContractCallsRequest()
139
-
140
- await getContractCallsQuote(client, request, options)
141
-
142
- expect(capturedOptions.signal).toBeDefined()
143
- expect(capturedOptions.signal).toBeInstanceOf(AbortSignal)
144
- })
145
- })
146
-
147
- describe('validation scenarios', () => {
148
- it('should throw SDKError when fromChain is missing', async () => {
149
- const invalidRequest = createMockContractCallsRequest({
150
- fromChain: undefined as any,
151
- })
152
-
153
- await expect(
154
- getContractCallsQuote(client, invalidRequest)
155
- ).rejects.toThrow(SDKError)
156
-
157
- try {
158
- await getContractCallsQuote(client, invalidRequest)
159
- } catch (error) {
160
- expect(error).toBeInstanceOf(SDKError)
161
- expect((error as SDKError).cause).toBeInstanceOf(ValidationError)
162
- expect((error as SDKError).cause.message).toBe(
163
- 'Required parameter "fromChain" is missing.'
164
- )
165
- }
166
- })
167
-
168
- it('should throw SDKError when fromToken is missing', async () => {
169
- const invalidRequest = createMockContractCallsRequest({
170
- fromToken: undefined as any,
171
- })
172
-
173
- await expect(
174
- getContractCallsQuote(client, invalidRequest)
175
- ).rejects.toThrow(SDKError)
176
-
177
- try {
178
- await getContractCallsQuote(client, invalidRequest)
179
- } catch (error) {
180
- expect(error).toBeInstanceOf(SDKError)
181
- expect((error as SDKError).cause).toBeInstanceOf(ValidationError)
182
- expect((error as SDKError).cause.message).toBe(
183
- 'Required parameter "fromToken" is missing.'
184
- )
185
- }
186
- })
187
-
188
- it('should throw SDKError when fromAddress is missing', async () => {
189
- const invalidRequest = createMockContractCallsRequest({
190
- fromAddress: undefined as any,
191
- })
192
-
193
- await expect(
194
- getContractCallsQuote(client, invalidRequest)
195
- ).rejects.toThrow(SDKError)
196
-
197
- try {
198
- await getContractCallsQuote(client, invalidRequest)
199
- } catch (error) {
200
- expect(error).toBeInstanceOf(SDKError)
201
- expect((error as SDKError).cause).toBeInstanceOf(ValidationError)
202
- expect((error as SDKError).cause.message).toBe(
203
- 'Required parameter "fromAddress" is missing.'
204
- )
205
- }
206
- })
207
-
208
- it('should throw SDKError when toChain is missing', async () => {
209
- const invalidRequest = createMockContractCallsRequest({
210
- toChain: undefined as any,
211
- })
212
-
213
- await expect(
214
- getContractCallsQuote(client, invalidRequest)
215
- ).rejects.toThrow(SDKError)
216
-
217
- try {
218
- await getContractCallsQuote(client, invalidRequest)
219
- } catch (error) {
220
- expect(error).toBeInstanceOf(SDKError)
221
- expect((error as SDKError).cause).toBeInstanceOf(ValidationError)
222
- expect((error as SDKError).cause.message).toBe(
223
- 'Required parameter "toChain" is missing.'
224
- )
225
- }
226
- })
227
-
228
- it('should throw SDKError when toToken is missing', async () => {
229
- const invalidRequest = createMockContractCallsRequest({
230
- toToken: undefined as any,
231
- })
232
-
233
- await expect(
234
- getContractCallsQuote(client, invalidRequest)
235
- ).rejects.toThrow(SDKError)
236
-
237
- try {
238
- await getContractCallsQuote(client, invalidRequest)
239
- } catch (error) {
240
- expect(error).toBeInstanceOf(SDKError)
241
- expect((error as SDKError).cause).toBeInstanceOf(ValidationError)
242
- expect((error as SDKError).cause.message).toBe(
243
- 'Required parameter "toToken" is missing.'
244
- )
245
- }
246
- })
247
-
248
- it('should throw SDKError when contractCalls is missing', async () => {
249
- const invalidRequest = createMockContractCallsRequest({
250
- contractCalls: undefined as any,
251
- })
252
-
253
- await expect(
254
- getContractCallsQuote(client, invalidRequest)
255
- ).rejects.toThrow(SDKError)
256
-
257
- try {
258
- await getContractCallsQuote(client, invalidRequest)
259
- } catch (error) {
260
- expect(error).toBeInstanceOf(SDKError)
261
- expect((error as SDKError).cause).toBeInstanceOf(ValidationError)
262
- expect((error as SDKError).cause.message).toBe(
263
- 'Required parameter "contractCalls" is missing.'
264
- )
265
- }
266
- })
267
-
268
- it('should throw SDKError when both fromAmount and toAmount are missing', async () => {
269
- const invalidRequest = createMockContractCallsRequest()
270
- // Remove both fromAmount and toAmount to test validation
271
- delete (invalidRequest as any).fromAmount
272
- delete (invalidRequest as any).toAmount
273
-
274
- await expect(
275
- getContractCallsQuote(client, invalidRequest)
276
- ).rejects.toThrow(SDKError)
277
-
278
- try {
279
- await getContractCallsQuote(client, invalidRequest)
280
- } catch (error) {
281
- expect(error).toBeInstanceOf(SDKError)
282
- expect((error as SDKError).cause).toBeInstanceOf(ValidationError)
283
- expect((error as SDKError).cause.message).toBe(
284
- 'Required parameter "fromAmount" or "toAmount" is missing.'
285
- )
286
- }
287
- })
288
- })
289
-
290
- describe('error scenarios', () => {
291
- it('should throw SDKError when network request fails', async () => {
292
- server.use(
293
- http.post(`${client.config.apiUrl}/quote/contractCalls`, async () => {
294
- return HttpResponse.error()
295
- })
296
- )
297
-
298
- const request = createMockContractCallsRequest()
299
-
300
- await expect(getContractCallsQuote(client, request)).rejects.toThrow(
301
- SDKError
302
- )
303
- })
304
-
305
- it('should throw SDKError when request times out', async () => {
306
- server.use(
307
- http.post(`${client.config.apiUrl}/quote/contractCalls`, async () => {
308
- // Simulate timeout by not responding
309
- await new Promise(() => {}) // Never resolves
310
- })
311
- )
312
-
313
- const request = createMockContractCallsRequest()
314
- const timeoutOptions: RequestOptions = {
315
- signal: AbortSignal.timeout(100), // 100ms timeout
316
- }
317
-
318
- await expect(
319
- getContractCallsQuote(client, request, timeoutOptions)
320
- ).rejects.toThrow()
321
- })
322
- })
323
- })
@@ -1,40 +0,0 @@
1
- import { ChainId } from '@lifi/types'
2
- import { describe, expect, it, vi } from 'vitest'
3
- import { ValidationError } from '../errors/errors.js'
4
- import { SDKError } from '../errors/SDKError.js'
5
- import * as request from '../utils/request.js'
6
- import { client, setupTestServer } from './actions.unit.handlers.js'
7
- import { getGasRecommendation } from './getGasRecommendation.js'
8
-
9
- const mockedFetch = vi.spyOn(request, 'request')
10
-
11
- describe('getGasRecommendation', () => {
12
- setupTestServer()
13
-
14
- describe('user input is invalid', () => {
15
- it('throw an error', async () => {
16
- await expect(
17
- getGasRecommendation(client, {
18
- chainId: undefined as unknown as number,
19
- })
20
- ).rejects.toThrowError(
21
- new SDKError(
22
- new ValidationError('Required parameter "chainId" is missing.')
23
- )
24
- )
25
- expect(mockedFetch).toHaveBeenCalledTimes(0)
26
- })
27
- })
28
-
29
- describe('user input is valid', () => {
30
- describe('and the backend call is successful', () => {
31
- it('call the server once', async () => {
32
- await getGasRecommendation(client, {
33
- chainId: ChainId.OPT,
34
- })
35
-
36
- expect(mockedFetch).toHaveBeenCalledTimes(1)
37
- })
38
- })
39
- })
40
- })