@portal-hq/web 3.6.0-alpha → 3.6.0

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.
@@ -730,11 +730,17 @@ export const mockQuoteRes = {
730
730
  }
731
731
 
732
732
  export const mockSourcesRes = {
733
- '0x': '0xE41d2489571d322189246DaFA5ebDe1F4699F498',
734
- SushiSwap: '0x6B3595068778DD592e39A122f4f5a5cF09C90fE2',
735
- Uniswap: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
736
- Uniswap_V2: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
737
- Uniswap_V3: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
733
+ data: {
734
+ rawResponse: {
735
+ sources: ['0x', 'SushiSwap', 'Uniswap', 'Uniswap_V2', 'Uniswap_V3'],
736
+ zid: 'test-zid',
737
+ },
738
+ },
739
+ metadata: {
740
+ chainId: 'eip155:1',
741
+ clientId: 'test',
742
+ clientEip155Address: '0x1234567890123456789012345678901234567890',
743
+ },
738
744
  }
739
745
 
740
746
  export const mockZeroXQuoteResponse = {
@@ -1312,3 +1318,198 @@ export const mockLifiGetRouteStepResponse = {
1312
1318
  },
1313
1319
  },
1314
1320
  }
1321
+
1322
+ // ZeroEx v2 mock data
1323
+ export const mockZeroExQuoteV2Request = {
1324
+ chainId: 'eip155:1',
1325
+ buyToken: 'UNI',
1326
+ sellToken: 'WETH',
1327
+ sellAmount: '1000000000000000000',
1328
+ }
1329
+
1330
+ export const mockZeroExQuoteV2Response = {
1331
+ data: {
1332
+ rawResponse: {
1333
+ blockNumber: '18500000',
1334
+ buyAmount: '100000000000000000000',
1335
+ buyToken: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
1336
+ fees: {
1337
+ integratorFee: null,
1338
+ zeroExFee: null,
1339
+ gasFee: {
1340
+ amount: '21000000000000',
1341
+ token: '0x0000000000000000000000000000000000000000',
1342
+ type: 'gas',
1343
+ },
1344
+ },
1345
+ issues: {
1346
+ allowance: {
1347
+ actual: '0',
1348
+ spender: '0x1234567890123456789012345678901234567890',
1349
+ },
1350
+ balance: {
1351
+ token: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
1352
+ actual: '1000000000000000000',
1353
+ expected: '1000000000000000000',
1354
+ },
1355
+ simulationIncomplete: false,
1356
+ invalidSourcesPassed: [],
1357
+ },
1358
+ liquidityAvailable: true,
1359
+ minBuyAmount: '99000000000000000000',
1360
+ route: {
1361
+ fills: [
1362
+ {
1363
+ from: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
1364
+ to: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
1365
+ source: 'Uniswap_V3',
1366
+ proportionBps: '10000',
1367
+ },
1368
+ ],
1369
+ tokens: [
1370
+ {
1371
+ address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
1372
+ symbol: 'WETH',
1373
+ },
1374
+ {
1375
+ address: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
1376
+ symbol: 'UNI',
1377
+ },
1378
+ ],
1379
+ },
1380
+ sellAmount: '1000000000000000000',
1381
+ sellToken: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
1382
+ tokenMetadata: {
1383
+ buyToken: {
1384
+ buyTaxBps: '0',
1385
+ sellTaxBps: '0',
1386
+ },
1387
+ sellToken: {
1388
+ buyTaxBps: '0',
1389
+ sellTaxBps: '0',
1390
+ },
1391
+ },
1392
+ totalNetworkFee: '21000000000000',
1393
+ transaction: {
1394
+ to: '0x1234567890123456789012345678901234567890',
1395
+ data: '0xabcdef',
1396
+ gas: '200000',
1397
+ gasPrice: '30000000000',
1398
+ value: '0',
1399
+ },
1400
+ },
1401
+ },
1402
+ metadata: {
1403
+ buyToken: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
1404
+ sellToken: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
1405
+ sellAmount: '1000000000000000000',
1406
+ chainId: 'eip155:1',
1407
+ clientId: 'test-client-id',
1408
+ clientEip155Address: mockEip155Address,
1409
+ },
1410
+ }
1411
+
1412
+ export const mockZeroExSourcesV2Request = {
1413
+ chainId: 'eip155:1',
1414
+ }
1415
+
1416
+ export const mockZeroExSourcesV2Response = {
1417
+ data: {
1418
+ rawResponse: {
1419
+ sources: ['Uniswap_V2', 'Uniswap_V3', 'SushiSwap', '0x'],
1420
+ zid: 'test-zid',
1421
+ },
1422
+ },
1423
+ metadata: {
1424
+ chainId: 'eip155:1',
1425
+ clientId: 'test-client-id',
1426
+ },
1427
+ }
1428
+
1429
+ export const mockZeroExPriceRequest = {
1430
+ chainId: 'eip155:1',
1431
+ buyToken: 'UNI',
1432
+ sellToken: 'WETH',
1433
+ sellAmount: '1000000000000000000',
1434
+ }
1435
+
1436
+ export const mockZeroExPriceResponse = {
1437
+ data: {
1438
+ rawResponse: {
1439
+ blockNumber: '18500000',
1440
+ buyAmount: '100000000000000000000',
1441
+ buyToken: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
1442
+ fees: {
1443
+ integratorFee: null,
1444
+ zeroExFee: null,
1445
+ gasFee: {
1446
+ amount: '21000000000000',
1447
+ token: '0x0000000000000000000000000000000000000000',
1448
+ type: 'gas',
1449
+ },
1450
+ },
1451
+ gas: '200000',
1452
+ gasPrice: '30000000000',
1453
+ issues: {
1454
+ allowance: {
1455
+ actual: '0',
1456
+ spender: '0x1234567890123456789012345678901234567890',
1457
+ },
1458
+ balance: {
1459
+ token: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
1460
+ actual: '1000000000000000000',
1461
+ expected: '1000000000000000000',
1462
+ },
1463
+ simulationIncomplete: false,
1464
+ invalidSourcesPassed: [],
1465
+ },
1466
+ liquidityAvailable: true,
1467
+ minBuyAmount: '99000000000000000000',
1468
+ route: {
1469
+ fills: [
1470
+ {
1471
+ from: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
1472
+ to: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
1473
+ source: 'Uniswap_V3',
1474
+ proportionBps: '10000',
1475
+ },
1476
+ ],
1477
+ tokens: [
1478
+ {
1479
+ address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
1480
+ symbol: 'WETH',
1481
+ },
1482
+ {
1483
+ address: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
1484
+ symbol: 'UNI',
1485
+ },
1486
+ ],
1487
+ },
1488
+ sellAmount: '1000000000000000000',
1489
+ sellToken: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
1490
+ tokenMetadata: {
1491
+ buyToken: {
1492
+ buyTaxBps: '0',
1493
+ sellTaxBps: '0',
1494
+ },
1495
+ sellToken: {
1496
+ buyTaxBps: '0',
1497
+ sellTaxBps: '0',
1498
+ },
1499
+ },
1500
+ totalNetworkFee: '21000000000000',
1501
+ },
1502
+ },
1503
+ metadata: {
1504
+ buyToken: '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984',
1505
+ sellToken: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
1506
+ sellAmount: '1000000000000000000',
1507
+ chainId: 'eip155:1',
1508
+ clientId: 'test-client-id',
1509
+ clientEip155Address: mockEip155Address,
1510
+ },
1511
+ }
1512
+
1513
+ export const mockZeroExOptions = {
1514
+ zeroXApiKey: 'test-0x-api-key',
1515
+ }
package/src/index.test.ts CHANGED
@@ -883,9 +883,9 @@ describe('Portal', () => {
883
883
 
884
884
  expect(portal.mpc.getQuote).toHaveBeenCalledTimes(1)
885
885
  expect(portal.mpc.getQuote).toHaveBeenCalledWith(
886
- 'test',
887
- mockQuoteArgs,
888
886
  'eip155:1',
887
+ mockQuoteArgs,
888
+ 'test',
889
889
  )
890
890
  })
891
891
  })
@@ -895,7 +895,7 @@ describe('Portal', () => {
895
895
  await portal.getSources('test', 'eip155:1')
896
896
 
897
897
  expect(portal.mpc.getSources).toHaveBeenCalledTimes(1)
898
- expect(portal.mpc.getSources).toHaveBeenCalledWith('test', 'eip155:1')
898
+ expect(portal.mpc.getSources).toHaveBeenCalledWith('eip155:1', 'test')
899
899
  })
900
900
  })
901
901
 
package/src/index.ts CHANGED
@@ -465,6 +465,7 @@ class Portal {
465
465
  chainId,
466
466
  method: 'eth_sendTransaction',
467
467
  params: [buildTxResponse.transaction],
468
+ sponsorGas: params.sponsorGas,
468
469
  })
469
470
  break
470
471
  }
@@ -473,6 +474,7 @@ class Portal {
473
474
  chainId,
474
475
  method: 'sol_signAndSendTransaction',
475
476
  params: [buildTxResponse.transaction],
477
+ sponsorGas: params.sponsorGas,
476
478
  })
477
479
  break
478
480
  }
@@ -899,7 +901,7 @@ class Portal {
899
901
  args: QuoteArgs,
900
902
  chainId: string,
901
903
  ): Promise<QuoteResponse> {
902
- return this.mpc?.getQuote(apiKey, args, chainId)
904
+ return this.mpc?.getQuote(chainId, args, apiKey)
903
905
  }
904
906
 
905
907
  /**
@@ -909,7 +911,7 @@ class Portal {
909
911
  apiKey: string,
910
912
  chainId: string,
911
913
  ): Promise<Record<string, string>> {
912
- return this.mpc?.getSources(apiKey, chainId)
914
+ return this.mpc?.getSources(chainId, apiKey)
913
915
  }
914
916
 
915
917
  /*******************************
@@ -7,10 +7,14 @@ import Mpc from '../../../mpc'
7
7
  import portalMock from '../../../__mocks/portal/portal'
8
8
  import {
9
9
  mockHost,
10
- mockQuoteArgs,
11
10
  mockSourcesRes,
12
- mockZeroXQuoteResponse,
11
+ mockZeroExQuoteV2Request,
12
+ mockZeroExQuoteV2Response,
13
+ mockZeroExOptions,
14
+ mockZeroExPriceRequest,
15
+ mockZeroExPriceResponse,
13
16
  } from '../../../__mocks/constants'
17
+ import type { ZeroExPriceResponse } from '../../../../zero-x'
14
18
 
15
19
  describe('ZeroX', () => {
16
20
  let zeroX: ZeroX
@@ -28,46 +32,121 @@ describe('ZeroX', () => {
28
32
  })
29
33
 
30
34
  describe('getQuote', () => {
31
- it('should correctly call mpc.getQuote', async () => {
35
+ it('should correctly call mpc.getSwapsQuoteV2 with args and options', async () => {
32
36
  const spy = jest
33
- .spyOn(mpc, 'getQuote')
34
- .mockResolvedValue(mockZeroXQuoteResponse)
37
+ .spyOn(mpc, 'getSwapsQuoteV2')
38
+ .mockResolvedValue(mockZeroExQuoteV2Response)
35
39
 
36
- const result = await zeroX.getQuote('test', mockQuoteArgs, 'eip155:1')
40
+ const result = await zeroX.getQuote(
41
+ mockZeroExQuoteV2Request,
42
+ mockZeroExOptions,
43
+ )
44
+
45
+ expect(spy).toHaveBeenCalledTimes(1)
46
+ expect(spy).toHaveBeenCalledWith(
47
+ mockZeroExQuoteV2Request,
48
+ mockZeroExOptions,
49
+ )
50
+ expect(result).toEqual(mockZeroExQuoteV2Response)
51
+ })
52
+
53
+ it('should correctly call mpc.getSwapsQuoteV2 without options', async () => {
54
+ const spy = jest
55
+ .spyOn(mpc, 'getSwapsQuoteV2')
56
+ .mockResolvedValue(mockZeroExQuoteV2Response)
57
+
58
+ const result = await zeroX.getQuote(mockZeroExQuoteV2Request)
37
59
 
38
60
  expect(spy).toHaveBeenCalledTimes(1)
39
- expect(spy).toHaveBeenCalledWith('test', mockQuoteArgs, 'eip155:1')
40
- expect(result).toEqual(mockZeroXQuoteResponse)
61
+ expect(spy).toHaveBeenCalledWith(mockZeroExQuoteV2Request, undefined)
62
+ expect(result).toEqual(mockZeroExQuoteV2Response)
41
63
  })
42
64
 
43
- it('should propagate errors from mpc.getQuote', async () => {
65
+ it('should propagate errors from mpc.getSwapsQuoteV2', async () => {
44
66
  const error = new Error('Test error')
45
- jest.spyOn(mpc, 'getQuote').mockRejectedValue(error)
67
+ jest.spyOn(mpc, 'getSwapsQuoteV2').mockRejectedValue(error)
46
68
 
47
- await expect(
48
- zeroX.getQuote('test', mockQuoteArgs, 'eip155:1'),
49
- ).rejects.toThrow('Test error')
69
+ await expect(zeroX.getQuote(mockZeroExQuoteV2Request)).rejects.toThrow(
70
+ 'Test error',
71
+ )
50
72
  })
51
73
  })
52
74
 
53
75
  describe('getSources', () => {
54
- it('should correctly call mpc.getSources', async () => {
76
+ it('should correctly call mpc.getSources with chainId and apiKey', async () => {
77
+ const spy = jest
78
+ .spyOn(mpc, 'getSwapsSourcesV2')
79
+ .mockResolvedValue(mockSourcesRes)
80
+
81
+ const result = await zeroX.getSources('eip155:1', {
82
+ zeroXApiKey: 'test-api-key',
83
+ })
84
+
85
+ console.log(`Result:`, result)
86
+ expect(spy).toHaveBeenCalledTimes(1)
87
+ expect(spy).toHaveBeenCalledWith(
88
+ { chainId: 'eip155:1' },
89
+ { zeroXApiKey: 'test-api-key' },
90
+ )
91
+ expect(result).toEqual(mockSourcesRes)
92
+ })
93
+
94
+ it('should correctly call mpc.getSources without apiKey', async () => {
55
95
  const spy = jest
56
- .spyOn(mpc, 'getSources')
96
+ .spyOn(mpc, 'getSwapsSourcesV2')
57
97
  .mockResolvedValue(mockSourcesRes)
58
98
 
59
- const result = await zeroX.getSources('test', 'eip155:1')
99
+ const result = await zeroX.getSources('eip155:1')
60
100
 
61
101
  expect(spy).toHaveBeenCalledTimes(1)
62
- expect(spy).toHaveBeenCalledWith('test', 'eip155:1')
102
+ expect(spy).toHaveBeenCalledWith({ chainId: 'eip155:1' }, undefined)
63
103
  expect(result).toEqual(mockSourcesRes)
64
104
  })
65
105
 
66
106
  it('should propagate errors from mpc.getSources', async () => {
67
107
  const error = new Error('Test error')
68
- jest.spyOn(mpc, 'getSources').mockRejectedValue(error)
108
+ jest.spyOn(mpc, 'getSwapsSourcesV2').mockRejectedValue(error)
109
+
110
+ await expect(zeroX.getSources('eip155:1')).rejects.toThrow('Test error')
111
+ })
112
+ })
113
+
114
+ describe('getPrice', () => {
115
+ it('should correctly call mpc.getSwapsPrice with args and options', async () => {
116
+ const spy = jest
117
+ .spyOn(mpc, 'getSwapsPrice')
118
+ .mockResolvedValue(mockZeroExPriceResponse as ZeroExPriceResponse)
119
+
120
+ const result = await zeroX.getPrice(
121
+ mockZeroExPriceRequest,
122
+ mockZeroExOptions,
123
+ )
124
+
125
+ expect(spy).toHaveBeenCalledTimes(1)
126
+ expect(spy).toHaveBeenCalledWith(
127
+ mockZeroExPriceRequest,
128
+ mockZeroExOptions,
129
+ )
130
+ expect(result).toEqual(mockZeroExPriceResponse)
131
+ })
132
+
133
+ it('should correctly call mpc.getSwapsPrice without options', async () => {
134
+ const spy = jest
135
+ .spyOn(mpc, 'getSwapsPrice')
136
+ .mockResolvedValue(mockZeroExPriceResponse as ZeroExPriceResponse)
137
+
138
+ const result = await zeroX.getPrice(mockZeroExPriceRequest)
139
+
140
+ expect(spy).toHaveBeenCalledTimes(1)
141
+ expect(spy).toHaveBeenCalledWith(mockZeroExPriceRequest, undefined)
142
+ expect(result).toEqual(mockZeroExPriceResponse)
143
+ })
144
+
145
+ it('should propagate errors from mpc.getSwapsPrice', async () => {
146
+ const error = new Error('Test error')
147
+ jest.spyOn(mpc, 'getSwapsPrice').mockRejectedValue(error)
69
148
 
70
- await expect(zeroX.getSources('test', 'eip155:1')).rejects.toThrow(
149
+ await expect(zeroX.getPrice(mockZeroExPriceRequest)).rejects.toThrow(
71
150
  'Test error',
72
151
  )
73
152
  })
@@ -1,5 +1,12 @@
1
1
  import Mpc from '../../../mpc'
2
- import { QuoteArgs, QuoteResponse } from '../../../../types'
2
+ import {
3
+ ZeroExOptions,
4
+ ZeroExPriceRequest,
5
+ ZeroExPriceResponse,
6
+ ZeroExQuoteRequest,
7
+ ZeroExQuoteResponse,
8
+ ZeroExSourcesResponse,
9
+ } from '../../../../zero-x'
3
10
 
4
11
  export default class ZeroX {
5
12
  private mpc: Mpc
@@ -17,11 +24,10 @@ export default class ZeroX {
17
24
  * @returns The quote response.
18
25
  */
19
26
  public async getQuote(
20
- apiKey: string,
21
- args: QuoteArgs,
22
- chainId: string,
23
- ): Promise<QuoteResponse> {
24
- return this.mpc?.getQuote(apiKey, args, chainId)
27
+ args: ZeroExQuoteRequest,
28
+ options?: ZeroExOptions,
29
+ ): Promise<ZeroExQuoteResponse> {
30
+ return this.mpc?.getSwapsQuoteV2(args, options)
25
31
  }
26
32
 
27
33
  /**
@@ -32,9 +38,23 @@ export default class ZeroX {
32
38
  * @returns The sources response.
33
39
  */
34
40
  public async getSources(
35
- apiKey: string,
36
41
  chainId: string,
37
- ): Promise<Record<string, string>> {
38
- return this.mpc?.getSources(apiKey, chainId)
42
+ options?: ZeroExOptions,
43
+ ): Promise<ZeroExSourcesResponse> {
44
+ return this.mpc?.getSwapsSourcesV2({ chainId }, options)
45
+ }
46
+
47
+ /**
48
+ * Get the price of a token from the Swaps API.
49
+ *
50
+ * @param args - The arguments for the price.
51
+ * @param options - The options for the price.
52
+ * @returns The price response.
53
+ */
54
+ public async getPrice(
55
+ args: ZeroExPriceRequest,
56
+ options?: ZeroExOptions,
57
+ ): Promise<ZeroExPriceResponse> {
58
+ return this.mpc?.getSwapsPrice(args, options)
39
59
  }
40
60
  }