@portal-hq/web 3.6.2-alpha → 3.7.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.
Files changed (45) hide show
  1. package/hypernative.d.ts +346 -0
  2. package/lib/commonjs/index.js +144 -2
  3. package/lib/commonjs/index.test.js +119 -2
  4. package/lib/commonjs/integrations/security/hypernative/index.js +101 -0
  5. package/lib/commonjs/integrations/security/hypernative/index.test.js +151 -0
  6. package/lib/commonjs/integrations/security/index.js +16 -0
  7. package/lib/commonjs/integrations/trading/zero-x/index.js +17 -4
  8. package/lib/commonjs/integrations/trading/zero-x/index.test.js +61 -15
  9. package/lib/commonjs/mpc/index.js +156 -5
  10. package/lib/commonjs/mpc/index.test.js +794 -5
  11. package/lib/commonjs/passkeys/index.js +394 -0
  12. package/lib/commonjs/passkeys/types.js +2 -0
  13. package/lib/commonjs/provider/index.js +5 -2
  14. package/lib/esm/index.js +144 -2
  15. package/lib/esm/index.test.js +119 -2
  16. package/lib/esm/integrations/security/hypernative/index.js +98 -0
  17. package/lib/esm/integrations/security/hypernative/index.test.js +146 -0
  18. package/lib/esm/integrations/security/index.js +10 -0
  19. package/lib/esm/integrations/trading/zero-x/index.js +17 -4
  20. package/lib/esm/integrations/trading/zero-x/index.test.js +62 -16
  21. package/lib/esm/mpc/index.js +156 -5
  22. package/lib/esm/mpc/index.test.js +795 -6
  23. package/lib/esm/passkeys/index.js +390 -0
  24. package/lib/esm/passkeys/types.js +1 -0
  25. package/lib/esm/provider/index.js +5 -2
  26. package/lifi-types.d.ts +1236 -0
  27. package/package.json +6 -3
  28. package/src/__mocks/constants.ts +422 -5
  29. package/src/__mocks/portal/mpc.ts +1 -0
  30. package/src/index.test.ts +179 -3
  31. package/src/index.ts +212 -4
  32. package/src/integrations/security/hypernative/index.test.ts +196 -0
  33. package/src/integrations/security/hypernative/index.ts +106 -0
  34. package/src/integrations/security/index.ts +14 -0
  35. package/src/integrations/trading/zero-x/index.test.ts +98 -19
  36. package/src/integrations/trading/zero-x/index.ts +29 -9
  37. package/src/mpc/index.test.ts +944 -7
  38. package/src/mpc/index.ts +200 -10
  39. package/src/passkeys/index.ts +536 -0
  40. package/src/passkeys/types.ts +78 -0
  41. package/src/provider/index.ts +5 -0
  42. package/tsconfig.json +7 -1
  43. package/types.d.ts +45 -12
  44. package/yieldxyz-types.d.ts +778 -0
  45. package/zero-x.d.ts +204 -0
package/src/mpc/index.ts CHANGED
@@ -67,8 +67,33 @@ import {
67
67
  LifiStepTransactionRequest,
68
68
  LifiStepTransactionResponse,
69
69
  } from '../../lifi-types'
70
-
71
- const WEB_SDK_VERSION = '3.6.2-alpha'
70
+ import {
71
+ ZeroExOptions,
72
+ ZeroExPriceRequest,
73
+ ZeroExPriceResponse,
74
+ ZeroExQuoteRequest,
75
+ ZeroExQuoteResponse,
76
+ ZeroExSourcesRequest,
77
+ ZeroExSourcesResponse,
78
+ } from '../../zero-x'
79
+ import {
80
+ ScreenAddressApiResponse,
81
+ ScanEVMRequest,
82
+ ScanEVMResponse,
83
+ ScanEip712Request,
84
+ ScanEip712Response,
85
+ ScanSolanaRequest,
86
+ ScanSolanaResponse,
87
+ ScanNftsRequest,
88
+ ScanNftsResponse,
89
+ ScanTokensRequest,
90
+ ScanTokensResponse,
91
+ ScanUrlRequest,
92
+ ScanUrlResponse,
93
+ ScreenAddressRequestOptions,
94
+ } from '../../hypernative'
95
+
96
+ const WEB_SDK_VERSION = '3.7.0'
72
97
 
73
98
  class Mpc {
74
99
  public iframe?: HTMLIFrameElement
@@ -135,16 +160,21 @@ class Mpc {
135
160
  window.removeEventListener('message', handleBackup)
136
161
  window.removeEventListener('message', handleProgress)
137
162
 
163
+ const resultData = result as Record<string, unknown>
164
+ const backupIds = Array.isArray(resultData.backupIds)
165
+ ? (resultData.backupIds as string[])
166
+ : []
138
167
  const storageCallback = async () => {
139
- await this.setBackupStatus(
140
- 'STORED_CLIENT_BACKUP_SHARE',
141
- result.backupIds as string[],
142
- )
168
+ await this.setBackupStatus('STORED_CLIENT_BACKUP_SHARE', backupIds)
143
169
  }
144
170
 
145
171
  // Resolve the promise with the result
146
172
  resolve({
147
- cipherText: result.cipherText,
173
+ cipherText: resultData.cipherText as string,
174
+ encryptionKey:
175
+ typeof resultData.encryptionKey === 'string'
176
+ ? (resultData.encryptionKey as string)
177
+ : undefined,
148
178
  storageCallback,
149
179
  })
150
180
  }
@@ -837,9 +867,9 @@ class Mpc {
837
867
  }
838
868
 
839
869
  public async getQuote(
840
- apiKey: string,
841
- args: QuoteArgs,
842
870
  chainId: string,
871
+ args: QuoteArgs,
872
+ apiKey?: string,
843
873
  ): Promise<QuoteResponse> {
844
874
  return new Promise((resolve, reject) => {
845
875
  const handleGetQuote = (event: MessageEvent<WorkerResult>) => {
@@ -881,8 +911,8 @@ class Mpc {
881
911
  }
882
912
 
883
913
  public async getSources(
884
- apiKey: string,
885
914
  chainId: string,
915
+ apiKey?: string,
886
916
  ): Promise<Record<string, string>> {
887
917
  return new Promise((resolve, reject) => {
888
918
  const handleGetSources = (event: MessageEvent<WorkerResult>) => {
@@ -1350,6 +1380,119 @@ class Mpc {
1350
1380
  })
1351
1381
  }
1352
1382
 
1383
+ public async getSwapsQuoteV2(
1384
+ data: ZeroExQuoteRequest,
1385
+ options?: ZeroExOptions,
1386
+ ): Promise<ZeroExQuoteResponse> {
1387
+ return this.handleRequestToIframeAndPost({
1388
+ methodMessage: 'portal:swaps:getQuoteV2',
1389
+ errorMessage: 'portal:swaps:getQuoteV2Error',
1390
+ resultMessage: 'portal:swaps:getQuoteV2Result',
1391
+ data: { ...data, options },
1392
+ })
1393
+ }
1394
+
1395
+ public async getSwapsSourcesV2(
1396
+ data: ZeroExSourcesRequest,
1397
+ options?: ZeroExOptions,
1398
+ ): Promise<ZeroExSourcesResponse> {
1399
+ return this.handleRequestToIframeAndPost({
1400
+ methodMessage: 'portal:swaps:getSourcesV2',
1401
+ errorMessage: 'portal:swaps:getSourcesV2Error',
1402
+ resultMessage: 'portal:swaps:getSourcesV2Result',
1403
+ data: { ...data, options },
1404
+ })
1405
+ }
1406
+
1407
+ public async getSwapsPrice(
1408
+ data: ZeroExPriceRequest,
1409
+ options?: ZeroExOptions,
1410
+ ): Promise<ZeroExPriceResponse> {
1411
+ return this.handleRequestToIframeAndPost({
1412
+ methodMessage: 'portal:swaps:getPrice',
1413
+ errorMessage: 'portal:swaps:getPriceError',
1414
+ resultMessage: 'portal:swaps:getPriceResult',
1415
+ data: { ...data, options },
1416
+ })
1417
+ }
1418
+
1419
+ /*******************************
1420
+ * Security Methods
1421
+ *******************************/
1422
+
1423
+ public async scanAddresses(
1424
+ data: { addresses: string[] } & ScreenAddressRequestOptions,
1425
+ ): Promise<ScreenAddressApiResponse> {
1426
+ return this.handleRequestToIframeAndPost({
1427
+ methodMessage: 'portal:security:scanAddresses',
1428
+ errorMessage: 'portal:security:scanAddressesError',
1429
+ resultMessage: 'portal:security:scanAddressesResult',
1430
+ data,
1431
+ })
1432
+ }
1433
+
1434
+ public async scanEVMTx(
1435
+ data: ScanEVMRequest,
1436
+ ): Promise<ScanEVMResponse> {
1437
+ return this.handleRequestToIframeAndPost({
1438
+ methodMessage: 'portal:security:scanEVMTx',
1439
+ errorMessage: 'portal:security:scanEVMTxError',
1440
+ resultMessage: 'portal:security:scanEVMTxResult',
1441
+ data,
1442
+ })
1443
+ }
1444
+
1445
+ public async scanEip712Tx(
1446
+ data: ScanEip712Request,
1447
+ ): Promise<ScanEip712Response> {
1448
+ return this.handleRequestToIframeAndPost({
1449
+ methodMessage: 'portal:security:scanEip712Tx',
1450
+ errorMessage: 'portal:security:scanEip712TxError',
1451
+ resultMessage: 'portal:security:scanEip712TxResult',
1452
+ data,
1453
+ })
1454
+ }
1455
+
1456
+ public async scanSolanaTx(
1457
+ data: ScanSolanaRequest,
1458
+ ): Promise<ScanSolanaResponse> {
1459
+ return this.handleRequestToIframeAndPost({
1460
+ methodMessage: 'portal:security:scanSolanaTx',
1461
+ errorMessage: 'portal:security:scanSolanaTxError',
1462
+ resultMessage: 'portal:security:scanSolanaTxResult',
1463
+ data,
1464
+ })
1465
+ }
1466
+
1467
+ public async scanNFTs(nfts: ScanNftsRequest): Promise<ScanNftsResponse> {
1468
+ return this.handleRequestToIframeAndPost({
1469
+ methodMessage: 'portal:security:scanNfts',
1470
+ errorMessage: 'portal:security:scanNftsError',
1471
+ resultMessage: 'portal:security:scanNftsResult',
1472
+ data: nfts,
1473
+ })
1474
+ }
1475
+
1476
+ public async scanTokens(
1477
+ tokens: ScanTokensRequest,
1478
+ ): Promise<ScanTokensResponse> {
1479
+ return this.handleRequestToIframeAndPost({
1480
+ methodMessage: 'portal:security:scanTokens',
1481
+ errorMessage: 'portal:security:scanTokensError',
1482
+ resultMessage: 'portal:security:scanTokensResult',
1483
+ data: tokens,
1484
+ })
1485
+ }
1486
+
1487
+ public async scanUrl(url: ScanUrlRequest): Promise<ScanUrlResponse> {
1488
+ return this.handleRequestToIframeAndPost({
1489
+ methodMessage: 'portal:security:scanUrl',
1490
+ errorMessage: 'portal:security:scanUrlError',
1491
+ resultMessage: 'portal:security:scanUrlResult',
1492
+ data: { url },
1493
+ })
1494
+ }
1495
+
1353
1496
  /***************************
1354
1497
  * Private Methods
1355
1498
  ***************************/
@@ -1457,6 +1600,53 @@ class Mpc {
1457
1600
  return origin
1458
1601
  }
1459
1602
 
1603
+ /**
1604
+ * Fetches a scoped JWT for passkey operations from the iframe.
1605
+ * The JWT has only "passkey" permission, reducing blast radius if compromised.
1606
+ */
1607
+ public async getPasskeyJwt(): Promise<string> {
1608
+ return new Promise((resolve, reject) => {
1609
+ const handleResult = (event: MessageEvent) => {
1610
+ const { type, data } = event.data
1611
+ const { origin } = event
1612
+
1613
+ // ignore any broadcast postMessages
1614
+ if (origin !== this.getOrigin()) {
1615
+ return
1616
+ }
1617
+
1618
+ if (type === 'portal:getPasskeyJwtResult') {
1619
+ window.removeEventListener('message', handleResult)
1620
+ window.removeEventListener('message', handleError)
1621
+ resolve(data.token)
1622
+ }
1623
+ }
1624
+
1625
+ const handleError = (event: MessageEvent) => {
1626
+ const { type, data } = event.data
1627
+ const { origin } = event
1628
+
1629
+ if (origin !== this.getOrigin()) {
1630
+ return
1631
+ }
1632
+
1633
+ if (type === 'portal:getPasskeyJwtError') {
1634
+ window.removeEventListener('message', handleResult)
1635
+ window.removeEventListener('message', handleError)
1636
+ reject(new Error(data.message))
1637
+ }
1638
+ }
1639
+
1640
+ window.addEventListener('message', handleResult)
1641
+ window.addEventListener('message', handleError)
1642
+
1643
+ this.postMessage({
1644
+ type: 'portal:getPasskeyJwt',
1645
+ data: {},
1646
+ })
1647
+ })
1648
+ }
1649
+
1460
1650
  private postMessage(event: { type: string; data: any }) {
1461
1651
  this.iframe?.contentWindow?.postMessage(event, this.getOrigin())
1462
1652
  }