@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/index.ts CHANGED
@@ -17,9 +17,10 @@ import {
17
17
  NFTAsset,
18
18
  OrgBackupShares,
19
19
  SendAssetParams,
20
- SendAssetResponse,
21
20
  type BackupConfigs,
21
+ type BackupOptions,
22
22
  type BackupResponse,
23
+ type BackupShareResult,
23
24
  type Balance,
24
25
  type ClientResponse,
25
26
  type ClientResponseWallet,
@@ -29,6 +30,7 @@ import {
29
30
  type GDriveConfig,
30
31
  type NFT,
31
32
  type PasskeyConfig,
33
+ type PasskeyOptions,
32
34
  type PortalOptions,
33
35
  type ProgressCallback,
34
36
  type QuoteArgs,
@@ -45,6 +47,9 @@ import Mpc from './mpc'
45
47
  import Provider, { RequestMethod } from './provider'
46
48
  import Yield from './integrations/yield'
47
49
  import Trading from './integrations/trading'
50
+ import Security from './integrations/security'
51
+ import PasskeyService from './passkeys'
52
+
48
53
 
49
54
  class Portal {
50
55
  public address?: string
@@ -58,6 +63,7 @@ class Portal {
58
63
  public mpc: Mpc
59
64
  public yield: Yield
60
65
  public trading: Trading
66
+ public security: Security
61
67
  public mpcHost: string
62
68
  public mpcVersion: string
63
69
  public provider: Provider
@@ -66,6 +72,8 @@ class Portal {
66
72
  private errorCallbacks: ((reason: string) => any | Promise<any>)[] = []
67
73
  private rpcConfig: RpcConfig
68
74
  private readyCallbacks: (() => any | Promise<any>)[] = []
75
+ private passkeyService?: PasskeyService
76
+ private passkeyServiceDefaultDomain?: string
69
77
 
70
78
  public get ready() {
71
79
  return this.mpc.ready
@@ -113,6 +121,8 @@ class Portal {
113
121
 
114
122
  this.trading = new Trading({ mpc: this.mpc })
115
123
 
124
+ this.security = new Security({ mpc: this.mpc })
125
+
116
126
  this.provider = new Provider({
117
127
  portal: this,
118
128
  chainId: chainId ? Number(chainId) : undefined,
@@ -192,6 +202,141 @@ class Portal {
192
202
  return address
193
203
  }
194
204
 
205
+ public async generateBackupShare(
206
+ progress: ProgressCallback = () => {
207
+ // Noop
208
+ },
209
+ ): Promise<BackupShareResult> {
210
+ const response = await this.mpc.backup(
211
+ {
212
+ backupMethod: BackupMethods.custom,
213
+ backupConfigs: {},
214
+ host: this.host,
215
+ mpcVersion: this.mpcVersion,
216
+ featureFlags: this.featureFlags,
217
+ },
218
+ progress,
219
+ )
220
+
221
+ if (!response.encryptionKey) {
222
+ throw new Error(
223
+ '[Portal] Custom backup did not return an encryption key. Please ensure you are using the latest iframe bundle.',
224
+ )
225
+ }
226
+
227
+ return {
228
+ cipherText: response.cipherText,
229
+ encryptionKey: response.encryptionKey,
230
+ }
231
+ }
232
+
233
+ public async registerPasskeyAndStoreEncryptionKey(
234
+ cipherText: string,
235
+ encryptionKey: string,
236
+ options: PasskeyOptions = {},
237
+ ): Promise<void> {
238
+ const { service, customDomain, relyingPartyId, relyingPartyName } =
239
+ this.resolvePasskeyOptions(options)
240
+
241
+ await service.registerPasskeyAndStoreKey({
242
+ customDomain,
243
+ relyingPartyName,
244
+ encryptionKey,
245
+ relyingPartyId,
246
+ cipherText,
247
+ })
248
+ }
249
+
250
+ public async authenticatePasskeyAndRetrieveKey(
251
+ options: PasskeyOptions = {},
252
+ ): Promise<string> {
253
+ const { service, customDomain, relyingPartyId, relyingPartyName } =
254
+ this.resolvePasskeyOptions(options)
255
+
256
+ return await service.authenticatePasskeyAndRetrieveKey({
257
+ customDomain,
258
+ relyingPartyName,
259
+ relyingPartyId,
260
+ })
261
+ }
262
+
263
+ /**
264
+ * Register a passkey without tying it to an encryption key.
265
+ * The encryption key can be stored later using authenticatePasskeyAndWriteKey.
266
+ */
267
+ public async registerPasskey(
268
+ options: PasskeyOptions = {},
269
+ ): Promise<void> {
270
+ const { service, customDomain, relyingPartyId, relyingPartyName } =
271
+ this.resolvePasskeyOptions(options)
272
+
273
+ await service.registerPasskey({
274
+ customDomain,
275
+ relyingPartyName,
276
+ relyingPartyId,
277
+ })
278
+ }
279
+
280
+ /**
281
+ * Authenticate with passkey and store an encryption key.
282
+ * Used after registerPasskey to associate an encryption key with the passkey.
283
+ */
284
+ public async authenticatePasskeyAndWriteKey(
285
+ encryptionKey: string,
286
+ options: PasskeyOptions = {},
287
+ ): Promise<void> {
288
+ const { service, customDomain, relyingPartyId, relyingPartyName } =
289
+ this.resolvePasskeyOptions(options)
290
+
291
+ await service.authenticatePasskeyAndWriteKey({
292
+ customDomain,
293
+ relyingPartyName,
294
+ relyingPartyId,
295
+ encryptionKey,
296
+ })
297
+ }
298
+
299
+ public async backupWithPasskey(
300
+ options: BackupOptions = {},
301
+ progress: ProgressCallback = () => {
302
+ // Noop
303
+ },
304
+ ): Promise<void> {
305
+ const {
306
+ usePopup = true,
307
+ customDomain,
308
+ relyingPartyName,
309
+ backupMethod = BackupMethods.passkey,
310
+ } = options
311
+
312
+ if (usePopup) {
313
+ await this.backupWallet(backupMethod, progress, {})
314
+ return
315
+ }
316
+
317
+ if (backupMethod !== BackupMethods.passkey) {
318
+ throw new Error(
319
+ `[Portal] Direct passkey backup currently supports only BackupMethods.passkey (received ${backupMethod}).`,
320
+ )
321
+ }
322
+
323
+ const { cipherText, encryptionKey } = await this.generateBackupShare(
324
+ progress,
325
+ )
326
+
327
+ await this.registerPasskeyAndStoreEncryptionKey(
328
+ cipherText,
329
+ encryptionKey,
330
+ {
331
+ customDomain,
332
+ relyingPartyName,
333
+ usePopup,
334
+ },
335
+ )
336
+
337
+ await this.storedClientBackupShare(true, BackupMethods.passkey)
338
+ }
339
+
195
340
  public async backupWallet(
196
341
  backupMethod: BackupMethods,
197
342
  progress: ProgressCallback = () => {
@@ -441,7 +586,7 @@ class Portal {
441
586
  public async sendAsset(
442
587
  chain: string,
443
588
  params: SendAssetParams,
444
- ): Promise<SendAssetResponse> {
589
+ ): Promise<string> {
445
590
  try {
446
591
  // Convert the chain to a chain ID
447
592
  const chainId = this.convertChainToChainId(chain)
@@ -465,6 +610,7 @@ class Portal {
465
610
  chainId,
466
611
  method: 'eth_sendTransaction',
467
612
  params: [buildTxResponse.transaction],
613
+ sponsorGas: params.sponsorGas,
468
614
  })
469
615
  break
470
616
  }
@@ -473,6 +619,7 @@ class Portal {
473
619
  chainId,
474
620
  method: 'sol_signAndSendTransaction',
475
621
  params: [buildTxResponse.transaction],
622
+ sponsorGas: params.sponsorGas,
476
623
  })
477
624
  break
478
625
  }
@@ -899,7 +1046,7 @@ class Portal {
899
1046
  args: QuoteArgs,
900
1047
  chainId: string,
901
1048
  ): Promise<QuoteResponse> {
902
- return this.mpc?.getQuote(apiKey, args, chainId)
1049
+ return this.mpc?.getQuote(chainId, args, apiKey)
903
1050
  }
904
1051
 
905
1052
  /**
@@ -909,7 +1056,7 @@ class Portal {
909
1056
  apiKey: string,
910
1057
  chainId: string,
911
1058
  ): Promise<Record<string, string>> {
912
- return this.mpc?.getSources(apiKey, chainId)
1059
+ return this.mpc?.getSources(chainId, apiKey)
913
1060
  }
914
1061
 
915
1062
  /*******************************
@@ -1030,6 +1177,66 @@ class Portal {
1030
1177
 
1031
1178
  return chainId
1032
1179
  }
1180
+
1181
+ private ensurePasskeyService(): PasskeyService {
1182
+ const defaultDomain = this.getDefaultPasskeyDomain()
1183
+
1184
+ if (
1185
+ !this.passkeyService ||
1186
+ this.passkeyServiceDefaultDomain !== defaultDomain
1187
+ ) {
1188
+ this.passkeyService = new PasskeyService({
1189
+ defaultDomain,
1190
+ getJwt: () => this.mpc!.getPasskeyJwt(),
1191
+ })
1192
+ this.passkeyServiceDefaultDomain = defaultDomain
1193
+ }
1194
+
1195
+ return this.passkeyService
1196
+ }
1197
+
1198
+ private getDefaultPasskeyDomain(): string {
1199
+ return this.passkeyConfig?.webAuthnHost ?? 'backup.web.portalhq.io'
1200
+ }
1201
+
1202
+ private extractRpId(domain?: string): string {
1203
+ const targetDomain = domain ?? this.getDefaultPasskeyDomain()
1204
+
1205
+ try {
1206
+ const normalized = targetDomain.startsWith('http')
1207
+ ? targetDomain
1208
+ : `https://${targetDomain}`
1209
+ return new URL(normalized).hostname
1210
+ } catch {
1211
+ return targetDomain
1212
+ }
1213
+ }
1214
+
1215
+ private resolvePasskeyOptions(options: PasskeyOptions): {
1216
+ service: PasskeyService
1217
+ customDomain: string | undefined
1218
+ relyingPartyId: string
1219
+ relyingPartyName: string
1220
+ } {
1221
+ if (options.usePopup) {
1222
+ throw new Error(
1223
+ '[Portal] This method does not support the popup flow. Use usePopup: false.',
1224
+ )
1225
+ }
1226
+
1227
+ const service = this.ensurePasskeyService()
1228
+ const domain = options.customDomain ?? this.getDefaultPasskeyDomain()
1229
+ const relyingPartyId = options.relyingPartyId ?? this.extractRpId(domain)
1230
+ const relyingPartyName =
1231
+ options.relyingPartyName ?? this.passkeyConfig?.relyingParty ?? 'Portal'
1232
+
1233
+ return {
1234
+ service,
1235
+ customDomain: options.customDomain,
1236
+ relyingPartyId,
1237
+ relyingPartyName,
1238
+ }
1239
+ }
1033
1240
  }
1034
1241
 
1035
1242
  export {
@@ -1079,6 +1286,7 @@ export enum BackupMethods {
1079
1286
  gdrive = 'GDRIVE',
1080
1287
  password = 'PASSWORD',
1081
1288
  passkey = 'PASSKEY',
1289
+ custom = 'CUSTOM',
1082
1290
  unknown = 'UNKNOWN',
1083
1291
  }
1084
1292
 
@@ -0,0 +1,196 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+
5
+ import Hypernative from '.'
6
+ import Mpc from '../../../mpc'
7
+ import portalMock from '../../../__mocks/portal/portal'
8
+ import {
9
+ mockHost,
10
+ mockScanAddressesRequest,
11
+ mockScanAddressesResponse,
12
+ mockScanEVMTxRequest,
13
+ mockScanEVMTxResponse,
14
+ mockScanEip712TxRequest,
15
+ mockScanEip712TxResponse,
16
+ mockScanSolanaTxRequest,
17
+ mockScanSolanaTxResponse,
18
+ mockScanNftRequest,
19
+ mockScanNftResponse,
20
+ mockScanTokenRequest,
21
+ mockScanTokenResponse,
22
+ mockScanUrlRequest,
23
+ mockScanUrlResponse,
24
+ } from '../../../__mocks/constants'
25
+
26
+ describe('Hypernative', () => {
27
+ let hypernative: Hypernative
28
+ let mpc: Mpc
29
+
30
+ beforeEach(() => {
31
+ jest.clearAllMocks()
32
+
33
+ portalMock.host = mockHost
34
+ mpc = new Mpc({
35
+ portal: portalMock,
36
+ })
37
+
38
+ hypernative = new Hypernative({ mpc })
39
+ })
40
+
41
+ describe('scanEVMTx', () => {
42
+ it('should call mpc.scanEVMTx with the correct arguments', async () => {
43
+ const spy = jest
44
+ .spyOn(mpc, 'scanEVMTx')
45
+ .mockResolvedValue(mockScanEVMTxResponse)
46
+
47
+ const result = await hypernative.scanEVMTx(mockScanEVMTxRequest)
48
+
49
+ expect(spy).toHaveBeenCalledWith(mockScanEVMTxRequest)
50
+ expect(result).toEqual(mockScanEVMTxResponse)
51
+ })
52
+
53
+ it('should propagate errors from mpc.scanEVMTx', async () => {
54
+ const error = new Error('Test error')
55
+ jest.spyOn(mpc, 'scanEVMTx').mockRejectedValue(error)
56
+
57
+ await expect(
58
+ hypernative.scanEVMTx(mockScanEVMTxRequest),
59
+ ).rejects.toThrow('Test error')
60
+ })
61
+ })
62
+
63
+ describe('scanEip712Tx', () => {
64
+ it('should call mpc.scanEip712Tx with the correct arguments', async () => {
65
+ const spy = jest
66
+ .spyOn(mpc, 'scanEip712Tx')
67
+ .mockResolvedValue(mockScanEip712TxResponse)
68
+
69
+ const result = await hypernative.scanEip712Tx(mockScanEip712TxRequest)
70
+
71
+ expect(spy).toHaveBeenCalledWith(mockScanEip712TxRequest)
72
+ expect(result).toEqual(mockScanEip712TxResponse)
73
+ })
74
+
75
+ it('should propagate errors from mpc.scanEip712Tx', async () => {
76
+ const error = new Error('Test error')
77
+ jest.spyOn(mpc, 'scanEip712Tx').mockRejectedValue(error)
78
+
79
+ await expect(
80
+ hypernative.scanEip712Tx(mockScanEip712TxRequest),
81
+ ).rejects.toThrow('Test error')
82
+ })
83
+ })
84
+
85
+ describe('scanSolanaTx', () => {
86
+ it('should call mpc.scanSolanaTx with the correct arguments', async () => {
87
+ const spy = jest
88
+ .spyOn(mpc, 'scanSolanaTx')
89
+ .mockResolvedValue(mockScanSolanaTxResponse)
90
+
91
+ const result = await hypernative.scanSolanaTx(mockScanSolanaTxRequest)
92
+
93
+ expect(spy).toHaveBeenCalledWith(mockScanSolanaTxRequest)
94
+ expect(result).toEqual(mockScanSolanaTxResponse)
95
+ })
96
+
97
+ it('should propagate errors from mpc.scanSolanaTx', async () => {
98
+ const error = new Error('Test error')
99
+ jest.spyOn(mpc, 'scanSolanaTx').mockRejectedValue(error)
100
+
101
+ await expect(
102
+ hypernative.scanSolanaTx(mockScanSolanaTxRequest),
103
+ ).rejects.toThrow('Test error')
104
+ })
105
+ })
106
+
107
+ describe('scanAddresses', () => {
108
+ it('should call mpc.scanAddresses with the correct arguments', async () => {
109
+ const spy = jest
110
+ .spyOn(mpc, 'scanAddresses')
111
+ .mockResolvedValue(mockScanAddressesResponse)
112
+
113
+ const { addresses, ...options } = mockScanAddressesRequest
114
+ const result = await hypernative.scanAddresses(addresses, options)
115
+
116
+ expect(spy).toHaveBeenCalledWith(mockScanAddressesRequest)
117
+ expect(result).toEqual(mockScanAddressesResponse)
118
+ })
119
+
120
+ it('should propagate errors from mpc.scanAddresses', async () => {
121
+ const error = new Error('Test error')
122
+ jest.spyOn(mpc, 'scanAddresses').mockRejectedValue(error)
123
+
124
+ const { addresses, ...options } = mockScanAddressesRequest
125
+ await expect(
126
+ hypernative.scanAddresses(addresses, options),
127
+ ).rejects.toThrow('Test error')
128
+ })
129
+ })
130
+
131
+ describe('scanNFTs', () => {
132
+ it('should call mpc.scanNFTs with the correct arguments', async () => {
133
+ const spy = jest
134
+ .spyOn(mpc, 'scanNFTs')
135
+ .mockResolvedValue(mockScanNftResponse)
136
+
137
+ const result = await hypernative.scanNFTs(mockScanNftRequest)
138
+
139
+ expect(spy).toHaveBeenCalledWith(mockScanNftRequest)
140
+ expect(result).toEqual(mockScanNftResponse)
141
+ })
142
+
143
+ it('should propagate errors from mpc.scanNFTs', async () => {
144
+ const error = new Error('Test error')
145
+ jest.spyOn(mpc, 'scanNFTs').mockRejectedValue(error)
146
+
147
+ await expect(hypernative.scanNFTs(mockScanNftRequest)).rejects.toThrow(
148
+ 'Test error',
149
+ )
150
+ })
151
+ })
152
+
153
+ describe('scanTokens', () => {
154
+ it('should call mpc.scanTokens with the correct arguments', async () => {
155
+ const spy = jest
156
+ .spyOn(mpc, 'scanTokens')
157
+ .mockResolvedValue(mockScanTokenResponse)
158
+
159
+ const result = await hypernative.scanTokens(mockScanTokenRequest)
160
+
161
+ expect(spy).toHaveBeenCalledWith(mockScanTokenRequest)
162
+ expect(result).toEqual(mockScanTokenResponse)
163
+ })
164
+
165
+ it('should propagate errors from mpc.scanTokens', async () => {
166
+ const error = new Error('Test error')
167
+ jest.spyOn(mpc, 'scanTokens').mockRejectedValue(error)
168
+
169
+ await expect(
170
+ hypernative.scanTokens(mockScanTokenRequest),
171
+ ).rejects.toThrow('Test error')
172
+ })
173
+ })
174
+
175
+ describe('scanURL', () => {
176
+ it('should call mpc.scanUrl with the correct arguments', async () => {
177
+ const spy = jest
178
+ .spyOn(mpc, 'scanUrl')
179
+ .mockResolvedValue(mockScanUrlResponse)
180
+
181
+ const result = await hypernative.scanURL(mockScanUrlRequest)
182
+
183
+ expect(spy).toHaveBeenCalledWith(mockScanUrlRequest)
184
+ expect(result).toEqual(mockScanUrlResponse)
185
+ })
186
+
187
+ it('should propagate errors from mpc.scanUrl', async () => {
188
+ const error = new Error('Test error')
189
+ jest.spyOn(mpc, 'scanUrl').mockRejectedValue(error)
190
+
191
+ await expect(hypernative.scanURL(mockScanUrlRequest)).rejects.toThrow(
192
+ 'Test error',
193
+ )
194
+ })
195
+ })
196
+ })
@@ -0,0 +1,106 @@
1
+ import Mpc from '../../../mpc'
2
+ import {
3
+ ScreenAddressApiResponse,
4
+ ScanEVMRequest,
5
+ ScanEVMResponse,
6
+ ScanEip712Request,
7
+ ScanEip712Response,
8
+ ScanSolanaRequest,
9
+ ScanSolanaResponse,
10
+ ScanNftsRequest,
11
+ ScanNftsResponse,
12
+ ScanTokensRequest,
13
+ ScanTokensResponse,
14
+ ScanUrlRequest,
15
+ ScanUrlResponse,
16
+ ScreenAddressRequestOptions,
17
+ } from '../../../../hypernative'
18
+
19
+ export default class Hypernative {
20
+ private mpc: Mpc
21
+
22
+ constructor({ mpc }: { mpc: Mpc }) {
23
+ this.mpc = mpc
24
+ }
25
+
26
+ /**
27
+ * Scans an EIP-155 transaction for security risks.
28
+ * @param data - The parameters for the EIP-155 transaction scan request.
29
+ * @returns A `ScanEVMResponse` promise.
30
+ * @throws An error if the operation fails.
31
+ */
32
+ public async scanEVMTx(
33
+ data: ScanEVMRequest,
34
+ ): Promise<ScanEVMResponse> {
35
+ return this.mpc?.scanEVMTx(data)
36
+ }
37
+
38
+ /**
39
+ * Scans an EIP-712 typed message for security risks.
40
+ * @param data - The parameters for the EIP-712 message scan request.
41
+ * @returns A `ScanEip712Response` promise.
42
+ * @throws An error if the operation fails.
43
+ */
44
+ public async scanEip712Tx(
45
+ data: ScanEip712Request,
46
+ ): Promise<ScanEip712Response> {
47
+ return this.mpc?.scanEip712Tx(data)
48
+ }
49
+
50
+ /**
51
+ * Scans a Solana transaction for security risks.
52
+ * @param data - The parameters for the Solana transaction scan request.
53
+ * @returns A `ScanSolanaResponse` promise.
54
+ * @throws An error if the operation fails.
55
+ */
56
+ public async scanSolanaTx(
57
+ data: ScanSolanaRequest,
58
+ ): Promise<ScanSolanaResponse> {
59
+ return this.mpc?.scanSolanaTx(data)
60
+ }
61
+
62
+ /**
63
+ * Scans addresses for security risks and flags.
64
+ * @param data - The parameters for the address scan request.
65
+ * @returns A `ScreenAddressApiResponse` promise.
66
+ * @throws An error if the operation fails.
67
+ */
68
+ public async scanAddresses(
69
+ addresses: string[],
70
+ options?: ScreenAddressRequestOptions,
71
+ ): Promise<ScreenAddressApiResponse> {
72
+ return this.mpc?.scanAddresses({ addresses, ...options })
73
+ }
74
+
75
+ /**
76
+ * Scans NFTs for security risks.
77
+ * @param data - The parameters for the NFT scan request.
78
+ * @returns A `ScanNftResponse` promise.
79
+ * @throws An error if the operation fails.
80
+ */
81
+ public async scanNFTs(nfts: ScanNftsRequest): Promise<ScanNftsResponse> {
82
+ return this.mpc?.scanNFTs(nfts)
83
+ }
84
+
85
+ /**
86
+ * Scans tokens for security risks.
87
+ * @param data - The parameters for the token scan request.
88
+ * @returns A `ScanTokenResponse` promise.
89
+ * @throws An error if the operation fails.
90
+ */
91
+ public async scanTokens(
92
+ tokens: ScanTokensRequest,
93
+ ): Promise<ScanTokensResponse> {
94
+ return this.mpc?.scanTokens(tokens)
95
+ }
96
+
97
+ /**
98
+ * Scans a URL for malicious content.
99
+ * @param data - The parameters for the URL scan request.
100
+ * @returns A `ScanUrlResponse` promise.
101
+ * @throws An error if the operation fails.
102
+ */
103
+ public async scanURL(url: ScanUrlRequest): Promise<ScanUrlResponse> {
104
+ return this.mpc?.scanUrl(url)
105
+ }
106
+ }
@@ -0,0 +1,14 @@
1
+ import Mpc from '../../mpc'
2
+ import Hypernative from './hypernative'
3
+
4
+ /**
5
+ * This class is a container for the Hypernative class.
6
+ * In the future, Security domain logic should be here.
7
+ */
8
+ export default class Security {
9
+ public hypernative: Hypernative
10
+
11
+ constructor({ mpc }: { mpc: Mpc }) {
12
+ this.hypernative = new Hypernative({ mpc })
13
+ }
14
+ }