@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
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
|
-
})
|