@portal-hq/web 3.7.0 → 3.8.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.
package/src/mpc/index.ts CHANGED
@@ -56,8 +56,6 @@ import {
56
56
  YieldXyzManageYieldResponse,
57
57
  YieldXyzTrackTransactionRequest,
58
58
  YieldXyzTrackTransactionResponse,
59
- } from '../../yieldxyz-types'
60
- import {
61
59
  LifiQuoteRequest,
62
60
  LifiQuoteResponse,
63
61
  LifiRoutesRequest,
@@ -66,8 +64,6 @@ import {
66
64
  LifiStatusResponse,
67
65
  LifiStepTransactionRequest,
68
66
  LifiStepTransactionResponse,
69
- } from '../../lifi-types'
70
- import {
71
67
  ZeroExOptions,
72
68
  ZeroExPriceRequest,
73
69
  ZeroExPriceResponse,
@@ -75,9 +71,6 @@ import {
75
71
  ZeroExQuoteResponse,
76
72
  ZeroExSourcesRequest,
77
73
  ZeroExSourcesResponse,
78
- } from '../../zero-x'
79
- import {
80
- ScreenAddressApiResponse,
81
74
  ScanEVMRequest,
82
75
  ScanEVMResponse,
83
76
  ScanEip712Request,
@@ -90,10 +83,10 @@ import {
90
83
  ScanTokensResponse,
91
84
  ScanUrlRequest,
92
85
  ScanUrlResponse,
93
- ScreenAddressRequestOptions,
94
- } from '../../hypernative'
86
+ } from '../shared/types'
87
+ import { ScreenAddressApiResponse, ScreenAddressRequestOptions } from '../../hypernative'
95
88
 
96
- const WEB_SDK_VERSION = '3.7.0'
89
+ const WEB_SDK_VERSION = '3.8.0'
97
90
 
98
91
  class Mpc {
99
92
  public iframe?: HTMLIFrameElement
@@ -129,108 +122,44 @@ class Mpc {
129
122
  // Noop
130
123
  },
131
124
  ): Promise<BackupResponse> {
132
- const message = {
133
- type: 'portal:wasm:backup',
134
- data,
135
- }
136
-
137
125
  // validates password config for password backup
138
126
  this.validateBackupConfig(data)
139
127
 
140
- return new Promise((resolve, reject) => {
141
- // Create a function to be bound when backup is triggered
142
- const handleBackup = (event: MessageEvent<WorkerResult>) => {
143
- const { type, data: result } = event.data
144
- const { origin } = event
145
-
146
- // ignore any broadcast postMessages
147
- if (origin !== this.getOrigin()) {
148
- return
149
- }
150
-
151
- if (type === 'portal:wasm:backupError') {
152
- // Remove the event listeners
153
- window.removeEventListener('message', handleBackup)
154
- window.removeEventListener('message', handleProgress)
155
-
156
- // Reject the promise with the error
157
- return reject(new PortalMpcError(result as PortalError))
158
- } else if (type === 'portal:wasm:backupResult') {
159
- // Remove the event listeners
160
- window.removeEventListener('message', handleBackup)
161
- window.removeEventListener('message', handleProgress)
162
-
163
- const resultData = result as Record<string, unknown>
164
- const backupIds = Array.isArray(resultData.backupIds)
165
- ? (resultData.backupIds as string[])
166
- : []
167
- const storageCallback = async () => {
168
- await this.setBackupStatus('STORED_CLIENT_BACKUP_SHARE', backupIds)
169
- }
170
-
171
- // Resolve the promise with the result
172
- resolve({
173
- cipherText: resultData.cipherText as string,
174
- encryptionKey:
175
- typeof resultData.encryptionKey === 'string'
176
- ? (resultData.encryptionKey as string)
177
- : undefined,
178
- storageCallback,
179
- })
180
- }
181
- }
182
-
183
- const handleProgress = (message: MessageEvent<WorkerResult>) => {
184
- const { type, data: status } = message.data
185
- const { origin } = message
186
-
187
- // ignore any broadcast postMessages
188
- if (origin !== this.getOrigin()) {
189
- return
128
+ return this.handleRequestToIframeAndPost({
129
+ methodMessage: 'portal:wasm:backup',
130
+ errorMessage: 'portal:wasm:backupError',
131
+ resultMessage: 'portal:wasm:backupResult',
132
+ data,
133
+ progressMessage: 'portal:wasm:backupProgress',
134
+ progressCallback: progress,
135
+ mapReturnValue: (result: Record<string, unknown>) => {
136
+ const resultData = result as Record<string, unknown>
137
+ const backupIds = Array.isArray(resultData.backupIds)
138
+ ? (resultData.backupIds as string[])
139
+ : []
140
+ const storageCallback = async () => {
141
+ await this.setBackupStatus('STORED_CLIENT_BACKUP_SHARE', backupIds)
190
142
  }
191
143
 
192
- if (type === 'portal:wasm:backupProgress') {
193
- void progress(status as MpcStatus)
144
+ return {
145
+ cipherText: result.cipherText as string,
146
+ encryptionKey:
147
+ typeof resultData.encryptionKey === 'string'
148
+ ? (resultData.encryptionKey as string)
149
+ : undefined,
150
+ storageCallback,
194
151
  }
195
- }
196
-
197
- // Bind the function to the message event
198
- window.addEventListener('message', handleBackup)
199
- window.addEventListener('message', handleProgress)
200
-
201
- // Send the request to the iframe
202
- this.postMessage(message)
152
+ },
203
153
  })
204
154
  }
205
155
 
206
156
  public clearLocalWallet(): Promise<boolean> {
207
- return new Promise((resolve) => {
208
- const handleClearLocalWallet = (event: MessageEvent<WorkerResult>) => {
209
- const { type } = event.data
210
- const { origin } = event
211
-
212
- // ignore any broadcast postMessages
213
- if (origin !== this.getOrigin()) {
214
- return
215
- }
216
-
217
- if (type === 'portal:destroyResult') {
218
- // Remove the event listener
219
- window.removeEventListener('message', handleClearLocalWallet)
220
-
221
- // Resolve the promise with the result
222
- resolve(true)
223
- }
224
- }
225
-
226
- // Bind the function to the message event
227
- window.addEventListener('message', handleClearLocalWallet)
228
-
229
- // Send the request to the iframe
230
- this.postMessage({
231
- type: 'portal:destroy',
232
- data: {},
233
- })
157
+ return this.handleRequestToIframeAndPost({
158
+ methodMessage: 'portal:destroy',
159
+ errorMessage: 'portal:destroyError', // This message is not used in the iframe
160
+ resultMessage: 'portal:destroyResult',
161
+ data: {},
162
+ mapReturnValue: () => true,
234
163
  })
235
164
  }
236
165
 
@@ -240,95 +169,22 @@ class Mpc {
240
169
  // Noop
241
170
  },
242
171
  ): Promise<string> {
243
- const message = {
244
- type: 'portal:wasm:generate',
172
+ return this.handleRequestToIframeAndPost({
173
+ methodMessage: 'portal:wasm:generate',
174
+ errorMessage: 'portal:wasm:generateError',
175
+ resultMessage: 'portal:wasm:generateResult',
245
176
  data,
246
- }
247
-
248
- return new Promise((resolve, reject) => {
249
- // Create a function to be bound when generate is triggered
250
- const handleGenerate = (event: MessageEvent<WorkerResult>) => {
251
- const { type, data: result } = event.data
252
- const { origin } = event
253
-
254
- // ignore any broadcast postMessages
255
- if (origin !== this.getOrigin()) {
256
- return
257
- }
258
-
259
- // Handle errors
260
- if (type === 'portal:wasm:generateError') {
261
- // Remove the event listeners
262
- window.removeEventListener('message', handleGenerate)
263
- window.removeEventListener('message', handleProgress)
264
-
265
- // Reject the promise with the error
266
- return reject(new PortalMpcError(result as PortalError))
267
- } else if (type === 'portal:wasm:generateResult') {
268
- // Remove the event listeners
269
- window.removeEventListener('message', handleGenerate)
270
- window.removeEventListener('message', handleProgress)
271
-
272
- // Resolve the promise with the result
273
- resolve(result as string)
274
- }
275
- }
276
-
277
- const handleProgress = (message: MessageEvent<WorkerResult>) => {
278
- const { type, data: status } = message.data
279
- const { origin } = message
280
-
281
- // ignore any broadcast postMessages
282
- if (origin !== this.getOrigin()) {
283
- return
284
- }
285
-
286
- if (type === 'portal:wasm:generateProgress') {
287
- void progress(status as MpcStatus)
288
- }
289
- }
290
-
291
- // Bind the function to the message event
292
- window.addEventListener('message', handleGenerate)
293
- window.addEventListener('message', handleProgress)
294
-
295
- // Send the request to the iframe
296
- this.postMessage(message)
177
+ progressMessage: 'portal:wasm:generateProgress',
178
+ progressCallback: progress,
297
179
  })
298
180
  }
299
181
 
300
182
  public async getAddress(): Promise<string> {
301
- const message = {
302
- type: 'portal:address',
183
+ return this.handleRequestToIframeAndPost({
184
+ methodMessage: 'portal:address',
185
+ errorMessage: 'portal:addressError', // This message is not used in the iframe
186
+ resultMessage: 'portal:addressResult',
303
187
  data: {},
304
- }
305
-
306
- return new Promise((resolve) => {
307
- // Create a function to be bound when getAddress is triggered
308
- const handleGetAddress = (event: MessageEvent<WorkerResult>) => {
309
- const { type, data: result } = event.data
310
- const { origin } = event
311
-
312
- // ignore any broadcast postMessages
313
- if (origin !== this.getOrigin()) {
314
- return
315
- }
316
-
317
- // Check that the message is the one we're looking for
318
- if (type === 'portal:addressResult') {
319
- // Remove the event listener
320
- window.removeEventListener('message', handleGetAddress)
321
-
322
- // Resolve the promise with the result
323
- resolve(result as string)
324
- }
325
- }
326
-
327
- // Bind the function to the message event
328
- window.addEventListener('message', handleGetAddress)
329
-
330
- // Send the request to the iframe
331
- this.postMessage(message)
332
188
  })
333
189
  }
334
190
 
@@ -338,160 +194,45 @@ class Mpc {
338
194
  // Noop
339
195
  },
340
196
  ): Promise<string> {
341
- return new Promise((resolve, reject) => {
342
- const handleRecover = (message: MessageEvent<WorkerResult>) => {
343
- const { type, data } = message.data
344
- const { origin } = message
345
-
346
- // ignore any broadcast postMessages
347
- if (origin !== this.getOrigin()) {
348
- return
349
- }
350
-
351
- if (type === 'portal:wasm:recoverError') {
352
- // Remove the event listeners
353
- window.removeEventListener('message', handleRecover)
354
- window.removeEventListener('message', handleProgress)
355
-
356
- reject(new PortalMpcError(data as PortalError))
357
- } else if (type === 'portal:wasm:recoverResult') {
358
- // Remove the event listeners
359
- window.removeEventListener('message', handleRecover)
360
- window.removeEventListener('message', handleProgress)
361
-
362
- resolve(data as string)
363
- }
364
- }
365
-
366
- const handleProgress = (message: MessageEvent<WorkerResult>) => {
367
- const { type, data: status } = message.data
368
- const { origin } = message
369
-
370
- // ignore any broadcast postMessages
371
- if (origin !== this.getOrigin()) {
372
- return
373
- }
374
-
375
- if (type === 'portal:wasm:recoverProgress') {
376
- void progress(status as MpcStatus)
377
- }
378
- }
379
-
380
- window.addEventListener('message', handleRecover)
381
- window.addEventListener('message', handleProgress)
382
-
383
- this.postMessage({
384
- type: 'portal:wasm:recover',
385
- data,
386
- })
197
+ return this.handleRequestToIframeAndPost({
198
+ methodMessage: 'portal:wasm:recover',
199
+ errorMessage: 'portal:wasm:recoverError',
200
+ resultMessage: 'portal:wasm:recoverResult',
201
+ data,
202
+ progressMessage: 'portal:wasm:recoverProgress',
203
+ progressCallback: progress,
387
204
  })
388
205
  }
389
206
 
390
207
  public async eject(data: EjectArgs): Promise<EjectResult> {
391
- return new Promise((resolve, reject) => {
392
- const handleEject = (message: MessageEvent<WorkerResult>) => {
393
- const { type, data: result } = message.data
394
- const { origin } = message
395
-
396
- // ignore any broadcast postMessages
397
- if (origin !== this.getOrigin()) {
398
- return
399
- }
400
-
401
- if (type === 'portal:wasm:ejectError') {
402
- // Remove the event listeners
403
- window.removeEventListener('message', handleEject)
404
-
405
- reject(new PortalMpcError(result as PortalError))
406
- } else if (type === 'portal:wasm:ejectResult') {
407
- // Remove the event listeners
408
- window.removeEventListener('message', handleEject)
409
-
410
- resolve(result as EjectResult)
411
- }
412
- }
413
-
414
- window.addEventListener('message', handleEject)
415
-
416
- this.postMessage({
417
- type: 'portal:wasm:eject',
418
- data,
419
- })
208
+ return this.handleRequestToIframeAndPost({
209
+ methodMessage: 'portal:wasm:eject',
210
+ errorMessage: 'portal:wasm:ejectError',
211
+ resultMessage: 'portal:wasm:ejectResult',
212
+ data,
420
213
  })
421
214
  }
422
215
 
423
216
  public async ejectPrivateKeys(
424
217
  data: EjectPrivateKeysArgs,
425
218
  ): Promise<EjectPrivateKeysResult> {
426
- return new Promise((resolve, reject) => {
427
- const handleEject = (message: MessageEvent<WorkerResult>) => {
428
- const { type, data: result } = message.data
429
- const { origin } = message
430
-
431
- // ignore any broadcast postMessages
432
- if (origin !== this.getOrigin()) {
433
- return
434
- }
435
-
436
- if (type === 'portal:wasm:ejectPrivateKeysError') {
437
- // Remove the event listeners
438
- window.removeEventListener('message', handleEject)
439
-
440
- reject(new PortalMpcError(result as PortalError))
441
- } else if (type === 'portal:wasm:ejectPrivateKeysResult') {
442
- // Remove the event listeners
443
- window.removeEventListener('message', handleEject)
444
-
445
- resolve(result as EjectPrivateKeysResult)
446
- }
447
- }
448
-
449
- window.addEventListener('message', handleEject)
450
-
451
- this.postMessage({
452
- type: 'portal:wasm:ejectPrivateKeys',
453
- data,
454
- })
219
+ return this.handleRequestToIframeAndPost({
220
+ methodMessage: 'portal:wasm:ejectPrivateKeys',
221
+ errorMessage: 'portal:wasm:ejectPrivateKeysError',
222
+ resultMessage: 'portal:wasm:ejectPrivateKeysResult',
223
+ data,
455
224
  })
456
225
  }
457
226
 
458
227
  public async rawSign(curve: PortalCurve, param: string): Promise<string> {
459
- return new Promise((resolve, reject) => {
460
- const handleRawSign = (event: MessageEvent<WorkerResult>) => {
461
- const { type, data: result } = event.data
462
- const { origin } = event
463
-
464
- // ignore any broadcast postMessages
465
- if (origin !== this.getOrigin()) {
466
- return
467
- }
468
-
469
- if (type === 'portal:mpc:rawSignError') {
470
- // Remove the event listeners
471
- window.removeEventListener('message', handleRawSign)
472
-
473
- // Reject the promise with the error
474
- return reject(new PortalMpcError(result as PortalError))
475
- } else if (type === 'portal:mpc:rawSignResult') {
476
- // Remove the event listeners
477
- window.removeEventListener('message', handleRawSign)
478
-
479
- // Resolve the promise with the result
480
- resolve(result as string)
481
- }
482
- }
483
-
484
- // Bind the function to the message event
485
- window.addEventListener('message', handleRawSign)
486
-
487
- // Send the request to the iframe
488
- this.postMessage({
489
- type: 'portal:mpc:rawSign',
490
- data: {
491
- curve,
492
- param,
493
- },
494
- })
228
+ return this.handleRequestToIframeAndPost({
229
+ methodMessage: 'portal:mpc:rawSign',
230
+ errorMessage: 'portal:mpc:rawSignError',
231
+ resultMessage: 'portal:mpc:rawSignResult',
232
+ data: {
233
+ curve,
234
+ param,
235
+ },
495
236
  })
496
237
  }
497
238
 
@@ -501,94 +242,22 @@ class Mpc {
501
242
  // Noop
502
243
  },
503
244
  ): Promise<string> {
504
- return new Promise((resolve, reject) => {
505
- // Create a function to be bound when sign is triggered
506
- const handleSign = (event: MessageEvent<WorkerResult>) => {
507
- const { type, data: result } = event.data
508
- const { origin } = event
509
-
510
- // ignore any broadcast postMessages
511
- if (origin !== this.getOrigin()) {
512
- return
513
- }
514
-
515
- if (type === 'portal:wasm:signError') {
516
- // Remove the event listeners
517
- window.removeEventListener('message', handleSign)
518
- window.removeEventListener('message', handleProgress)
519
-
520
- // Reject the promise with the error
521
- return reject(new PortalMpcError(result as PortalError))
522
- } else if (type === 'portal:wasm:signResult') {
523
- // Remove the event listeners
524
- window.removeEventListener('message', handleSign)
525
- window.removeEventListener('message', handleProgress)
526
-
527
- // Resolve the promise with the result
528
- resolve(result as string)
529
- }
530
- }
531
-
532
- const handleProgress = (message: MessageEvent<WorkerResult>) => {
533
- const { type, data: status } = message.data
534
- const { origin } = message
535
-
536
- // ignore any broadcast postMessages
537
- if (origin !== this.getOrigin()) {
538
- return
539
- }
540
-
541
- if (type === 'portal:wasm:signProgress') {
542
- void progress(status as MpcStatus)
543
- }
544
- }
545
-
546
- // Bind the functions to the message event
547
- window.addEventListener('message', handleSign)
548
- window.addEventListener('message', handleProgress)
549
-
550
- // Send the request to the iframe
551
- this.postMessage({
552
- type: 'portal:wasm:sign',
553
- data,
554
- })
245
+ return this.handleRequestToIframeAndPost({
246
+ methodMessage: 'portal:wasm:sign',
247
+ errorMessage: 'portal:wasm:signError',
248
+ resultMessage: 'portal:wasm:signResult',
249
+ data,
250
+ progressMessage: 'portal:wasm:signProgress',
251
+ progressCallback: progress,
555
252
  })
556
253
  }
557
254
 
558
255
  public async checkSharesOnDevice(): Promise<SharesOnDeviceResponse> {
559
- return new Promise((resolve, reject) => {
560
- const handleCheckSharesOnDevice = (event: MessageEvent<WorkerResult>) => {
561
- const { type, data } = event.data
562
- const { origin } = event
563
-
564
- // ignore any broadcast postMessages
565
- if (origin !== this.getOrigin()) {
566
- return
567
- }
568
-
569
- if (type === 'portal:checkSharesOnDeviceError') {
570
- // Remove the event listener
571
- window.removeEventListener('message', handleCheckSharesOnDevice)
572
-
573
- // Reject the promise with the error
574
- return reject(new PortalMpcError(data as PortalError))
575
- } else if (type === 'portal:checkSharesOnDeviceResult') {
576
- // Remove the event listener
577
- window.removeEventListener('message', handleCheckSharesOnDevice)
578
-
579
- // Resolve the promise with the result
580
- resolve(data as SharesOnDeviceResponse)
581
- }
582
- }
583
-
584
- // Bind the function to the message event
585
- window.addEventListener('message', handleCheckSharesOnDevice)
586
-
587
- // Send the request to the iframe
588
- this.postMessage({
589
- type: 'portal:checkSharesOnDevice',
590
- data: {},
591
- })
256
+ return this.handleRequestToIframeAndPost({
257
+ methodMessage: 'portal:checkSharesOnDevice',
258
+ errorMessage: 'portal:checkSharesOnDeviceError',
259
+ resultMessage: 'portal:checkSharesOnDeviceResult',
260
+ data: {},
592
261
  })
593
262
  }
594
263
 
@@ -597,39 +266,11 @@ class Mpc {
597
266
  *******************************/
598
267
 
599
268
  public async getBalances(chainId?: string): Promise<Balance[]> {
600
- return new Promise((resolve, reject) => {
601
- const handleGetBalances = (event: MessageEvent<WorkerResult>) => {
602
- const { type, data } = event.data
603
- const { origin } = event
604
-
605
- // ignore any broadcast postMessages
606
- if (origin !== this.getOrigin()) {
607
- return
608
- }
609
-
610
- if (type === 'portal:getBalancesError') {
611
- // Remove the event listener
612
- window.removeEventListener('message', handleGetBalances)
613
-
614
- // Reject the promise with the error
615
- return reject(new PortalMpcError(data as PortalError))
616
- } else if (type === 'portal:getBalancesResult') {
617
- // Remove the event listener
618
- window.removeEventListener('message', handleGetBalances)
619
-
620
- // Resolve the promise with the result
621
- resolve(data as Balance[])
622
- }
623
- }
624
-
625
- // Bind the function to the message event
626
- window.addEventListener('message', handleGetBalances)
627
-
628
- // Send the request to the iframe
629
- this.postMessage({
630
- type: 'portal:getBalances',
631
- data: { chainId },
632
- })
269
+ return this.handleRequestToIframeAndPost({
270
+ methodMessage: 'portal:getBalances',
271
+ errorMessage: 'portal:getBalancesError',
272
+ resultMessage: 'portal:getBalancesResult',
273
+ data: { chainId },
633
274
  })
634
275
  }
635
276
 
@@ -637,190 +278,50 @@ class Mpc {
637
278
  chainId: string,
638
279
  params: FundParams,
639
280
  ): Promise<FundResponse> {
640
- return new Promise((resolve, reject) => {
641
- const handleFund = (event: MessageEvent<WorkerResult>) => {
642
- const { type, data } = event.data
643
- const { origin } = event
644
-
645
- // Ignore any broadcast postMessages
646
- if (origin !== this.getOrigin()) {
647
- return
648
- }
649
-
650
- if (type === 'portal:fundError') {
651
- // Remove the event listener
652
- window.removeEventListener('message', handleFund)
653
-
654
- // Reject the promise with the error
655
- return reject(new PortalMpcError(data as PortalError))
656
- } else if (type === 'portal:fundResult') {
657
- // Remove the event listener
658
- window.removeEventListener('message', handleFund)
659
-
660
- // Resolve the promise with the result
661
- resolve(data as FundResponse)
662
- }
663
- }
664
-
665
- // Bind the function to the message event
666
- window.addEventListener('message', handleFund)
667
-
668
- // Send the request to the iframe
669
- this.postMessage({
670
- type: 'portal:fund',
671
- data: { chainId, params },
672
- })
281
+ return this.handleRequestToIframeAndPost({
282
+ methodMessage: 'portal:fund',
283
+ errorMessage: 'portal:fundError',
284
+ resultMessage: 'portal:fundResult',
285
+ data: { chainId, params },
673
286
  })
674
287
  }
675
288
 
676
289
  public async getClient(): Promise<ClientResponse> {
677
- return new Promise((resolve, reject) => {
678
- const handleGetClient = (event: MessageEvent<WorkerResult>) => {
679
- const { type, data } = event.data
680
- const { origin } = event
681
-
682
- // ignore any broadcast postMessages
683
- if (origin !== this.getOrigin()) {
684
- return
685
- }
686
-
687
- if (type === 'portal:getClientError') {
688
- // Remove the event listener
689
- window.removeEventListener('message', handleGetClient)
690
-
691
- // Reject the promise with the error
692
- return reject(new PortalMpcError(data as PortalError))
693
- } else if (type === 'portal:getClientResult') {
694
- // Remove the event listener
695
- window.removeEventListener('message', handleGetClient)
696
-
697
- // Resolve the promise with the result
698
- resolve(data as ClientResponse)
699
- }
700
- }
701
-
702
- // Bind the function to the message event
703
- window.addEventListener('message', handleGetClient)
704
-
705
- // Send the request to the iframe
706
- this.postMessage({
707
- type: 'portal:getClient',
708
- data: {},
709
- })
290
+ return this.handleRequestToIframeAndPost({
291
+ methodMessage: 'portal:getClient',
292
+ errorMessage: 'portal:getClientError',
293
+ resultMessage: 'portal:getClientResult',
294
+ data: {},
710
295
  })
711
296
  }
712
297
 
713
298
  public async getNFTs(chainId?: string): Promise<NFT[]> {
714
- return new Promise((resolve, reject) => {
715
- const handleGetNFTs = (event: MessageEvent<WorkerResult>) => {
716
- const { type, data } = event.data
717
- const { origin } = event
718
-
719
- // ignore any broadcast postMessages
720
- if (origin !== this.getOrigin()) {
721
- return
722
- }
723
-
724
- if (type === 'portal:getNFTsError') {
725
- // Remove the event listener
726
- window.removeEventListener('message', handleGetNFTs)
727
-
728
- // Reject the promise with the error
729
- return reject(new PortalMpcError(data as PortalError))
730
- } else if (type === 'portal:getNFTsResult') {
731
- // Remove the event listener
732
- window.removeEventListener('message', handleGetNFTs)
733
-
734
- // Resolve the promise with the result
735
- resolve(data as NFT[])
736
- }
737
- }
738
-
739
- // Bind the function to the message event
740
- window.addEventListener('message', handleGetNFTs)
741
-
742
- // Send the request to the iframe
743
- this.postMessage({
744
- type: 'portal:getNFTs',
745
- data: { chainId },
746
- })
299
+ return this.handleRequestToIframeAndPost({
300
+ methodMessage: 'portal:getNFTs',
301
+ errorMessage: 'portal:getNFTsError',
302
+ resultMessage: 'portal:getNFTsResult',
303
+ data: { chainId },
747
304
  })
748
305
  }
749
306
 
750
307
  public async getNFTAssets(chainId: string): Promise<NFTAsset[]> {
751
- return new Promise((resolve, reject) => {
752
- const handleGetNFTAssets = (event: MessageEvent<WorkerResult>) => {
753
- const { type, data } = event.data
754
- const { origin } = event
755
-
756
- // ignore any broadcast postMessages
757
- if (origin !== this.getOrigin()) {
758
- return
759
- }
760
-
761
- if (type === 'portal:getNFTAssetsError') {
762
- // Remove the event listener
763
- window.removeEventListener('message', handleGetNFTAssets)
764
-
765
- // Reject the promise with the error
766
- return reject(new PortalMpcError(data as PortalError))
767
- } else if (type === 'portal:getNFTAssetsResult') {
768
- // Remove the event listener
769
- window.removeEventListener('message', handleGetNFTAssets)
770
-
771
- // Resolve the promise with the result
772
- resolve(data as NFTAsset[])
773
- }
774
- }
775
-
776
- // Bind the function to the message event
777
- window.addEventListener('message', handleGetNFTAssets)
778
-
779
- // Send the request to the iframe
780
- this.postMessage({
781
- type: 'portal:getNFTAssets',
782
- data: { chainId },
783
- })
784
- })
785
- }
786
-
787
- public async getAssets(
788
- chainId: string,
789
- includeNfts = false,
790
- ): Promise<GetAssetsResponse> {
791
- return new Promise((resolve, reject) => {
792
- const handleGetAssets = (event: MessageEvent<WorkerResult>) => {
793
- const { type, data } = event.data
794
- const { origin } = event
795
-
796
- // ignore any broadcast postMessages
797
- if (origin !== this.getOrigin()) {
798
- return
799
- }
800
-
801
- if (type === 'portal:getAssetsError') {
802
- // Remove the event listener
803
- window.removeEventListener('message', handleGetAssets)
804
-
805
- // Reject the promise with the error
806
- return reject(new PortalMpcError(data as PortalError))
807
- } else if (type === 'portal:getAssetsResult') {
808
- // Remove the event listener
809
- window.removeEventListener('message', handleGetAssets)
810
-
811
- // Resolve the promise with the result
812
- resolve(data as GetAssetsResponse)
813
- }
814
- }
815
-
816
- // Bind the function to the message event
817
- window.addEventListener('message', handleGetAssets)
308
+ return this.handleRequestToIframeAndPost({
309
+ methodMessage: 'portal:getNFTAssets',
310
+ errorMessage: 'portal:getNFTAssetsError',
311
+ resultMessage: 'portal:getNFTAssetsResult',
312
+ data: { chainId },
313
+ })
314
+ }
818
315
 
819
- // Send the request to the iframe
820
- this.postMessage({
821
- type: 'portal:getAssets',
822
- data: { chainId, includeNfts },
823
- })
316
+ public async getAssets(
317
+ chainId: string,
318
+ includeNfts = false,
319
+ ): Promise<GetAssetsResponse> {
320
+ return this.handleRequestToIframeAndPost({
321
+ methodMessage: 'portal:getAssets',
322
+ errorMessage: 'portal:getAssetsError',
323
+ resultMessage: 'portal:getAssetsResult',
324
+ data: { chainId, includeNfts },
824
325
  })
825
326
  }
826
327
 
@@ -830,39 +331,11 @@ class Mpc {
830
331
  token: string,
831
332
  amount: string,
832
333
  ): Promise<BuiltTransaction> {
833
- return new Promise((resolve, reject) => {
834
- const handlebuildTransaction = (event: MessageEvent<WorkerResult>) => {
835
- const { type, data } = event.data
836
- const { origin } = event
837
-
838
- // ignore any broadcast postMessages
839
- if (origin !== this.getOrigin()) {
840
- return
841
- }
842
-
843
- if (type === 'portal:buildTransactionError') {
844
- // Remove the event listener
845
- window.removeEventListener('message', handlebuildTransaction)
846
-
847
- // Reject the promise with the error
848
- return reject(new PortalMpcError(data as PortalError))
849
- } else if (type === 'portal:buildTransactionResult') {
850
- // Remove the event listener
851
- window.removeEventListener('message', handlebuildTransaction)
852
-
853
- // Resolve the promise with the result
854
- resolve(data as BuiltTransaction)
855
- }
856
- }
857
-
858
- // Bind the function to the message event
859
- window.addEventListener('message', handlebuildTransaction)
860
-
861
- // Send the request to the iframe
862
- this.postMessage({
863
- type: 'portal:buildTransaction',
864
- data: { chainId, to, token, amount },
865
- })
334
+ return this.handleRequestToIframeAndPost({
335
+ methodMessage: 'portal:buildTransaction',
336
+ errorMessage: 'portal:buildTransactionError',
337
+ resultMessage: 'portal:buildTransactionResult',
338
+ data: { chainId, to, token, amount },
866
339
  })
867
340
  }
868
341
 
@@ -871,42 +344,15 @@ class Mpc {
871
344
  args: QuoteArgs,
872
345
  apiKey?: string,
873
346
  ): Promise<QuoteResponse> {
874
- return new Promise((resolve, reject) => {
875
- const handleGetQuote = (event: MessageEvent<WorkerResult>) => {
876
- const { type, data: result } = event.data
877
- const { origin } = event
878
-
879
- // ignore any broadcast postMessages
880
- if (origin !== this.getOrigin()) {
881
- return
882
- }
883
- if (type === 'portal:swaps:getQuoteError') {
884
- // Remove the event listener
885
- window.removeEventListener('message', handleGetQuote)
886
-
887
- // Reject the promise with the error
888
- return reject(new PortalMpcError(result as PortalError))
889
- } else if (type === 'portal:swaps:getQuoteResult') {
890
- // Remove the event listener
891
- window.removeEventListener('message', handleGetQuote)
892
-
893
- // Resolve the promise with the result
894
- resolve(result as QuoteResponse)
895
- }
896
- }
897
-
898
- // Bind the function to the message event
899
- window.addEventListener('message', handleGetQuote)
900
-
901
- // Send the request to the iframe
902
- this.postMessage({
903
- type: 'portal:swaps:getQuote',
904
- data: {
905
- apiKey,
906
- args,
907
- chainId,
908
- },
909
- })
347
+ return this.handleRequestToIframeAndPost({
348
+ methodMessage: 'portal:swaps:getQuote',
349
+ errorMessage: 'portal:swaps:getQuoteError',
350
+ resultMessage: 'portal:swaps:getQuoteResult',
351
+ data: {
352
+ apiKey,
353
+ args,
354
+ chainId,
355
+ },
910
356
  })
911
357
  }
912
358
 
@@ -914,41 +360,14 @@ class Mpc {
914
360
  chainId: string,
915
361
  apiKey?: string,
916
362
  ): Promise<Record<string, string>> {
917
- return new Promise((resolve, reject) => {
918
- const handleGetSources = (event: MessageEvent<WorkerResult>) => {
919
- const { type, data: result } = event.data
920
- const { origin } = event
921
-
922
- // ignore any broadcast postMessages
923
- if (origin !== this.getOrigin()) {
924
- return
925
- }
926
- if (type === 'portal:swaps:getSourcesError') {
927
- // Remove the event listener
928
- window.removeEventListener('message', handleGetSources)
929
-
930
- // Reject the promise with the error
931
- return reject(new PortalMpcError(result as PortalError))
932
- } else if (type === 'portal:swaps:getSourcesResult') {
933
- // Remove the event listener
934
- window.removeEventListener('message', handleGetSources)
935
-
936
- // Resolve the promise with the result
937
- resolve(result as Record<string, string>)
938
- }
939
- }
940
-
941
- // Bind the function to the message event
942
- window.addEventListener('message', handleGetSources)
943
-
944
- // Send the request to the iframe
945
- this.postMessage({
946
- type: 'portal:swaps:getSources',
947
- data: {
948
- apiKey,
949
- chainId,
950
- },
951
- })
363
+ return this.handleRequestToIframeAndPost({
364
+ methodMessage: 'portal:swaps:getSources',
365
+ errorMessage: 'portal:swaps:getSourcesError',
366
+ resultMessage: 'portal:swaps:getSourcesResult',
367
+ data: {
368
+ apiKey,
369
+ chainId,
370
+ },
952
371
  })
953
372
  }
954
373
 
@@ -958,44 +377,16 @@ class Mpc {
958
377
  offset?: number,
959
378
  order?: GetTransactionsOrder,
960
379
  ): Promise<Transaction[]> {
961
- return new Promise((resolve, reject) => {
962
- const handleGetTransactions = (event: MessageEvent<WorkerResult>) => {
963
- const { type, data } = event.data
964
- const { origin } = event
965
-
966
- // ignore any broadcast postMessages
967
- if (origin !== this.getOrigin()) {
968
- return
969
- }
970
-
971
- if (type === 'portal:getTransactionsError') {
972
- // Remove the event listener
973
- window.removeEventListener('message', handleGetTransactions)
974
-
975
- // Reject the promise with the error
976
- return reject(new PortalMpcError(data as PortalError))
977
- } else if (type === 'portal:getTransactionsResult') {
978
- // Remove the event listener
979
- window.removeEventListener('message', handleGetTransactions)
980
-
981
- // Resolve the promise with the result
982
- resolve(data as Transaction[])
983
- }
984
- }
985
-
986
- // Bind the function to the message event
987
- window.addEventListener('message', handleGetTransactions)
988
-
989
- // Send the request to the iframe
990
- this.postMessage({
991
- type: 'portal:getTransactions',
992
- data: {
993
- chainId,
994
- limit,
995
- offset,
996
- order,
997
- },
998
- })
380
+ return this.handleRequestToIframeAndPost({
381
+ methodMessage: 'portal:getTransactions',
382
+ errorMessage: 'portal:getTransactionsError',
383
+ resultMessage: 'portal:getTransactionsResult',
384
+ data: {
385
+ chainId,
386
+ limit,
387
+ offset,
388
+ order,
389
+ },
999
390
  })
1000
391
  }
1001
392
 
@@ -1003,41 +394,14 @@ class Mpc {
1003
394
  status: string,
1004
395
  backupIds: string[],
1005
396
  ): Promise<boolean> {
1006
- return new Promise((resolve, reject) => {
1007
- const handleSetBackupStatus = (event: MessageEvent<WorkerResult>) => {
1008
- const { type, data } = event.data
1009
- const { origin } = event
1010
-
1011
- // ignore any broadcast postMessages
1012
- if (origin !== this.getOrigin()) {
1013
- return
1014
- }
1015
-
1016
- if (type === 'portal:api:setBackupStatusError') {
1017
- // Remove the event listener
1018
- window.removeEventListener('message', handleSetBackupStatus)
1019
-
1020
- // Reject the promise with the error
1021
- return reject(new PortalMpcError(data as PortalError))
1022
- } else if (type === 'portal:api:setBackupStatusResult') {
1023
- // Remove the event listener
1024
- window.removeEventListener('message', handleSetBackupStatus)
1025
-
1026
- // Resolve the promise with the result
1027
- return resolve(data as boolean)
1028
- }
1029
- }
1030
-
1031
- // Bind the function to the message event
1032
- window.addEventListener('message', handleSetBackupStatus)
1033
-
1034
- this.postMessage({
1035
- type: 'portal:api:setBackupStatus',
1036
- data: {
1037
- backupIds,
1038
- status,
1039
- },
1040
- })
397
+ return this.handleRequestToIframeAndPost({
398
+ methodMessage: 'portal:api:setBackupStatus',
399
+ errorMessage: 'portal:api:setBackupStatusError',
400
+ resultMessage: 'portal:api:setBackupStatusResult',
401
+ data: {
402
+ backupIds,
403
+ status,
404
+ },
1041
405
  })
1042
406
  }
1043
407
 
@@ -1045,42 +409,14 @@ class Mpc {
1045
409
  transaction: SimulateTransactionParam,
1046
410
  chainId?: string,
1047
411
  ): Promise<SimulatedTransaction> {
1048
- return new Promise((resolve, reject) => {
1049
- const handleSimulateTransaction = (event: MessageEvent<WorkerResult>) => {
1050
- const { type, data } = event.data
1051
- const { origin } = event
1052
-
1053
- // ignore any broadcast postMessages
1054
- if (origin !== this.getOrigin()) {
1055
- return
1056
- }
1057
-
1058
- if (type === 'portal:simulateTransactionError') {
1059
- // Remove the event listener
1060
- window.removeEventListener('message', handleSimulateTransaction)
1061
-
1062
- // Reject the promise with the error
1063
- return reject(new PortalMpcError(data as PortalError))
1064
- } else if (type === 'portal:simulateTransactionResult') {
1065
- // Remove the event listener
1066
- window.removeEventListener('message', handleSimulateTransaction)
1067
-
1068
- // Resolve the promise with the result
1069
- resolve(data as SimulatedTransaction)
1070
- }
1071
- }
1072
-
1073
- // Bind the function to the message event
1074
- window.addEventListener('message', handleSimulateTransaction)
1075
-
1076
- // Send the request to the iframe
1077
- this.postMessage({
1078
- type: 'portal:simulateTransaction',
1079
- data: {
1080
- chainId,
1081
- transaction,
1082
- },
1083
- })
412
+ return this.handleRequestToIframeAndPost({
413
+ methodMessage: 'portal:simulateTransaction',
414
+ errorMessage: 'portal:simulateTransactionError',
415
+ resultMessage: 'portal:simulateTransactionResult',
416
+ data: {
417
+ chainId,
418
+ transaction,
419
+ },
1084
420
  })
1085
421
  }
1086
422
 
@@ -1089,43 +425,15 @@ class Mpc {
1089
425
  transaction: EvaluateTransactionParam,
1090
426
  operationType: EvaluateTransactionOperationType = 'all',
1091
427
  ): Promise<EvaluatedTransaction> {
1092
- return new Promise((resolve, reject) => {
1093
- const handleEvaluateTransaction = (event: MessageEvent<WorkerResult>) => {
1094
- const { type, data } = event.data
1095
- const { origin } = event
1096
-
1097
- // ignore any broadcast postMessages
1098
- if (origin !== this.getOrigin()) {
1099
- return
1100
- }
1101
-
1102
- if (type === 'portal:evaluateTransactionError') {
1103
- // Remove the event listener
1104
- window.removeEventListener('message', handleEvaluateTransaction)
1105
-
1106
- // Reject the promise with the error
1107
- return reject(new PortalMpcError(data as PortalError))
1108
- } else if (type === 'portal:evaluateTransactionResult') {
1109
- // Remove the event listener
1110
- window.removeEventListener('message', handleEvaluateTransaction)
1111
-
1112
- // Resolve the promise with the result
1113
- resolve(data as EvaluatedTransaction)
1114
- }
1115
- }
1116
-
1117
- // Bind the function to the message event
1118
- window.addEventListener('message', handleEvaluateTransaction)
1119
-
1120
- // Send the request to the iframe
1121
- this.postMessage({
1122
- type: 'portal:evaluateTransaction',
1123
- data: {
1124
- chainId,
1125
- transaction,
1126
- operationType,
1127
- },
1128
- })
428
+ return this.handleRequestToIframeAndPost({
429
+ methodMessage: 'portal:evaluateTransaction',
430
+ errorMessage: 'portal:evaluateTransactionError',
431
+ resultMessage: 'portal:evaluateTransactionResult',
432
+ data: {
433
+ chainId,
434
+ transaction,
435
+ operationType,
436
+ },
1129
437
  })
1130
438
  }
1131
439
 
@@ -1133,118 +441,33 @@ class Mpc {
1133
441
  success: boolean,
1134
442
  backupMethod: BackupMethods,
1135
443
  ): Promise<void> {
1136
- return new Promise((resolve, reject) => {
1137
- const handleStoredClientBackupShare = (
1138
- event: MessageEvent<WorkerResult>,
1139
- ) => {
1140
- const { type, data } = event.data
1141
- const { origin } = event
1142
-
1143
- // ignore any broadcast postMessages
1144
- if (origin !== this.getOrigin()) {
1145
- return
1146
- }
1147
-
1148
- if (type === 'portal:storedClientBackupShareError') {
1149
- // Remove the event listener
1150
- window.removeEventListener('message', handleStoredClientBackupShare)
1151
-
1152
- // Reject the promise with the error
1153
- return reject(new PortalMpcError(data as PortalError))
1154
- } else if (type === 'portal:storedClientBackupShareResult') {
1155
- // Remove the event listener
1156
- window.removeEventListener('message', handleStoredClientBackupShare)
1157
-
1158
- // Resolve the promise with the result
1159
- resolve()
1160
- }
1161
- }
1162
-
1163
- // Bind the function to the message event
1164
- window.addEventListener('message', handleStoredClientBackupShare)
1165
-
1166
- // Send the request to the iframe
1167
- this.postMessage({
1168
- type: 'portal:storedClientBackupShare',
1169
- data: {
1170
- success,
1171
- backupMethod,
1172
- },
1173
- })
444
+ return this.handleRequestToIframeAndPost({
445
+ methodMessage: 'portal:storedClientBackupShare',
446
+ errorMessage: 'portal:storedClientBackupShareError',
447
+ resultMessage: 'portal:storedClientBackupShareResult',
448
+ data: {
449
+ success,
450
+ backupMethod,
451
+ },
452
+ mapReturnValue: () => undefined,
1174
453
  })
1175
454
  }
1176
455
 
1177
456
  public async formatShares(shares: string): Promise<string> {
1178
- return new Promise((resolve, reject) => {
1179
- const handleFormatShares = (event: MessageEvent<WorkerResult>) => {
1180
- const { type, data: result } = event.data
1181
- const { origin } = event
1182
-
1183
- // ignore any broadcast postMessages
1184
- if (origin !== this.getOrigin()) {
1185
- return
1186
- }
1187
-
1188
- if (type === 'portal:wasm:formatSharesError') {
1189
- // Remove the event listener
1190
- window.removeEventListener('message', handleFormatShares)
1191
-
1192
- // Reject the promise with the error
1193
- return reject(new PortalMpcError(result as PortalError))
1194
- } else if (type === 'portal:wasm:formatSharesResult') {
1195
- // Remove the event listener
1196
- window.removeEventListener('message', handleFormatShares)
1197
-
1198
- // Resolve the promise with the result
1199
- resolve(result as string)
1200
- }
1201
- }
1202
-
1203
- // Bind the function to the message event
1204
- window.addEventListener('message', handleFormatShares)
1205
-
1206
- // Send the request to the iframe
1207
- this.postMessage({
1208
- type: 'portal:wasm:formatShares',
1209
- data: shares,
1210
- })
457
+ return this.handleRequestToIframeAndPost({
458
+ methodMessage: 'portal:wasm:formatShares',
459
+ errorMessage: 'portal:wasm:formatSharesError',
460
+ resultMessage: 'portal:wasm:formatSharesResult',
461
+ data: shares,
1211
462
  })
1212
463
  }
1213
464
 
1214
465
  public async getCustodianIdClientIdHashes(data: any): Promise<string> {
1215
- return new Promise((resolve, reject) => {
1216
- const handleGetHashes = (event: MessageEvent<WorkerResult>) => {
1217
- const { type, data: result } = event.data
1218
- const { origin } = event
1219
-
1220
- // ignore any broadcast postMessages
1221
- if (origin !== this.getOrigin()) {
1222
- return
1223
- }
1224
-
1225
- if (type === 'portal:wasm:getCustodianIdClientIdHashesError') {
1226
- // Remove the event listener
1227
- window.removeEventListener('message', handleGetHashes)
1228
-
1229
- // Reject the promise with the error
1230
- return reject(new PortalMpcError(result as PortalError))
1231
- } else if (type === 'portal:wasm:getCustodianIdClientIdHashesResult') {
1232
- // Remove the event listener
1233
- window.removeEventListener('message', handleGetHashes)
1234
-
1235
- // Resolve the promise with the result
1236
- resolve(result as string)
1237
- }
1238
- }
1239
-
1240
- // Bind the function to the message event
1241
- window.addEventListener('message', handleGetHashes)
1242
-
1243
- // Send the request to the iframe
1244
- this.postMessage({
1245
- type: 'portal:wasm:getCustodianIdClientIdHashes',
1246
- data,
1247
- })
466
+ return this.handleRequestToIframeAndPost({
467
+ methodMessage: 'portal:wasm:getCustodianIdClientIdHashes',
468
+ errorMessage: 'portal:wasm:getCustodianIdClientIdHashesError',
469
+ resultMessage: 'portal:wasm:getCustodianIdClientIdHashesResult',
470
+ data,
1248
471
  })
1249
472
  }
1250
473
 
@@ -1505,11 +728,17 @@ class Mpc {
1505
728
  errorMessage,
1506
729
  resultMessage,
1507
730
  data,
731
+ progressMessage,
732
+ progressCallback,
733
+ mapReturnValue,
1508
734
  }: {
1509
735
  methodMessage: string
1510
736
  errorMessage: string
1511
737
  resultMessage: string
1512
738
  data: any
739
+ progressMessage?: string
740
+ progressCallback?: (status: MpcStatus) => void
741
+ mapReturnValue?: (result: any) => T
1513
742
  }): Promise<T> {
1514
743
  return new Promise((resolve, reject) => {
1515
744
  const handleRequest = (event: MessageEvent<WorkerResult>) => {
@@ -1532,7 +761,11 @@ class Mpc {
1532
761
  window.removeEventListener('message', handleRequest)
1533
762
 
1534
763
  // Resolve the promise with the result
1535
- resolve(result as T)
764
+ resolve(mapReturnValue ? mapReturnValue(result) : (result as T))
765
+ }
766
+
767
+ if (type === progressMessage && progressCallback) {
768
+ void progressCallback(result as MpcStatus)
1536
769
  }
1537
770
  }
1538
771
 
@@ -1706,8 +939,7 @@ class Mpc {
1706
939
  const validBackupMethods = Object.values(BackupMethods)
1707
940
  if (!validBackupMethods.includes(data.backupMethod)) {
1708
941
  throw new Error(
1709
- `Invalid backup method: ${
1710
- data.backupMethod
942
+ `Invalid backup method: ${data.backupMethod
1711
943
  }. Valid methods are: ${validBackupMethods.join(', ')}`,
1712
944
  )
1713
945
  }