@lifi/sdk 4.0.0-alpha.1 → 4.0.0-alpha.3

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 (62) hide show
  1. package/LICENSE +201 -165
  2. package/dist/cjs/client/getClientStorage.js +3 -4
  3. package/dist/cjs/client/getClientStorage.js.map +1 -1
  4. package/dist/cjs/version.d.ts +1 -1
  5. package/dist/cjs/version.js +1 -1
  6. package/dist/esm/client/getClientStorage.js +4 -4
  7. package/dist/esm/client/getClientStorage.js.map +1 -1
  8. package/dist/esm/version.d.ts +1 -1
  9. package/dist/esm/version.js +1 -1
  10. package/dist/types/client/getClientStorage.d.ts.map +1 -1
  11. package/dist/types/version.d.ts +1 -1
  12. package/package.json +17 -2
  13. package/src/client/getClientStorage.ts +5 -4
  14. package/src/version.ts +1 -1
  15. package/CHANGELOG.md +0 -1272
  16. package/package.json.tmp +0 -103
  17. package/src/actions/actions.unit.handlers.ts +0 -78
  18. package/src/actions/getChains.unit.spec.ts +0 -19
  19. package/src/actions/getConnections.unit.spec.ts +0 -45
  20. package/src/actions/getContractCallsQuote.unit.spec.ts +0 -323
  21. package/src/actions/getGasRecommendation.unit.spec.ts +0 -40
  22. package/src/actions/getNameServiceAddress.unit.spec.ts +0 -169
  23. package/src/actions/getQuote.int.spec.ts +0 -18
  24. package/src/actions/getQuote.unit.spec.ts +0 -154
  25. package/src/actions/getRelayedTransactionStatus.unit.spec.ts +0 -243
  26. package/src/actions/getRelayerQuote.unit.spec.ts +0 -220
  27. package/src/actions/getRoutes.unit.spec.ts +0 -112
  28. package/src/actions/getStatus.unit.spec.ts +0 -53
  29. package/src/actions/getStepTransaction.unit.spec.ts +0 -140
  30. package/src/actions/getToken.unit.spec.ts +0 -45
  31. package/src/actions/getTokenBalance.unit.spec.ts +0 -61
  32. package/src/actions/getTokenBalances.unit.spec.ts +0 -68
  33. package/src/actions/getTokenBalancesByChain.unit.spec.ts +0 -108
  34. package/src/actions/getTokens.unit.spec.ts +0 -16
  35. package/src/actions/getTools.unit.spec.ts +0 -20
  36. package/src/actions/getTransactionHistory.unit.spec.ts +0 -36
  37. package/src/actions/getWalletBalances.unit.spec.ts +0 -90
  38. package/src/actions/relayTransaction.unit.spec.ts +0 -229
  39. package/src/client/createClient.unit.spec.ts +0 -274
  40. package/src/client/getClientStorage.unit.spec.ts +0 -382
  41. package/src/core/StatusManager.unit.spec.ts +0 -298
  42. package/src/core/execution.unit.handlers.ts +0 -32
  43. package/src/core/execution.unit.mock.ts +0 -252
  44. package/src/core/execution.unit.spec.ts +0 -86
  45. package/src/core/stepComparison.unit.spec.ts +0 -89
  46. package/src/errors/SDKError.unit.spec.ts +0 -160
  47. package/src/errors/baseError.unit.spec.ts +0 -22
  48. package/src/errors/httpError.unit.spec.ts +0 -125
  49. package/src/errors/utils/baseErrorRootCause.unit.spec.ts +0 -89
  50. package/src/errors/utils/rootCause.unit.spec.ts +0 -36
  51. package/src/utils/checkPackageUpdates.unit.spec.ts +0 -71
  52. package/src/utils/convertQuoteToRoute.unit.spec.ts +0 -56
  53. package/src/utils/fetchTxErrorDetails.unit.spec.ts +0 -42
  54. package/src/utils/getTransactionMessage.unit.spec.ts +0 -38
  55. package/src/utils/isRoutesRequest.unit.spec.ts +0 -46
  56. package/src/utils/isStep.unit.spec.ts +0 -55
  57. package/src/utils/isToken.unit.spec.ts +0 -49
  58. package/src/utils/request.unit.spec.ts +0 -159
  59. package/src/utils/sleep.unit.spec.ts +0 -17
  60. package/src/utils/waitForResult.unit.spec.ts +0 -75
  61. package/src/utils/withDedupe.unit.spec.ts +0 -26
  62. package/tsconfig.json +0 -18
@@ -1,169 +0,0 @@
1
- import type { ChainType } from '@lifi/types'
2
- import { describe, expect, it, vi } from 'vitest'
3
- import { client } from './actions.unit.handlers.js'
4
- import { getNameServiceAddress } from './getNameServiceAddress.js'
5
-
6
- // Mock providers locally
7
- const createMockProvider = (type: ChainType, resolveAddressMock: any) => ({
8
- type,
9
- resolveAddress: resolveAddressMock,
10
- isAddress: vi.fn(),
11
- getBalance: vi.fn(),
12
- getStepExecutor: vi.fn(),
13
- setOptions: vi.fn(),
14
- })
15
-
16
- const EVM = (_options: any) => createMockProvider('EVM' as ChainType, vi.fn())
17
- const Solana = (_options: any) =>
18
- createMockProvider('SVM' as ChainType, vi.fn())
19
- const UTXO = (_options: any) => createMockProvider('UTXO' as ChainType, vi.fn())
20
-
21
- describe('getNameServiceAddress', () => {
22
- describe('success scenarios', () => {
23
- it('should resolve address successfully with single provider', async () => {
24
- const mockResolveAddress = vi
25
- .fn()
26
- .mockResolvedValue('0x1234567890123456789012345678901234567890')
27
-
28
- const provider = EVM({ getWalletClient: vi.fn() })
29
- vi.spyOn(provider, 'resolveAddress').mockImplementation(
30
- mockResolveAddress
31
- )
32
-
33
- client.setProviders([provider])
34
-
35
- const result = await getNameServiceAddress(client, 'test.eth')
36
-
37
- expect(result).toBe('0x1234567890123456789012345678901234567890')
38
- expect(mockResolveAddress).toHaveBeenCalledWith('test.eth', client)
39
- })
40
-
41
- it('should resolve address successfully with multiple providers', async () => {
42
- const mockResolveAddress1 = vi
43
- .fn()
44
- .mockResolvedValue('0x1111111111111111111111111111111111111111')
45
- const mockResolveAddress2 = vi
46
- .fn()
47
- .mockResolvedValue('0x2222222222222222222222222222222222222222')
48
-
49
- const provider1 = EVM({ getWalletClient: vi.fn() })
50
- const provider2 = Solana({ getWalletAdapter: vi.fn() })
51
-
52
- vi.spyOn(provider1, 'resolveAddress').mockImplementation(
53
- mockResolveAddress1
54
- )
55
- vi.spyOn(provider2, 'resolveAddress').mockImplementation(
56
- mockResolveAddress2
57
- )
58
-
59
- client.setProviders([provider1, provider2])
60
-
61
- const result = await getNameServiceAddress(client, 'test.sol')
62
-
63
- // Should return the first successful result
64
- expect(result).toBe('0x1111111111111111111111111111111111111111')
65
- expect(mockResolveAddress1).toHaveBeenCalledWith('test.sol', client)
66
- })
67
-
68
- it('should resolve address with specific chain type', async () => {
69
- const mockResolveAddress = vi
70
- .fn()
71
- .mockResolvedValue('0x1234567890123456789012345678901234567890')
72
-
73
- const evmProvider = EVM({ getWalletClient: vi.fn() })
74
- const svmProvider = Solana({ getWalletAdapter: vi.fn() })
75
-
76
- vi.spyOn(evmProvider, 'resolveAddress').mockImplementation(
77
- mockResolveAddress
78
- )
79
-
80
- client.setProviders([evmProvider, svmProvider])
81
-
82
- const result = await getNameServiceAddress(
83
- client,
84
- 'test.eth',
85
- 'EVM' as ChainType
86
- )
87
-
88
- expect(result).toBe('0x1234567890123456789012345678901234567890')
89
- expect(mockResolveAddress).toHaveBeenCalledWith('test.eth', client)
90
- })
91
- })
92
-
93
- describe('chain type filtering', () => {
94
- it('should filter providers by chain type', async () => {
95
- const mockResolveAddress = vi
96
- .fn()
97
- .mockResolvedValue('0x1234567890123456789012345678901234567890')
98
-
99
- const evmProvider = EVM({ getWalletClient: vi.fn() })
100
- const svmProvider = Solana({ getWalletAdapter: vi.fn() })
101
- const utxoProvider = UTXO({ getWalletClient: vi.fn() })
102
-
103
- vi.spyOn(evmProvider, 'resolveAddress').mockImplementation(
104
- mockResolveAddress
105
- )
106
-
107
- client.setProviders([evmProvider, svmProvider, utxoProvider])
108
-
109
- const result = await getNameServiceAddress(
110
- client,
111
- 'test.eth',
112
- 'EVM' as ChainType
113
- )
114
-
115
- expect(result).toBe('0x1234567890123456789012345678901234567890')
116
- expect(mockResolveAddress).toHaveBeenCalledWith('test.eth', client)
117
- })
118
-
119
- it('should return undefined when no providers match chain type', async () => {
120
- const mockResolveAddress = vi
121
- .fn()
122
- .mockResolvedValue('0x1234567890123456789012345678901234567890')
123
- const evmProvider = EVM({ getWalletClient: vi.fn() })
124
- client.setProviders([evmProvider])
125
-
126
- const result = await getNameServiceAddress(
127
- client,
128
- 'test.name',
129
- 'SVM' as ChainType
130
- )
131
-
132
- expect(result).toBeUndefined()
133
- expect(mockResolveAddress).not.toHaveBeenCalled()
134
- })
135
- })
136
-
137
- describe('error scenarios', () => {
138
- it('should handle mixed success and failure scenarios', async () => {
139
- const mockResolveAddress1 = vi
140
- .fn()
141
- .mockRejectedValue(new Error('Provider 1 failed'))
142
- const mockResolveAddress2 = vi
143
- .fn()
144
- .mockResolvedValue('0x2222222222222222222222222222222222222222')
145
- const mockResolveAddress3 = vi.fn().mockResolvedValue(undefined)
146
-
147
- const provider1 = EVM({ getWalletClient: vi.fn() })
148
- const provider2 = Solana({ getWalletAdapter: vi.fn() })
149
- const provider3 = UTXO({ getWalletClient: vi.fn() })
150
-
151
- vi.spyOn(provider1, 'resolveAddress').mockImplementation(
152
- mockResolveAddress1
153
- )
154
- vi.spyOn(provider2, 'resolveAddress').mockImplementation(
155
- mockResolveAddress2
156
- )
157
- vi.spyOn(provider3, 'resolveAddress').mockImplementation(
158
- mockResolveAddress3
159
- )
160
-
161
- client.setProviders([provider1, provider2, provider3])
162
-
163
- const result = await getNameServiceAddress(client, 'test.name')
164
-
165
- // Should return the first successful result (provider2)
166
- expect(result).toBe('0x2222222222222222222222222222222222222222')
167
- })
168
- })
169
- })
@@ -1,18 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import { client } from './actions.unit.handlers.js'
3
- import { getQuote } from './getQuote.js'
4
-
5
- describe('ApiService Integration Tests', () => {
6
- it('should successfully request a quote', async () => {
7
- const quote = await getQuote(client, {
8
- fromChain: '1',
9
- fromToken: '0x0000000000000000000000000000000000000000',
10
- fromAddress: '0x552008c0f6870c2f77e5cC1d2eb9bdff03e30Ea0',
11
- fromAmount: '1000000000000000000',
12
- toChain: '137',
13
- toToken: '0x0000000000000000000000000000000000000000',
14
- // allowBridges: ['hop', 'multichain'],
15
- })
16
- expect(quote).toBeDefined()
17
- }, 100000)
18
- })
@@ -1,154 +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 { getQuote } from './getQuote.js'
8
-
9
- const mockedFetch = vi.spyOn(request, 'request')
10
-
11
- describe('getQuote', () => {
12
- setupTestServer()
13
-
14
- const fromChain = ChainId.DAI
15
- const fromToken = 'DAI'
16
- const fromAddress = 'Some wallet address'
17
- const fromAmount = '1000'
18
- const toChain = ChainId.POL
19
- const toToken = 'MATIC'
20
- const toAmount = '1000'
21
-
22
- describe('user input is invalid', () => {
23
- it('throw an error', async () => {
24
- await expect(
25
- getQuote(client, {
26
- fromChain: undefined as unknown as ChainId,
27
- fromToken,
28
- fromAddress,
29
- fromAmount,
30
- toChain,
31
- toToken,
32
- })
33
- ).rejects.toThrowError(
34
- new SDKError(
35
- new ValidationError('Required parameter "fromChain" is missing.')
36
- )
37
- )
38
-
39
- await expect(
40
- getQuote(client, {
41
- fromChain,
42
- fromToken: undefined as unknown as string,
43
- fromAddress,
44
- fromAmount,
45
- toChain,
46
- toToken,
47
- })
48
- ).rejects.toThrowError(
49
- new SDKError(
50
- new ValidationError('Required parameter "fromToken" is missing.')
51
- )
52
- )
53
-
54
- await expect(
55
- getQuote(client, {
56
- fromChain,
57
- fromToken,
58
- fromAddress: undefined as unknown as string,
59
- fromAmount,
60
- toChain,
61
- toToken,
62
- })
63
- ).rejects.toThrowError(
64
- new SDKError(
65
- new ValidationError('Required parameter "fromAddress" is missing.')
66
- )
67
- )
68
-
69
- await expect(
70
- getQuote(client, {
71
- fromChain,
72
- fromToken,
73
- fromAddress,
74
- fromAmount: undefined as unknown as string,
75
- toChain,
76
- toToken,
77
- })
78
- ).rejects.toThrowError(
79
- new SDKError(
80
- new ValidationError(
81
- 'Required parameter "fromAmount" or "toAmount" is missing.'
82
- )
83
- )
84
- )
85
-
86
- await expect(
87
- getQuote(client, {
88
- fromChain,
89
- fromToken,
90
- fromAddress,
91
- fromAmount,
92
- toChain,
93
- toToken,
94
- toAmount,
95
- } as any)
96
- ).rejects.toThrowError(
97
- new SDKError(
98
- new ValidationError(
99
- 'Cannot provide both "fromAmount" and "toAmount" parameters.'
100
- )
101
- )
102
- )
103
-
104
- await expect(
105
- getQuote(client, {
106
- fromChain,
107
- fromToken,
108
- fromAddress,
109
- fromAmount,
110
- toChain: undefined as unknown as ChainId,
111
- toToken,
112
- })
113
- ).rejects.toThrowError(
114
- new SDKError(
115
- new ValidationError('Required parameter "toChain" is missing.')
116
- )
117
- )
118
-
119
- await expect(
120
- getQuote(client, {
121
- fromChain,
122
- fromToken,
123
- fromAddress,
124
- fromAmount,
125
- toChain,
126
- toToken: undefined as unknown as string,
127
- })
128
- ).rejects.toThrowError(
129
- new SDKError(
130
- new ValidationError('Required parameter "toToken" is missing.')
131
- )
132
- )
133
-
134
- expect(mockedFetch).toHaveBeenCalledTimes(0)
135
- })
136
- })
137
-
138
- describe('user input is valid', () => {
139
- describe('and the backend call is successful', () => {
140
- it('call the server once', async () => {
141
- await getQuote(client, {
142
- fromChain,
143
- fromToken,
144
- fromAddress,
145
- fromAmount,
146
- toChain,
147
- toToken,
148
- })
149
-
150
- expect(mockedFetch).toHaveBeenCalledTimes(1)
151
- })
152
- })
153
- })
154
- })
@@ -1,243 +0,0 @@
1
- import type {
2
- RelayStatusRequest,
3
- RelayStatusResponse,
4
- RelayStatusResponseData,
5
- RequestOptions,
6
- } from '@lifi/types'
7
- import { HttpResponse, http } from 'msw'
8
- import { describe, expect, it } from 'vitest'
9
- import { BaseError } from '../errors/baseError.js'
10
- import { ErrorName } from '../errors/constants.js'
11
- import { ValidationError } from '../errors/errors.js'
12
- import { SDKError } from '../errors/SDKError.js'
13
- import { client, setupTestServer } from './actions.unit.handlers.js'
14
- import { getRelayedTransactionStatus } from './getRelayedTransactionStatus.js'
15
-
16
- describe('getRelayedTransactionStatus', () => {
17
- const server = setupTestServer()
18
-
19
- const createMockRelayStatusRequest = (
20
- overrides: Partial<RelayStatusRequest> = {}
21
- ): RelayStatusRequest => ({
22
- taskId:
23
- '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
24
- ...overrides,
25
- })
26
-
27
- const mockStatusResponseData: RelayStatusResponseData = {
28
- status: 'PENDING',
29
- metadata: {
30
- chainId: 1,
31
- },
32
- }
33
-
34
- const mockSuccessResponse: RelayStatusResponse = {
35
- status: 'ok',
36
- data: mockStatusResponseData,
37
- }
38
-
39
- const mockErrorResponse: RelayStatusResponse = {
40
- status: 'error',
41
- data: {
42
- code: 404,
43
- message: 'Task not found',
44
- },
45
- }
46
-
47
- describe('success scenarios', () => {
48
- it('should get relayed transaction status successfully', async () => {
49
- server.use(
50
- http.get(
51
- `${client.config.apiUrl}/relayer/status/0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef`,
52
- async () => {
53
- return HttpResponse.json(mockSuccessResponse)
54
- }
55
- )
56
- )
57
-
58
- const request = createMockRelayStatusRequest()
59
-
60
- const result = await getRelayedTransactionStatus(client, request)
61
-
62
- expect(result).toEqual(mockStatusResponseData)
63
- })
64
-
65
- it('should pass request options correctly', async () => {
66
- const mockAbortController = new AbortController()
67
- const options: RequestOptions = {
68
- signal: mockAbortController.signal,
69
- }
70
-
71
- let capturedOptions: any
72
- server.use(
73
- http.get(
74
- `${client.config.apiUrl}/relayer/status/0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef`,
75
- async ({ request }) => {
76
- capturedOptions = request
77
- return HttpResponse.json(mockSuccessResponse)
78
- }
79
- )
80
- )
81
-
82
- const request = createMockRelayStatusRequest()
83
-
84
- await getRelayedTransactionStatus(client, request, options)
85
-
86
- expect(capturedOptions.signal).toBeDefined()
87
- expect(capturedOptions.signal).toBeInstanceOf(AbortSignal)
88
- })
89
-
90
- it('should handle different task statuses', async () => {
91
- const pendingResponse = {
92
- ...mockSuccessResponse,
93
- data: { ...mockStatusResponseData, status: 'PENDING' },
94
- }
95
- const completedResponse = {
96
- ...mockSuccessResponse,
97
- data: { ...mockStatusResponseData, status: 'COMPLETED' },
98
- }
99
- const failedResponse = {
100
- ...mockSuccessResponse,
101
- data: { ...mockStatusResponseData, status: 'FAILED' },
102
- }
103
-
104
- // Test PENDING status
105
- server.use(
106
- http.get(
107
- `${client.config.apiUrl}/relayer/status/0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef`,
108
- async () => {
109
- return HttpResponse.json(pendingResponse)
110
- }
111
- )
112
- )
113
-
114
- let result = await getRelayedTransactionStatus(
115
- client,
116
- createMockRelayStatusRequest()
117
- )
118
- expect(result.status).toBe('PENDING')
119
-
120
- // Test COMPLETED status
121
- server.resetHandlers()
122
- server.use(
123
- http.get(
124
- `${client.config.apiUrl}/relayer/status/0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef`,
125
- async () => {
126
- return HttpResponse.json(completedResponse)
127
- }
128
- )
129
- )
130
-
131
- result = await getRelayedTransactionStatus(
132
- client,
133
- createMockRelayStatusRequest()
134
- )
135
- expect(result.status).toBe('COMPLETED')
136
-
137
- // Test FAILED status
138
- server.resetHandlers()
139
- server.use(
140
- http.get(
141
- `${client.config.apiUrl}/relayer/status/0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef`,
142
- async () => {
143
- return HttpResponse.json(failedResponse)
144
- }
145
- )
146
- )
147
-
148
- result = await getRelayedTransactionStatus(
149
- client,
150
- createMockRelayStatusRequest()
151
- )
152
- expect(result.status).toBe('FAILED')
153
- })
154
- })
155
-
156
- describe('validation scenarios', () => {
157
- it('should throw SDKError when taskId is missing', async () => {
158
- const invalidRequest = createMockRelayStatusRequest({
159
- taskId: undefined as any,
160
- })
161
-
162
- await expect(
163
- getRelayedTransactionStatus(client, invalidRequest)
164
- ).rejects.toThrow(SDKError)
165
-
166
- try {
167
- await getRelayedTransactionStatus(client, invalidRequest)
168
- } catch (error) {
169
- expect(error).toBeInstanceOf(SDKError)
170
- expect((error as SDKError).cause).toBeInstanceOf(ValidationError)
171
- expect((error as SDKError).cause.message).toBe(
172
- 'Required parameter "taskId" is missing.'
173
- )
174
- }
175
- })
176
- })
177
-
178
- describe('error scenarios', () => {
179
- it('should throw BaseError when server returns error status', async () => {
180
- server.use(
181
- http.get(
182
- `${client.config.apiUrl}/relayer/status/0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef`,
183
- async () => {
184
- return HttpResponse.json(mockErrorResponse)
185
- }
186
- )
187
- )
188
-
189
- const request = createMockRelayStatusRequest()
190
-
191
- await expect(
192
- getRelayedTransactionStatus(client, request)
193
- ).rejects.toThrow(BaseError)
194
-
195
- try {
196
- await getRelayedTransactionStatus(client, request)
197
- } catch (error) {
198
- expect(error).toBeInstanceOf(BaseError)
199
- expect((error as BaseError).name).toBe(ErrorName.ServerError)
200
- expect((error as BaseError).code).toBe(404)
201
- expect((error as BaseError).message).toBe('Task not found')
202
- }
203
- })
204
-
205
- it('should throw SDKError when network request fails', async () => {
206
- server.use(
207
- http.get(
208
- `${client.config.apiUrl}/relayer/status/0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef`,
209
- async () => {
210
- return HttpResponse.error()
211
- }
212
- )
213
- )
214
-
215
- const request = createMockRelayStatusRequest()
216
-
217
- await expect(
218
- getRelayedTransactionStatus(client, request)
219
- ).rejects.toThrow(SDKError)
220
- })
221
-
222
- it('should throw SDKError when request times out', async () => {
223
- server.use(
224
- http.get(
225
- `${client.config.apiUrl}/relayer/status/0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef`,
226
- async () => {
227
- // Simulate timeout by not responding
228
- await new Promise(() => {}) // Never resolves
229
- }
230
- )
231
- )
232
-
233
- const request = createMockRelayStatusRequest()
234
- const timeoutOptions: RequestOptions = {
235
- signal: AbortSignal.timeout(100), // 100ms timeout
236
- }
237
-
238
- await expect(
239
- getRelayedTransactionStatus(client, request, timeoutOptions)
240
- ).rejects.toThrow()
241
- })
242
- })
243
- })