@portal-hq/web 3.5.2 → 3.6.0-alpha
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/lib/commonjs/index.js +11 -1
- package/lib/commonjs/integrations/trading/index.js +18 -0
- package/lib/commonjs/integrations/trading/lifi/index.js +65 -0
- package/lib/commonjs/integrations/trading/lifi/index.test.js +93 -0
- package/lib/commonjs/integrations/trading/zero-x/index.js +44 -0
- package/lib/commonjs/integrations/trading/zero-x/index.test.js +65 -0
- package/lib/commonjs/mpc/index.js +41 -1
- package/lib/commonjs/mpc/index.test.js +260 -0
- package/lib/esm/index.js +9 -0
- package/lib/esm/integrations/trading/index.js +12 -0
- package/lib/esm/integrations/trading/lifi/index.js +62 -0
- package/lib/esm/integrations/trading/lifi/index.test.js +88 -0
- package/lib/esm/integrations/trading/zero-x/index.js +41 -0
- package/lib/esm/integrations/trading/zero-x/index.test.js +60 -0
- package/lib/esm/mpc/index.js +41 -1
- package/lib/esm/mpc/index.test.js +261 -1
- package/package.json +3 -2
- package/src/__mocks/constants.ts +216 -0
- package/src/index.ts +13 -0
- package/src/integrations/trading/index.ts +17 -0
- package/src/integrations/trading/lifi/index.test.ts +122 -0
- package/src/integrations/trading/lifi/index.ts +61 -0
- package/src/integrations/trading/zero-x/index.test.ts +75 -0
- package/src/integrations/trading/zero-x/index.ts +40 -0
- package/src/mpc/index.test.ts +312 -0
- package/src/mpc/index.ts +56 -2
- package/tsconfig.json +1 -1
- package/types.d.ts +1 -1
package/src/__mocks/constants.ts
CHANGED
|
@@ -737,6 +737,21 @@ export const mockSourcesRes = {
|
|
|
737
737
|
Uniswap_V3: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
|
|
738
738
|
}
|
|
739
739
|
|
|
740
|
+
export const mockZeroXQuoteResponse = {
|
|
741
|
+
allowanceTarget: '0x1234567890123456789012345678901234567890',
|
|
742
|
+
cost: '1000000000000000',
|
|
743
|
+
transaction: {
|
|
744
|
+
from: '0x67aD8DCb5a4e8d6711C87D553C9325c3e85A1Da6',
|
|
745
|
+
to: '0x1234567890123456789012345678901234567890',
|
|
746
|
+
data: '0xabcdef',
|
|
747
|
+
gasLimit: '21000',
|
|
748
|
+
maxFeePerGas: '2000000000',
|
|
749
|
+
maxPriorityFeePerGas: '1000000000',
|
|
750
|
+
nonce: '1',
|
|
751
|
+
value: '1000000000000000000',
|
|
752
|
+
},
|
|
753
|
+
}
|
|
754
|
+
|
|
740
755
|
export const mockOrganizationShare = 'test-org-share'
|
|
741
756
|
export const mockDecryptedData = JSON.stringify({
|
|
742
757
|
[PortalCurve.SECP256K1]: {
|
|
@@ -1096,3 +1111,204 @@ export const mockYieldXyzGetTransactionResponse = {
|
|
|
1096
1111
|
transactionId: 'test-tx-id',
|
|
1097
1112
|
},
|
|
1098
1113
|
}
|
|
1114
|
+
|
|
1115
|
+
// LiFi mock data
|
|
1116
|
+
export const mockLifiToken = {
|
|
1117
|
+
address: '0x0000000000000000000000000000000000000000',
|
|
1118
|
+
symbol: 'ETH',
|
|
1119
|
+
decimals: 18,
|
|
1120
|
+
chainId: 'eip155:8453',
|
|
1121
|
+
name: 'Ethereum',
|
|
1122
|
+
logoURI: 'https://example.com/eth.png',
|
|
1123
|
+
priceUSD: '3000',
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
export const mockLifiToToken = {
|
|
1127
|
+
address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
1128
|
+
symbol: 'USDC',
|
|
1129
|
+
decimals: 6,
|
|
1130
|
+
chainId: 'eip155:42161',
|
|
1131
|
+
name: 'USD Coin',
|
|
1132
|
+
logoURI: 'https://example.com/usdc.png',
|
|
1133
|
+
priceUSD: '1',
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
export const mockLifiAction = {
|
|
1137
|
+
fromChainId: 'eip155:8453',
|
|
1138
|
+
fromAmount: '1000000000000',
|
|
1139
|
+
fromToken: mockLifiToken,
|
|
1140
|
+
toChainId: 'eip155:42161',
|
|
1141
|
+
toToken: mockLifiToToken,
|
|
1142
|
+
slippage: 0.005,
|
|
1143
|
+
fromAddress: mockEip155Address,
|
|
1144
|
+
toAddress: mockEip155Address,
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
export const mockLifiEstimate = {
|
|
1148
|
+
tool: 'relay',
|
|
1149
|
+
fromAmount: '1000000000000',
|
|
1150
|
+
toAmount: '2990000000',
|
|
1151
|
+
toAmountMin: '2975050000',
|
|
1152
|
+
approvalAddress: '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE',
|
|
1153
|
+
executionDuration: 120,
|
|
1154
|
+
fromAmountUSD: '3000',
|
|
1155
|
+
toAmountUSD: '2990',
|
|
1156
|
+
feeCosts: [],
|
|
1157
|
+
gasCosts: [
|
|
1158
|
+
{
|
|
1159
|
+
type: 'SEND' as const,
|
|
1160
|
+
amount: '21000000000000',
|
|
1161
|
+
token: mockLifiToken,
|
|
1162
|
+
estimate: '21000',
|
|
1163
|
+
limit: '25000',
|
|
1164
|
+
amountUSD: '0.063',
|
|
1165
|
+
},
|
|
1166
|
+
],
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
export const mockLifiStep = {
|
|
1170
|
+
id: 'test-step-id',
|
|
1171
|
+
type: 'cross' as const,
|
|
1172
|
+
tool: 'relay',
|
|
1173
|
+
action: mockLifiAction,
|
|
1174
|
+
toolDetails: {
|
|
1175
|
+
key: 'relay',
|
|
1176
|
+
name: 'Relay',
|
|
1177
|
+
logoURI: 'https://example.com/relay.png',
|
|
1178
|
+
},
|
|
1179
|
+
estimate: mockLifiEstimate,
|
|
1180
|
+
integrator: 'portal',
|
|
1181
|
+
transactionRequest: {
|
|
1182
|
+
to: '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE',
|
|
1183
|
+
from: mockEip155Address,
|
|
1184
|
+
data: '0x123456',
|
|
1185
|
+
value: '0x0de0b6b3a7640000',
|
|
1186
|
+
gasLimit: '0x61a8',
|
|
1187
|
+
chainId: 'eip155:1',
|
|
1188
|
+
},
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
export const mockLifiRoute = {
|
|
1192
|
+
id: 'test-route-id',
|
|
1193
|
+
fromChainId: 'eip155:8453',
|
|
1194
|
+
fromAmountUSD: '3000',
|
|
1195
|
+
fromAmount: '1000000000000',
|
|
1196
|
+
fromToken: mockLifiToken,
|
|
1197
|
+
toChainId: 'eip155:42161',
|
|
1198
|
+
toAmountUSD: '2990',
|
|
1199
|
+
toAmount: '2990000000',
|
|
1200
|
+
toAmountMin: '2975050000',
|
|
1201
|
+
toToken: mockLifiToToken,
|
|
1202
|
+
steps: [mockLifiStep],
|
|
1203
|
+
gasCostUSD: '0.063',
|
|
1204
|
+
fromAddress: mockEip155Address,
|
|
1205
|
+
toAddress: mockEip155Address,
|
|
1206
|
+
tags: ['RECOMMENDED', 'FASTEST'],
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
export const mockLifiGetRoutesRequest = {
|
|
1210
|
+
fromChainId: 'eip155:8453',
|
|
1211
|
+
fromAmount: '1000000000000',
|
|
1212
|
+
fromTokenAddress: 'ETH',
|
|
1213
|
+
toChainId: 'eip155:42161',
|
|
1214
|
+
toTokenAddress: 'USDC',
|
|
1215
|
+
fromAddress: mockEip155Address,
|
|
1216
|
+
toAddress: mockEip155Address,
|
|
1217
|
+
options: {
|
|
1218
|
+
slippage: 0.005,
|
|
1219
|
+
integrator: 'portal',
|
|
1220
|
+
},
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
export const mockLifiGetRoutesResponse = {
|
|
1224
|
+
data: {
|
|
1225
|
+
rawResponse: {
|
|
1226
|
+
routes: [mockLifiRoute],
|
|
1227
|
+
unavailableRoutes: {
|
|
1228
|
+
filteredOut: [],
|
|
1229
|
+
failed: [],
|
|
1230
|
+
},
|
|
1231
|
+
},
|
|
1232
|
+
},
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
export const mockLifiGetQuoteRequest = {
|
|
1236
|
+
fromChain: 'eip155:8453',
|
|
1237
|
+
toChain: 'eip155:42161',
|
|
1238
|
+
fromToken: 'ETH',
|
|
1239
|
+
toToken: 'USDC',
|
|
1240
|
+
fromAddress: mockEip155Address,
|
|
1241
|
+
fromAmount: '1000000000000',
|
|
1242
|
+
toAddress: mockEip155Address,
|
|
1243
|
+
order: 'FASTEST' as const,
|
|
1244
|
+
slippage: 0.005,
|
|
1245
|
+
integrator: 'portal',
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
export const mockLifiGetQuoteResponse = {
|
|
1249
|
+
data: {
|
|
1250
|
+
rawResponse: mockLifiStep,
|
|
1251
|
+
},
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
export const mockLifiGetStatusRequest = {
|
|
1255
|
+
txHash: '0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890',
|
|
1256
|
+
bridge: 'relay' as const,
|
|
1257
|
+
fromChain: '1',
|
|
1258
|
+
toChain: '137',
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
export const mockLifiGetStatusResponse = {
|
|
1262
|
+
data: {
|
|
1263
|
+
rawResponse: {
|
|
1264
|
+
sending: {
|
|
1265
|
+
txHash:
|
|
1266
|
+
'0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890',
|
|
1267
|
+
txLink:
|
|
1268
|
+
'https://etherscan.io/tx/0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890',
|
|
1269
|
+
amount: '1000000000000000000',
|
|
1270
|
+
token: mockLifiToken,
|
|
1271
|
+
chainId: '1',
|
|
1272
|
+
gasAmount: '21000000000000',
|
|
1273
|
+
gasAmountUSD: '0.063',
|
|
1274
|
+
timestamp: 1704067200,
|
|
1275
|
+
},
|
|
1276
|
+
receiving: {
|
|
1277
|
+
chainId: '137',
|
|
1278
|
+
txHash:
|
|
1279
|
+
'0x0987654321fedcba0987654321fedcba0987654321fedcba0987654321fedcba',
|
|
1280
|
+
txLink:
|
|
1281
|
+
'https://polygonscan.com/tx/0x0987654321fedcba0987654321fedcba0987654321fedcba0987654321fedcba',
|
|
1282
|
+
token: mockLifiToToken,
|
|
1283
|
+
amount: '2990000000',
|
|
1284
|
+
timestamp: 1704067320,
|
|
1285
|
+
},
|
|
1286
|
+
status: 'DONE' as const,
|
|
1287
|
+
substatus: 'COMPLETED' as const,
|
|
1288
|
+
substatusMessage: 'Transfer completed successfully',
|
|
1289
|
+
tool: 'relay',
|
|
1290
|
+
transactionId: 'test-lifi-tx-id',
|
|
1291
|
+
fromAddress: mockEip155Address,
|
|
1292
|
+
toAddress: mockEip155Address,
|
|
1293
|
+
lifiExplorerLink: 'https://explorer.li.fi/tx/test-lifi-tx-id',
|
|
1294
|
+
},
|
|
1295
|
+
},
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
export const mockLifiGetRouteStepRequest = mockLifiStep
|
|
1299
|
+
|
|
1300
|
+
export const mockLifiGetRouteStepResponse = {
|
|
1301
|
+
data: {
|
|
1302
|
+
rawResponse: {
|
|
1303
|
+
...mockLifiStep,
|
|
1304
|
+
transactionRequest: {
|
|
1305
|
+
to: '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE',
|
|
1306
|
+
from: mockEip155Address,
|
|
1307
|
+
data: '0x123456789abcdef',
|
|
1308
|
+
value: '0x0de0b6b3a7640000',
|
|
1309
|
+
gasLimit: '0x61a8',
|
|
1310
|
+
chainId: 'eip155:1',
|
|
1311
|
+
},
|
|
1312
|
+
},
|
|
1313
|
+
},
|
|
1314
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
import Mpc from './mpc'
|
|
45
45
|
import Provider, { RequestMethod } from './provider'
|
|
46
46
|
import Yield from './integrations/yield'
|
|
47
|
+
import Trading from './integrations/trading'
|
|
47
48
|
|
|
48
49
|
class Portal {
|
|
49
50
|
public address?: string
|
|
@@ -56,6 +57,7 @@ class Portal {
|
|
|
56
57
|
public host: string
|
|
57
58
|
public mpc: Mpc
|
|
58
59
|
public yield: Yield
|
|
60
|
+
public trading: Trading
|
|
59
61
|
public mpcHost: string
|
|
60
62
|
public mpcVersion: string
|
|
61
63
|
public provider: Provider
|
|
@@ -109,6 +111,8 @@ class Portal {
|
|
|
109
111
|
|
|
110
112
|
this.yield = new Yield({ mpc: this.mpc })
|
|
111
113
|
|
|
114
|
+
this.trading = new Trading({ mpc: this.mpc })
|
|
115
|
+
|
|
112
116
|
this.provider = new Provider({
|
|
113
117
|
portal: this,
|
|
114
118
|
chainId: chainId ? Number(chainId) : undefined,
|
|
@@ -887,6 +891,9 @@ class Portal {
|
|
|
887
891
|
* Swaps Methods
|
|
888
892
|
*******************************/
|
|
889
893
|
|
|
894
|
+
/**
|
|
895
|
+
* @deprecated This method is deprecated. Use `portal.trading.zeroX.getQuote` instead.
|
|
896
|
+
*/
|
|
890
897
|
public async getQuote(
|
|
891
898
|
apiKey: string,
|
|
892
899
|
args: QuoteArgs,
|
|
@@ -895,6 +902,9 @@ class Portal {
|
|
|
895
902
|
return this.mpc?.getQuote(apiKey, args, chainId)
|
|
896
903
|
}
|
|
897
904
|
|
|
905
|
+
/**
|
|
906
|
+
* @deprecated This method is deprecated. Use `portal.trading.zeroX.getSources` instead.
|
|
907
|
+
*/
|
|
898
908
|
public async getSources(
|
|
899
909
|
apiKey: string,
|
|
900
910
|
chainId: string,
|
|
@@ -1042,6 +1052,9 @@ export {
|
|
|
1042
1052
|
} from '../yieldxyz-types'
|
|
1043
1053
|
|
|
1044
1054
|
export { MpcError, MpcErrorCodes } from './mpc'
|
|
1055
|
+
|
|
1056
|
+
export { PortalMpcError } from './mpc/errors'
|
|
1057
|
+
|
|
1045
1058
|
export {
|
|
1046
1059
|
type Address,
|
|
1047
1060
|
type Dapp,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import Mpc from '../../mpc'
|
|
2
|
+
import ZeroX from './zero-x'
|
|
3
|
+
import LiFi from './lifi'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* This class is a container for the LiFi class.
|
|
7
|
+
* In the future, Trading domain logic should be here.
|
|
8
|
+
*/
|
|
9
|
+
export default class Trading {
|
|
10
|
+
public lifi: LiFi
|
|
11
|
+
public zeroX: ZeroX
|
|
12
|
+
|
|
13
|
+
constructor({ mpc }: { mpc: Mpc }) {
|
|
14
|
+
this.lifi = new LiFi({ mpc })
|
|
15
|
+
this.zeroX = new ZeroX({ mpc })
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import LiFi from '.'
|
|
6
|
+
import Mpc from '../../../mpc'
|
|
7
|
+
import portalMock from '../../../__mocks/portal/portal'
|
|
8
|
+
import {
|
|
9
|
+
mockHost,
|
|
10
|
+
mockLifiGetRoutesRequest,
|
|
11
|
+
mockLifiGetRoutesResponse,
|
|
12
|
+
mockLifiGetQuoteRequest,
|
|
13
|
+
mockLifiGetQuoteResponse,
|
|
14
|
+
mockLifiGetStatusRequest,
|
|
15
|
+
mockLifiGetStatusResponse,
|
|
16
|
+
mockLifiGetRouteStepRequest,
|
|
17
|
+
mockLifiGetRouteStepResponse,
|
|
18
|
+
} from '../../../__mocks/constants'
|
|
19
|
+
|
|
20
|
+
describe('LiFi', () => {
|
|
21
|
+
let lifi: LiFi
|
|
22
|
+
let mpc: Mpc
|
|
23
|
+
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
jest.clearAllMocks()
|
|
26
|
+
|
|
27
|
+
portalMock.host = mockHost
|
|
28
|
+
mpc = new Mpc({
|
|
29
|
+
portal: portalMock,
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
lifi = new LiFi({ mpc })
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
describe('getRoutes', () => {
|
|
36
|
+
it('should call mpc.getLifiRoutes with the correct arguments', async () => {
|
|
37
|
+
const spy = jest
|
|
38
|
+
.spyOn(mpc, 'getLifiRoutes')
|
|
39
|
+
.mockResolvedValue(mockLifiGetRoutesResponse)
|
|
40
|
+
|
|
41
|
+
const result = await lifi.getRoutes(mockLifiGetRoutesRequest)
|
|
42
|
+
|
|
43
|
+
expect(spy).toHaveBeenCalledWith(mockLifiGetRoutesRequest)
|
|
44
|
+
expect(result).toEqual(mockLifiGetRoutesResponse)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('should propagate errors from mpc.getLifiRoutes', async () => {
|
|
48
|
+
const error = new Error('Test error')
|
|
49
|
+
jest.spyOn(mpc, 'getLifiRoutes').mockRejectedValue(error)
|
|
50
|
+
|
|
51
|
+
await expect(lifi.getRoutes(mockLifiGetRoutesRequest)).rejects.toThrow(
|
|
52
|
+
'Test error',
|
|
53
|
+
)
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
describe('getQuote', () => {
|
|
58
|
+
it('should call mpc.getLifiQuote with the correct arguments', async () => {
|
|
59
|
+
const spy = jest
|
|
60
|
+
.spyOn(mpc, 'getLifiQuote')
|
|
61
|
+
.mockResolvedValue(mockLifiGetQuoteResponse)
|
|
62
|
+
|
|
63
|
+
const result = await lifi.getQuote(mockLifiGetQuoteRequest)
|
|
64
|
+
|
|
65
|
+
expect(spy).toHaveBeenCalledWith(mockLifiGetQuoteRequest)
|
|
66
|
+
expect(result).toEqual(mockLifiGetQuoteResponse)
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('should propagate errors from mpc.getLifiQuote', async () => {
|
|
70
|
+
const error = new Error('Test error')
|
|
71
|
+
jest.spyOn(mpc, 'getLifiQuote').mockRejectedValue(error)
|
|
72
|
+
|
|
73
|
+
await expect(lifi.getQuote(mockLifiGetQuoteRequest)).rejects.toThrow(
|
|
74
|
+
'Test error',
|
|
75
|
+
)
|
|
76
|
+
})
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
describe('getStatus', () => {
|
|
80
|
+
it('should call mpc.getLifiStatus with the correct arguments', async () => {
|
|
81
|
+
const spy = jest
|
|
82
|
+
.spyOn(mpc, 'getLifiStatus')
|
|
83
|
+
.mockResolvedValue(mockLifiGetStatusResponse)
|
|
84
|
+
|
|
85
|
+
const result = await lifi.getStatus(mockLifiGetStatusRequest)
|
|
86
|
+
|
|
87
|
+
expect(spy).toHaveBeenCalledWith(mockLifiGetStatusRequest)
|
|
88
|
+
expect(result).toEqual(mockLifiGetStatusResponse)
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it('should propagate errors from mpc.getLifiStatus', async () => {
|
|
92
|
+
const error = new Error('Test error')
|
|
93
|
+
jest.spyOn(mpc, 'getLifiStatus').mockRejectedValue(error)
|
|
94
|
+
|
|
95
|
+
await expect(lifi.getStatus(mockLifiGetStatusRequest)).rejects.toThrow(
|
|
96
|
+
'Test error',
|
|
97
|
+
)
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
describe('getRouteStep', () => {
|
|
102
|
+
it('should call mpc.getLifiRouteStep with the correct arguments', async () => {
|
|
103
|
+
const spy = jest
|
|
104
|
+
.spyOn(mpc, 'getLifiRouteStep')
|
|
105
|
+
.mockResolvedValue(mockLifiGetRouteStepResponse)
|
|
106
|
+
|
|
107
|
+
const result = await lifi.getRouteStep(mockLifiGetRouteStepRequest)
|
|
108
|
+
|
|
109
|
+
expect(spy).toHaveBeenCalledWith(mockLifiGetRouteStepRequest)
|
|
110
|
+
expect(result).toEqual(mockLifiGetRouteStepResponse)
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
it('should propagate errors from mpc.getLifiRouteStep', async () => {
|
|
114
|
+
const error = new Error('Test error')
|
|
115
|
+
jest.spyOn(mpc, 'getLifiRouteStep').mockRejectedValue(error)
|
|
116
|
+
|
|
117
|
+
await expect(
|
|
118
|
+
lifi.getRouteStep(mockLifiGetRouteStepRequest),
|
|
119
|
+
).rejects.toThrow('Test error')
|
|
120
|
+
})
|
|
121
|
+
})
|
|
122
|
+
})
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import Mpc from '../../../mpc'
|
|
2
|
+
import {
|
|
3
|
+
LifiQuoteRequest,
|
|
4
|
+
LifiQuoteResponse,
|
|
5
|
+
LifiRoutesRequest,
|
|
6
|
+
LifiRoutesResponse,
|
|
7
|
+
LifiStatusRequest,
|
|
8
|
+
LifiStatusResponse,
|
|
9
|
+
LifiStepTransactionRequest,
|
|
10
|
+
LifiStepTransactionResponse,
|
|
11
|
+
} from '../../../../lifi-types'
|
|
12
|
+
|
|
13
|
+
export default class LiFi {
|
|
14
|
+
private mpc: Mpc
|
|
15
|
+
|
|
16
|
+
constructor({ mpc }: { mpc: Mpc }) {
|
|
17
|
+
this.mpc = mpc
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Retrieves routes from the Li.Fi integration.
|
|
22
|
+
* @param data - The parameters for the routes request.
|
|
23
|
+
* @returns A `LifiRoutesResponse` promise.
|
|
24
|
+
* @throws An error if the operation fails.
|
|
25
|
+
*/
|
|
26
|
+
public async getRoutes(data: LifiRoutesRequest): Promise<LifiRoutesResponse> {
|
|
27
|
+
return this.mpc?.getLifiRoutes(data)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Retrieves a quote from the Li.Fi integration.
|
|
32
|
+
* @param data - The parameters for the quote request.
|
|
33
|
+
* @returns A `LifiQuoteResponse` promise.
|
|
34
|
+
* @throws An error if the operation fails.
|
|
35
|
+
*/
|
|
36
|
+
public async getQuote(data: LifiQuoteRequest): Promise<LifiQuoteResponse> {
|
|
37
|
+
return this.mpc?.getLifiQuote(data)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Retrieves the status of a transaction from the Li.Fi integration.
|
|
42
|
+
* @param data - The parameters for the status request.
|
|
43
|
+
* @returns A `LifiStatusResponse` promise.
|
|
44
|
+
* @throws An error if the operation fails.
|
|
45
|
+
*/
|
|
46
|
+
public async getStatus(data: LifiStatusRequest): Promise<LifiStatusResponse> {
|
|
47
|
+
return this.mpc?.getLifiStatus(data)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Retrieves an unsigned transaction from the Li.Fi integration that has yet to be signed/submitted.
|
|
52
|
+
* @param data - The step transaction request containing the step details.
|
|
53
|
+
* @returns A `LifiStepTransactionResponse` promise.
|
|
54
|
+
* @throws An error if the operation fails.
|
|
55
|
+
*/
|
|
56
|
+
public async getRouteStep(
|
|
57
|
+
data: LifiStepTransactionRequest,
|
|
58
|
+
): Promise<LifiStepTransactionResponse> {
|
|
59
|
+
return this.mpc?.getLifiRouteStep(data)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import ZeroX from '.'
|
|
6
|
+
import Mpc from '../../../mpc'
|
|
7
|
+
import portalMock from '../../../__mocks/portal/portal'
|
|
8
|
+
import {
|
|
9
|
+
mockHost,
|
|
10
|
+
mockQuoteArgs,
|
|
11
|
+
mockSourcesRes,
|
|
12
|
+
mockZeroXQuoteResponse,
|
|
13
|
+
} from '../../../__mocks/constants'
|
|
14
|
+
|
|
15
|
+
describe('ZeroX', () => {
|
|
16
|
+
let zeroX: ZeroX
|
|
17
|
+
let mpc: Mpc
|
|
18
|
+
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
jest.clearAllMocks()
|
|
21
|
+
|
|
22
|
+
portalMock.host = mockHost
|
|
23
|
+
mpc = new Mpc({
|
|
24
|
+
portal: portalMock,
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
zeroX = new ZeroX({ mpc })
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
describe('getQuote', () => {
|
|
31
|
+
it('should correctly call mpc.getQuote', async () => {
|
|
32
|
+
const spy = jest
|
|
33
|
+
.spyOn(mpc, 'getQuote')
|
|
34
|
+
.mockResolvedValue(mockZeroXQuoteResponse)
|
|
35
|
+
|
|
36
|
+
const result = await zeroX.getQuote('test', mockQuoteArgs, 'eip155:1')
|
|
37
|
+
|
|
38
|
+
expect(spy).toHaveBeenCalledTimes(1)
|
|
39
|
+
expect(spy).toHaveBeenCalledWith('test', mockQuoteArgs, 'eip155:1')
|
|
40
|
+
expect(result).toEqual(mockZeroXQuoteResponse)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('should propagate errors from mpc.getQuote', async () => {
|
|
44
|
+
const error = new Error('Test error')
|
|
45
|
+
jest.spyOn(mpc, 'getQuote').mockRejectedValue(error)
|
|
46
|
+
|
|
47
|
+
await expect(
|
|
48
|
+
zeroX.getQuote('test', mockQuoteArgs, 'eip155:1'),
|
|
49
|
+
).rejects.toThrow('Test error')
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
describe('getSources', () => {
|
|
54
|
+
it('should correctly call mpc.getSources', async () => {
|
|
55
|
+
const spy = jest
|
|
56
|
+
.spyOn(mpc, 'getSources')
|
|
57
|
+
.mockResolvedValue(mockSourcesRes)
|
|
58
|
+
|
|
59
|
+
const result = await zeroX.getSources('test', 'eip155:1')
|
|
60
|
+
|
|
61
|
+
expect(spy).toHaveBeenCalledTimes(1)
|
|
62
|
+
expect(spy).toHaveBeenCalledWith('test', 'eip155:1')
|
|
63
|
+
expect(result).toEqual(mockSourcesRes)
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('should propagate errors from mpc.getSources', async () => {
|
|
67
|
+
const error = new Error('Test error')
|
|
68
|
+
jest.spyOn(mpc, 'getSources').mockRejectedValue(error)
|
|
69
|
+
|
|
70
|
+
await expect(zeroX.getSources('test', 'eip155:1')).rejects.toThrow(
|
|
71
|
+
'Test error',
|
|
72
|
+
)
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
})
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import Mpc from '../../../mpc'
|
|
2
|
+
import { QuoteArgs, QuoteResponse } from '../../../../types'
|
|
3
|
+
|
|
4
|
+
export default class ZeroX {
|
|
5
|
+
private mpc: Mpc
|
|
6
|
+
|
|
7
|
+
constructor({ mpc }: { mpc: Mpc }) {
|
|
8
|
+
this.mpc = mpc
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Get a quote from the Swaps API.
|
|
13
|
+
*
|
|
14
|
+
* @param apiKey - The API key for the Swaps API.
|
|
15
|
+
* @param args - The arguments for the quote.
|
|
16
|
+
* @param chainId - The chain ID for the quote.
|
|
17
|
+
* @returns The quote response.
|
|
18
|
+
*/
|
|
19
|
+
public async getQuote(
|
|
20
|
+
apiKey: string,
|
|
21
|
+
args: QuoteArgs,
|
|
22
|
+
chainId: string,
|
|
23
|
+
): Promise<QuoteResponse> {
|
|
24
|
+
return this.mpc?.getQuote(apiKey, args, chainId)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get the valid, swappable token sources that can be used with your Portal MPC Wallet.
|
|
29
|
+
*
|
|
30
|
+
* @param apiKey - The API key for the Swaps API.
|
|
31
|
+
* @param chainId - The chain ID for the sources.
|
|
32
|
+
* @returns The sources response.
|
|
33
|
+
*/
|
|
34
|
+
public async getSources(
|
|
35
|
+
apiKey: string,
|
|
36
|
+
chainId: string,
|
|
37
|
+
): Promise<Record<string, string>> {
|
|
38
|
+
return this.mpc?.getSources(apiKey, chainId)
|
|
39
|
+
}
|
|
40
|
+
}
|