@dynamic-labs-wallet/browser 0.0.48 → 0.0.49
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/index.cjs.js +467 -118
- package/index.esm.js +452 -102
- package/package.json +4 -3
- package/src/backup/encryption.d.ts.map +1 -1
- package/src/backup/providers/googleDrive.d.ts.map +1 -1
- package/src/client.d.ts +115 -18
- package/src/client.d.ts.map +1 -1
- package/src/constants.d.ts +0 -6
- package/src/constants.d.ts.map +1 -1
- package/src/services/iframeDisplay.d.ts +9 -0
- package/src/services/iframeDisplay.d.ts.map +1 -0
- package/src/services/iframeLocalStorage.d.ts +13 -0
- package/src/services/iframeLocalStorage.d.ts.map +1 -0
- package/src/services/messageTransportBridge.d.ts +3 -0
- package/src/services/messageTransportBridge.d.ts.map +1 -0
- package/src/types.d.ts +4 -52
- package/src/types.d.ts.map +1 -1
- package/src/utils.d.ts +1 -2
- package/src/utils.d.ts.map +1 -1
package/index.esm.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { SigningAlgorithm, MPC_RELAY_PROD_API_URL, getMPCChainConfig, BackupLocation, getClientThreshold, MPC_CONFIG,
|
|
1
|
+
import { SigningAlgorithm, MPC_RELAY_PROD_API_URL, getMPCChainConfig, BackupLocation, getClientThreshold, MPC_CONFIG, getTSSConfig, WalletOperation, getReshareConfig, DynamicApiClient, IFRAME_DOMAIN } from '@dynamic-labs-wallet/core';
|
|
2
2
|
export * from '@dynamic-labs-wallet/core';
|
|
3
3
|
import { BIP340, Ed25519, Ecdsa, MessageHash, EcdsaKeygenResult, Ed25519KeygenResult, BIP340KeygenResult } from './internal/web';
|
|
4
4
|
export { BIP340, BIP340InitKeygenResult, BIP340KeygenResult, Ecdsa, EcdsaInitKeygenResult, EcdsaKeygenResult, EcdsaPublicKey, EcdsaSignature, Ed25519, Ed25519InitKeygenResult, Ed25519KeygenResult, MessageHash } from './internal/web';
|
|
5
5
|
import { Logger } from '@dynamic-labs/logger';
|
|
6
|
+
import { createRequestChannel, parseMessageTransportData, applyDefaultMessageOrigin, createMessageTransport } from '@dynamic-labs/message-transport';
|
|
6
7
|
|
|
7
8
|
function _extends() {
|
|
8
9
|
_extends = Object.assign || function assign(target) {
|
|
@@ -184,7 +185,6 @@ const encryptData = async ({ data, password })=>{
|
|
|
184
185
|
cipher: bytesToBase64(new Uint8Array(encryptedData))
|
|
185
186
|
};
|
|
186
187
|
} catch (error) {
|
|
187
|
-
console.error('Error encrypting data:', error);
|
|
188
188
|
throw new Error('Error encrypting data');
|
|
189
189
|
}
|
|
190
190
|
};
|
|
@@ -208,7 +208,6 @@ const decryptData = async ({ data, password })=>{
|
|
|
208
208
|
}, key, cipherBytes);
|
|
209
209
|
return new TextDecoder().decode(decryptedData);
|
|
210
210
|
} catch (error) {
|
|
211
|
-
console.error('Decryption error details:', error);
|
|
212
211
|
throw new Error('Decryption failed');
|
|
213
212
|
}
|
|
214
213
|
};
|
|
@@ -305,7 +304,6 @@ const downloadFileFromGoogleDrive = async ({ accessToken, name })=>{
|
|
|
305
304
|
// The client will handle validation of the structure
|
|
306
305
|
return JSON.parse(fileRawData);
|
|
307
306
|
} catch (error) {
|
|
308
|
-
console.error('Error parsing backup file:', error);
|
|
309
307
|
return null;
|
|
310
308
|
}
|
|
311
309
|
};
|
|
@@ -379,17 +377,91 @@ const localStorageWriteTest = {
|
|
|
379
377
|
}
|
|
380
378
|
});
|
|
381
379
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
}
|
|
380
|
+
/**
|
|
381
|
+
* StorageRequestChannelAdapter.getItem() sends a message within host domain
|
|
382
|
+
* the bridge on host will capture this request and forwards it to the iframe via contentWindow.postMessage()
|
|
383
|
+
*/ class StorageRequestChannelAdapter {
|
|
384
|
+
async getItem(key) {
|
|
385
|
+
const item = await this.requestChannel.request('getItem', {
|
|
386
|
+
source: 'localStorage',
|
|
387
|
+
key
|
|
388
|
+
});
|
|
389
|
+
return item ? JSON.parse(item) : null;
|
|
390
|
+
}
|
|
391
|
+
async setItem(key, value) {
|
|
392
|
+
const stringifiedValue = typeof value === 'object' ? JSON.stringify(value) : value;
|
|
393
|
+
return this.requestChannel.request('setItem', {
|
|
394
|
+
source: 'localStorage',
|
|
395
|
+
key,
|
|
396
|
+
data: stringifiedValue
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
async removeItem(key) {
|
|
400
|
+
return this.requestChannel.request('deleteItem', {
|
|
401
|
+
source: 'localStorage',
|
|
402
|
+
key
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
constructor(messageTransport){
|
|
406
|
+
this.requestChannel = createRequestChannel(messageTransport);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const setupMessageTransportBridge = (messageTransport, iframe, iframeOrigin)=>{
|
|
411
|
+
if (!(iframe == null ? void 0 : iframe.contentWindow)) {
|
|
412
|
+
throw new Error('Iframe or contentWindow not available');
|
|
413
|
+
}
|
|
414
|
+
const logger = new Logger('debug');
|
|
415
|
+
messageTransport.on((message)=>{
|
|
416
|
+
// Forward the message to webview via postMessage
|
|
417
|
+
if (message.origin === 'host') {
|
|
418
|
+
var _iframe_contentWindow;
|
|
419
|
+
logger.debug(`[host bridge] host --> bridge --> iframe`, message);
|
|
420
|
+
iframe == null ? void 0 : (_iframe_contentWindow = iframe.contentWindow) == null ? void 0 : _iframe_contentWindow.postMessage(message, iframeOrigin);
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
const handleIncomingMessage = (message)=>{
|
|
424
|
+
const { data } = message;
|
|
425
|
+
if (!data) return;
|
|
426
|
+
if ((data == null ? void 0 : data.origin) !== 'webview') {
|
|
427
|
+
logger.debug(`skipped message: ${JSON.stringify(data)}: origin is not host`);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
if (typeof data !== 'object') {
|
|
431
|
+
logger.debug(`skipped message: ${JSON.stringify(data)}: data is not an object`);
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
try {
|
|
435
|
+
const message = parseMessageTransportData(data);
|
|
436
|
+
logger.debug(`[host bridge] iframe --> bridge --> host`, message);
|
|
437
|
+
messageTransport.emit(message);
|
|
438
|
+
} catch (error) {
|
|
439
|
+
if (!(error instanceof SyntaxError)) {
|
|
440
|
+
logger.error('Error handling incoming message:', error);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
/**
|
|
445
|
+
* Handle incoming message from android client
|
|
446
|
+
*/ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
447
|
+
// @ts-ignore
|
|
448
|
+
document.addEventListener('message', handleIncomingMessage);
|
|
449
|
+
/**
|
|
450
|
+
* Handle incoming message from iOS client
|
|
451
|
+
*/ window.addEventListener('message', handleIncomingMessage);
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
class IframeDisplayChannelAdapter {
|
|
455
|
+
async displayClientShares(accountAddress) {
|
|
456
|
+
await this.requestChannel.request('displayClientShares', accountAddress);
|
|
457
|
+
}
|
|
458
|
+
async displayPrivateKey(accountAddress, privateKey) {
|
|
459
|
+
await this.requestChannel.request('displayPrivateKey', accountAddress, privateKey);
|
|
460
|
+
}
|
|
461
|
+
constructor(messageTransport){
|
|
462
|
+
this.requestChannel = createRequestChannel(messageTransport);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
393
465
|
|
|
394
466
|
class DynamicWalletClient {
|
|
395
467
|
async initialize() {
|
|
@@ -403,11 +475,196 @@ class DynamicWalletClient {
|
|
|
403
475
|
return result;
|
|
404
476
|
}
|
|
405
477
|
/**
|
|
478
|
+
* Initializes the iframe display for a specific container.
|
|
479
|
+
*
|
|
480
|
+
* @param {HTMLElement} container - The container to which the iframe will be attached.
|
|
481
|
+
* @returns {Promise<{
|
|
482
|
+
* iframe: HTMLIFrameElement;
|
|
483
|
+
* iframeDisplay: IframeDisplayChannelAdapter;
|
|
484
|
+
* cleanup: () => void;
|
|
485
|
+
* }>} A promise that resolves when the iframe is loaded.
|
|
486
|
+
*/ async initializeIframeDisplayForContainer({ container }) {
|
|
487
|
+
try {
|
|
488
|
+
const iframe = await this.loadIframeForContainer(container);
|
|
489
|
+
const transport = applyDefaultMessageOrigin({
|
|
490
|
+
defaultOrigin: 'host',
|
|
491
|
+
messageTransport: createMessageTransport()
|
|
492
|
+
});
|
|
493
|
+
setupMessageTransportBridge(transport, iframe, this.iframeDomain);
|
|
494
|
+
const iframeDisplay = new IframeDisplayChannelAdapter(transport);
|
|
495
|
+
return {
|
|
496
|
+
iframe,
|
|
497
|
+
iframeDisplay,
|
|
498
|
+
cleanup: ()=>{
|
|
499
|
+
container.removeChild(iframe);
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
} catch (error) {
|
|
503
|
+
this.logger.error('Error initializing iframe:', error);
|
|
504
|
+
throw error;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* this is called on class construction time
|
|
509
|
+
* @returns {Promise<void>} that resolves when the iframe is loaded and the message transport and iframe storage are initialized
|
|
510
|
+
*/ initializeIframeCommunication() {
|
|
511
|
+
if (!this.iframeLoadPromise) {
|
|
512
|
+
this.iframeLoadPromise = this.doInitializeIframeCommunication();
|
|
513
|
+
}
|
|
514
|
+
return this.iframeLoadPromise;
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* initialize the iframe communication by awaiting the iframe load promise
|
|
518
|
+
* and initializing the message transport and iframe storage after iframe is successfully loaded
|
|
519
|
+
*/ async doInitializeIframeCommunication() {
|
|
520
|
+
try {
|
|
521
|
+
await this.loadIframe();
|
|
522
|
+
this.initializeMessageTransport();
|
|
523
|
+
this.initializeIframeStorage();
|
|
524
|
+
} catch (error) {
|
|
525
|
+
this.logger.error('Error initializing iframe:', error);
|
|
526
|
+
throw error;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* create a promise to load an iframe
|
|
531
|
+
* @returns {Promise<void>} that resolves when the iframe is loaded
|
|
532
|
+
*/ loadIframe() {
|
|
533
|
+
return new Promise((resolve, reject)=>{
|
|
534
|
+
const iframe = document.createElement('iframe');
|
|
535
|
+
const iframeTimeoutId = setTimeout(()=>{
|
|
536
|
+
reject(new Error('Iframe load timeout'));
|
|
537
|
+
}, 10000);
|
|
538
|
+
iframe.style.display = 'none';
|
|
539
|
+
iframe.setAttribute('title', 'Dynamic Wallet Iframe');
|
|
540
|
+
iframe.style.position = 'fixed';
|
|
541
|
+
iframe.style.top = '0';
|
|
542
|
+
iframe.style.left = '0';
|
|
543
|
+
iframe.style.width = '0';
|
|
544
|
+
iframe.style.height = '0';
|
|
545
|
+
iframe.style.border = 'none';
|
|
546
|
+
iframe.style.pointerEvents = 'none';
|
|
547
|
+
const params = new URLSearchParams({
|
|
548
|
+
instanceId: this.instanceId,
|
|
549
|
+
hostOrigin: window.location.origin
|
|
550
|
+
});
|
|
551
|
+
iframe.src = `${this.iframeDomain}/waas/${this.environmentId}?${params.toString()}`;
|
|
552
|
+
this.logger.debug('Creating iframe with src:', iframe.src);
|
|
553
|
+
document.body.appendChild(iframe);
|
|
554
|
+
iframe.onload = ()=>{
|
|
555
|
+
clearTimeout(iframeTimeoutId);
|
|
556
|
+
this.logger.debug('Iframe loaded successfully');
|
|
557
|
+
this.iframe = iframe;
|
|
558
|
+
resolve();
|
|
559
|
+
};
|
|
560
|
+
iframe.onerror = (error)=>{
|
|
561
|
+
clearTimeout(iframeTimeoutId);
|
|
562
|
+
this.logger.error('Iframe failed to load:', error);
|
|
563
|
+
reject(new Error('Failed to load iframe'));
|
|
564
|
+
};
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Load an iframe for a specific container
|
|
569
|
+
* @param {HTMLElement} container - The container to which the iframe will be attached
|
|
570
|
+
* @returns {Promise<HTMLIFrameElement>} that resolves when the iframe is loaded
|
|
571
|
+
*/ loadIframeForContainer(container) {
|
|
572
|
+
return new Promise((resolve, reject)=>{
|
|
573
|
+
const iframe = document.createElement('iframe');
|
|
574
|
+
const iframeTimeoutId = setTimeout(()=>{
|
|
575
|
+
reject(new Error('Iframe load timeout'));
|
|
576
|
+
}, 10000);
|
|
577
|
+
iframe.style.display = 'block';
|
|
578
|
+
iframe.style.width = '100%';
|
|
579
|
+
iframe.style.height = '100%';
|
|
580
|
+
iframe.setAttribute('title', 'Dynamic Wallet Storage');
|
|
581
|
+
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');
|
|
582
|
+
const params = new URLSearchParams({
|
|
583
|
+
instanceId: this.instanceId,
|
|
584
|
+
hostOrigin: window.location.origin
|
|
585
|
+
});
|
|
586
|
+
iframe.src = `${this.iframeDomain}/waas/${this.environmentId}?${params.toString()}`;
|
|
587
|
+
this.logger.debug('Creating iframe with src:', iframe.src);
|
|
588
|
+
// Add iframe to the provided container
|
|
589
|
+
container.appendChild(iframe);
|
|
590
|
+
iframe.onload = ()=>{
|
|
591
|
+
clearTimeout(iframeTimeoutId);
|
|
592
|
+
this.logger.debug('Iframe loaded successfully');
|
|
593
|
+
this.iframe = iframe;
|
|
594
|
+
resolve(iframe);
|
|
595
|
+
};
|
|
596
|
+
iframe.onerror = (error)=>{
|
|
597
|
+
clearTimeout(iframeTimeoutId);
|
|
598
|
+
this.logger.error('Iframe failed to load:', error);
|
|
599
|
+
reject(new Error('Failed to load iframe'));
|
|
600
|
+
};
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* initialize the message transport after iframe is successfully loaded
|
|
605
|
+
*/ initializeMessageTransport() {
|
|
606
|
+
const transport = applyDefaultMessageOrigin({
|
|
607
|
+
defaultOrigin: 'host',
|
|
608
|
+
messageTransport: createMessageTransport()
|
|
609
|
+
});
|
|
610
|
+
this.messageTransport = transport;
|
|
611
|
+
if (!this.iframe) {
|
|
612
|
+
throw new Error('Iframe not available');
|
|
613
|
+
}
|
|
614
|
+
setupMessageTransportBridge(this.messageTransport, this.iframe, this.iframeDomain);
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* initialize the iframe storage after iframe is successfully loaded
|
|
618
|
+
*/ initializeIframeStorage() {
|
|
619
|
+
if (!this.messageTransport) {
|
|
620
|
+
throw new Error('Message transport not initialized');
|
|
621
|
+
}
|
|
622
|
+
this.iframeStorage = new StorageRequestChannelAdapter(this.messageTransport);
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Gets the initialized iframe instance. This method ensures the iframe is properly loaded and configured.
|
|
626
|
+
* The first call will initialize and await the iframe loading process.
|
|
627
|
+
* Subsequent calls will return the same iframe instance immediately.
|
|
628
|
+
*
|
|
629
|
+
* @throws {Error} If iframe initialization fails
|
|
630
|
+
* @throws {Error} If message transport initialization fails
|
|
631
|
+
* @throws {Error} If iframe storage initialization fails
|
|
632
|
+
* @returns {Promise<HTMLIFrameElement>} The initialized iframe element
|
|
633
|
+
*/ async getIframe() {
|
|
634
|
+
await this.initializeIframeCommunication();
|
|
635
|
+
if (!this.iframe) {
|
|
636
|
+
throw new Error('Failed to initialize iframe');
|
|
637
|
+
}
|
|
638
|
+
if (!this.messageTransport) {
|
|
639
|
+
throw new Error('Failed to initialize message transport');
|
|
640
|
+
}
|
|
641
|
+
if (!this.iframeStorage) {
|
|
642
|
+
throw new Error('Failed to initialize iframe storage');
|
|
643
|
+
}
|
|
644
|
+
return this.iframe;
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Gets the initialized iframe storage instance. This method ensures the iframe storage is properly configured.
|
|
648
|
+
* The first call will initialize and await the iframe communication process.
|
|
649
|
+
* Subsequent calls will return the same storage instance immediately.
|
|
650
|
+
*
|
|
651
|
+
* @throws {Error} If iframe storage initialization fails
|
|
652
|
+
* @returns {Promise<SupportedStorage>} The initialized iframe storage instance
|
|
653
|
+
*/ async getIframeStorage() {
|
|
654
|
+
await this.initializeIframeCommunication();
|
|
655
|
+
if (!this.iframeStorage) {
|
|
656
|
+
throw new Error('Failed to initialize iframe storage');
|
|
657
|
+
}
|
|
658
|
+
return this.iframeStorage;
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
406
661
|
* Client initialization logic
|
|
407
662
|
*/ async _initialize() {
|
|
408
663
|
try {
|
|
409
|
-
const initializePromises = [
|
|
410
|
-
|
|
664
|
+
const initializePromises = [
|
|
665
|
+
this.restoreWallets(),
|
|
666
|
+
this.useIframeStorage && this.initializeIframeCommunication()
|
|
667
|
+
];
|
|
411
668
|
await Promise.all(initializePromises);
|
|
412
669
|
return {
|
|
413
670
|
error: null
|
|
@@ -514,6 +771,52 @@ class DynamicWalletClient {
|
|
|
514
771
|
throw new Error('Error creating wallet account');
|
|
515
772
|
}
|
|
516
773
|
}
|
|
774
|
+
async importRawPrivateKey({ chainName, privateKey, thresholdSignatureScheme, onError, onCeremonyComplete }) {
|
|
775
|
+
const mpcSigner = getMPCSigner({
|
|
776
|
+
chainName,
|
|
777
|
+
baseRelayUrl: this.baseMPCRelayApiUrl
|
|
778
|
+
});
|
|
779
|
+
const clientKeygenInitResults = await this.clientInitializeKeyGen({
|
|
780
|
+
chainName,
|
|
781
|
+
thresholdSignatureScheme
|
|
782
|
+
});
|
|
783
|
+
const clientKeygenIds = clientKeygenInitResults.map((result)=>result.keygenId);
|
|
784
|
+
const { roomId, serverKeygenIds } = await this.apiClient.importPrivateKey({
|
|
785
|
+
chainName,
|
|
786
|
+
clientKeygenIds,
|
|
787
|
+
thresholdSignatureScheme,
|
|
788
|
+
onError,
|
|
789
|
+
onCeremonyComplete
|
|
790
|
+
});
|
|
791
|
+
const { threshold } = getTSSConfig(thresholdSignatureScheme);
|
|
792
|
+
const clientKeygenResults = await Promise.all(clientKeygenInitResults.map(async (currentInit, index)=>{
|
|
793
|
+
const otherClientKeygenIds = clientKeygenInitResults.filter((init)=>init.keygenId !== currentInit.keygenId).map((init)=>init.keygenId);
|
|
794
|
+
if (index === 0) {
|
|
795
|
+
const otherKeyGenIds = [
|
|
796
|
+
...serverKeygenIds,
|
|
797
|
+
...otherClientKeygenIds
|
|
798
|
+
];
|
|
799
|
+
const importerKeygenResult = await mpcSigner.importPrivateKeyImporter(roomId, threshold, privateKey, currentInit, otherKeyGenIds);
|
|
800
|
+
return importerKeygenResult;
|
|
801
|
+
} else {
|
|
802
|
+
const recipientKeygenResult = await mpcSigner.importPrivateKeyRecipient(roomId, threshold, currentInit, [
|
|
803
|
+
...serverKeygenIds,
|
|
804
|
+
...otherClientKeygenIds
|
|
805
|
+
]);
|
|
806
|
+
return recipientKeygenResult;
|
|
807
|
+
}
|
|
808
|
+
}));
|
|
809
|
+
const [clientKeygenResult] = clientKeygenResults;
|
|
810
|
+
const rawPublicKey = await this.derivePublicKey({
|
|
811
|
+
chainName,
|
|
812
|
+
keyShare: clientKeygenResult,
|
|
813
|
+
derivationPath: undefined
|
|
814
|
+
});
|
|
815
|
+
return {
|
|
816
|
+
rawPublicKey,
|
|
817
|
+
clientKeyShares: clientKeygenResults
|
|
818
|
+
};
|
|
819
|
+
}
|
|
517
820
|
async serverSign({ walletId, message }) {
|
|
518
821
|
// Create the room and sign the message
|
|
519
822
|
if (typeof message !== 'string') {
|
|
@@ -576,11 +879,14 @@ class DynamicWalletClient {
|
|
|
576
879
|
});
|
|
577
880
|
const derivationPath = wallet.derivationPath && wallet.derivationPath != '' ? new Uint32Array(Object.values(JSON.parse(wallet.derivationPath))) : undefined;
|
|
578
881
|
// Perform the client sign and return the signature
|
|
882
|
+
const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
|
|
883
|
+
accountAddress
|
|
884
|
+
});
|
|
579
885
|
const signature = await this.clientSign({
|
|
580
886
|
chainName,
|
|
581
887
|
message,
|
|
582
888
|
roomId: data.roomId,
|
|
583
|
-
keyShare:
|
|
889
|
+
keyShare: clientKeyShares[0],
|
|
584
890
|
derivationPath
|
|
585
891
|
});
|
|
586
892
|
return signature;
|
|
@@ -593,7 +899,7 @@ class DynamicWalletClient {
|
|
|
593
899
|
});
|
|
594
900
|
const wallet = await this.getWallet({
|
|
595
901
|
accountAddress,
|
|
596
|
-
walletOperation: WalletOperation.
|
|
902
|
+
walletOperation: WalletOperation.NO_OPERATION,
|
|
597
903
|
password
|
|
598
904
|
});
|
|
599
905
|
const mpcSigner = getMPCSigner({
|
|
@@ -605,12 +911,18 @@ class DynamicWalletClient {
|
|
|
605
911
|
walletId: wallet.walletId
|
|
606
912
|
});
|
|
607
913
|
const roomId = data.roomId;
|
|
608
|
-
const
|
|
914
|
+
const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
|
|
915
|
+
accountAddress
|
|
916
|
+
});
|
|
917
|
+
const refreshResults = await Promise.all(clientKeyShares.map((clientKeyShare)=>mpcSigner.refresh(roomId, clientKeyShare)));
|
|
609
918
|
this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
|
|
610
|
-
clientKeyShares: refreshResults,
|
|
611
919
|
clientKeySharesBackupInfo: getClientKeyShareBackupInfo()
|
|
612
920
|
});
|
|
613
|
-
await this.
|
|
921
|
+
await this.setClientKeySharesToLocalStorage({
|
|
922
|
+
accountAddress,
|
|
923
|
+
clientKeyShares: refreshResults,
|
|
924
|
+
overwriteOrMerge: 'overwrite'
|
|
925
|
+
});
|
|
614
926
|
await this.storeEncryptedBackupByWallet({
|
|
615
927
|
accountAddress,
|
|
616
928
|
password: password != null ? password : this.environmentId
|
|
@@ -638,7 +950,7 @@ class DynamicWalletClient {
|
|
|
638
950
|
* existingClientKeyShares: ClientKeyShare[]
|
|
639
951
|
* }>} Object containing new and existing client keygen results, IDs and shares
|
|
640
952
|
* @todo Support higher to lower reshare strategies
|
|
641
|
-
*/ async reshareStrategy({ chainName, wallet, oldThresholdSignatureScheme, newThresholdSignatureScheme }) {
|
|
953
|
+
*/ async reshareStrategy({ chainName, wallet, accountAddress, oldThresholdSignatureScheme, newThresholdSignatureScheme }) {
|
|
642
954
|
const mpcSigner = getMPCSigner({
|
|
643
955
|
chainName,
|
|
644
956
|
baseRelayUrl: this.baseMPCRelayApiUrl
|
|
@@ -654,7 +966,9 @@ class DynamicWalletClient {
|
|
|
654
966
|
}, ()=>mpcSigner.initKeygen()));
|
|
655
967
|
const newClientKeygenIds = newClientInitKeygenResults.map((result)=>result.keygenId);
|
|
656
968
|
// Get existing client shares
|
|
657
|
-
const existingClientKeyShares =
|
|
969
|
+
const existingClientKeyShares = (await this.getClientKeySharesFromLocalStorage({
|
|
970
|
+
accountAddress
|
|
971
|
+
})).slice(0, existingClientShareCount);
|
|
658
972
|
const existingClientKeygenIds = await Promise.all(existingClientKeyShares.map(async (keyShare)=>await this.getExportId({
|
|
659
973
|
chainName,
|
|
660
974
|
clientKeyShare: keyShare
|
|
@@ -678,12 +992,13 @@ class DynamicWalletClient {
|
|
|
678
992
|
});
|
|
679
993
|
const wallet = await this.getWallet({
|
|
680
994
|
accountAddress,
|
|
681
|
-
walletOperation: WalletOperation.
|
|
995
|
+
walletOperation: WalletOperation.NO_OPERATION,
|
|
682
996
|
shareCount: existingClientShareCount,
|
|
683
997
|
password
|
|
684
998
|
});
|
|
685
999
|
const { newClientInitKeygenResults, newClientKeygenIds, existingClientKeygenIds, existingClientKeyShares } = await this.reshareStrategy({
|
|
686
1000
|
chainName,
|
|
1001
|
+
accountAddress,
|
|
687
1002
|
wallet,
|
|
688
1003
|
oldThresholdSignatureScheme,
|
|
689
1004
|
newThresholdSignatureScheme
|
|
@@ -716,17 +1031,18 @@ class DynamicWalletClient {
|
|
|
716
1031
|
...newClientInitKeygenResults.map((keygenResult)=>mpcSigner.reshareNewParty(roomId, oldMpcConfig.threshold, newMpcConfig.threshold, keygenResult, allPartyKeygenIds)),
|
|
717
1032
|
...existingClientKeyShares.map((keyShare)=>mpcSigner.reshareRemainingParty(roomId, newMpcConfig.threshold, keyShare, allPartyKeygenIds))
|
|
718
1033
|
]);
|
|
719
|
-
this.
|
|
720
|
-
|
|
1034
|
+
await this.setClientKeySharesToLocalStorage({
|
|
1035
|
+
accountAddress,
|
|
1036
|
+
clientKeyShares: reshareResults,
|
|
1037
|
+
overwriteOrMerge: 'overwrite'
|
|
721
1038
|
});
|
|
722
|
-
await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
|
|
723
1039
|
await this.storeEncryptedBackupByWallet({
|
|
724
1040
|
accountAddress,
|
|
725
1041
|
password
|
|
726
1042
|
});
|
|
727
1043
|
return reshareResults;
|
|
728
1044
|
}
|
|
729
|
-
async exportKey({ accountAddress, chainName, password = undefined }) {
|
|
1045
|
+
async exportKey({ accountAddress, displayContainer, chainName, password = undefined }) {
|
|
730
1046
|
const wallet = await this.getWallet({
|
|
731
1047
|
accountAddress,
|
|
732
1048
|
password,
|
|
@@ -736,15 +1052,18 @@ class DynamicWalletClient {
|
|
|
736
1052
|
chainName,
|
|
737
1053
|
baseRelayUrl: this.baseMPCRelayApiUrl
|
|
738
1054
|
});
|
|
1055
|
+
const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
|
|
1056
|
+
accountAddress
|
|
1057
|
+
});
|
|
739
1058
|
const exportId = await this.getExportId({
|
|
740
1059
|
chainName,
|
|
741
|
-
clientKeyShare:
|
|
1060
|
+
clientKeyShare: clientKeyShares[0]
|
|
742
1061
|
});
|
|
743
1062
|
const data = await this.apiClient.exportKey({
|
|
744
1063
|
walletId: wallet.walletId,
|
|
745
1064
|
exportId
|
|
746
1065
|
});
|
|
747
|
-
const keyExportRaw = await mpcSigner.exportFullPrivateKey(data.roomId,
|
|
1066
|
+
const keyExportRaw = await mpcSigner.exportFullPrivateKey(data.roomId, clientKeyShares[0], exportId);
|
|
748
1067
|
if (!keyExportRaw) {
|
|
749
1068
|
throw new Error('Error exporting private key');
|
|
750
1069
|
}
|
|
@@ -787,11 +1106,17 @@ class DynamicWalletClient {
|
|
|
787
1106
|
} else if (mpcSigner instanceof BIP340) {
|
|
788
1107
|
derivedPrivateKey = await mpcSigner.derivePrivateKeyFromXpriv(keyExportRaw, walletDerivationPath);
|
|
789
1108
|
}
|
|
1109
|
+
const rawPublicKey = await this.derivePublicKey({
|
|
1110
|
+
chainName,
|
|
1111
|
+
keyShare: walletKeyShares[0],
|
|
1112
|
+
derivationPath: walletDerivationPath
|
|
1113
|
+
});
|
|
790
1114
|
return {
|
|
791
|
-
derivedPrivateKey
|
|
1115
|
+
derivedPrivateKey,
|
|
1116
|
+
rawPublicKey
|
|
792
1117
|
};
|
|
793
1118
|
} catch (error) {
|
|
794
|
-
|
|
1119
|
+
this.logger.error('Error in offlineExportKey:', error);
|
|
795
1120
|
throw error;
|
|
796
1121
|
}
|
|
797
1122
|
}
|
|
@@ -806,6 +1131,47 @@ class DynamicWalletClient {
|
|
|
806
1131
|
return serializedEncryptedKeyShare;
|
|
807
1132
|
}
|
|
808
1133
|
/**
|
|
1134
|
+
* temporary helper function to store encrypted backup by wallet based on `useIframeStorage` flag
|
|
1135
|
+
* TODO: revise this to only use iframe storage when iframe is deployed
|
|
1136
|
+
*/ async getClientKeySharesFromLocalStorage({ accountAddress }) {
|
|
1137
|
+
var _this_iframeStorage;
|
|
1138
|
+
if (!this.useIframeStorage) {
|
|
1139
|
+
return this.walletMap[accountAddress].clientKeyShares;
|
|
1140
|
+
}
|
|
1141
|
+
await this.initializeIframeCommunication();
|
|
1142
|
+
const walletObject = await ((_this_iframeStorage = this.iframeStorage) == null ? void 0 : _this_iframeStorage.getItem(accountAddress));
|
|
1143
|
+
if (!walletObject) {
|
|
1144
|
+
this.logger.debug(`No item found in iframe local storage for accountAddress: ${accountAddress}`);
|
|
1145
|
+
return [];
|
|
1146
|
+
}
|
|
1147
|
+
try {
|
|
1148
|
+
return (walletObject == null ? void 0 : walletObject.clientKeyShares) || [];
|
|
1149
|
+
} catch (error) {
|
|
1150
|
+
this.logger.error(`Error parsing clientKeyShares: ${error} for accountAddress: ${accountAddress}`);
|
|
1151
|
+
return [];
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
/**
|
|
1155
|
+
* temporary helper function to store encrypted backup by wallet based on `useIframeStorage` flag
|
|
1156
|
+
* TODO: revise this to only use iframe storage when iframe is deployed
|
|
1157
|
+
*/ async setClientKeySharesToLocalStorage({ accountAddress, clientKeyShares, overwriteOrMerge = 'merge' }) {
|
|
1158
|
+
var _this_iframeStorage;
|
|
1159
|
+
if (!this.useIframeStorage) {
|
|
1160
|
+
var _this_walletMap_accountAddress;
|
|
1161
|
+
this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress] || {}, {
|
|
1162
|
+
clientKeyShares: overwriteOrMerge === 'overwrite' ? clientKeyShares : mergeUniqueKeyShares(((_this_walletMap_accountAddress = this.walletMap[accountAddress]) == null ? void 0 : _this_walletMap_accountAddress.clientKeyShares) || [], clientKeyShares)
|
|
1163
|
+
});
|
|
1164
|
+
await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
|
|
1165
|
+
return;
|
|
1166
|
+
}
|
|
1167
|
+
await this.initializeIframeCommunication();
|
|
1168
|
+
await ((_this_iframeStorage = this.iframeStorage) == null ? void 0 : _this_iframeStorage.setItem(accountAddress, {
|
|
1169
|
+
clientKeyShares: overwriteOrMerge === 'overwrite' ? clientKeyShares : mergeUniqueKeyShares(await this.getClientKeySharesFromLocalStorage({
|
|
1170
|
+
accountAddress
|
|
1171
|
+
}), clientKeyShares)
|
|
1172
|
+
}));
|
|
1173
|
+
}
|
|
1174
|
+
/**
|
|
809
1175
|
* Encrypts and stores wallet key shares as backups.
|
|
810
1176
|
*
|
|
811
1177
|
* This method encrypts all client key shares for a specific wallet and stores them
|
|
@@ -823,7 +1189,9 @@ class DynamicWalletClient {
|
|
|
823
1189
|
* @param {string} params.accountAddress - The account address of the wallet to backup
|
|
824
1190
|
* @param {string} [params.password] - Optional password for encrypting the key shares
|
|
825
1191
|
*/ async storeEncryptedBackupByWallet({ accountAddress, clientKeyShares = undefined, password = undefined }) {
|
|
826
|
-
const keySharesToBackup = clientKeyShares != null ? clientKeyShares : this.
|
|
1192
|
+
const keySharesToBackup = clientKeyShares != null ? clientKeyShares : await this.getClientKeySharesFromLocalStorage({
|
|
1193
|
+
accountAddress
|
|
1194
|
+
});
|
|
827
1195
|
const encryptedKeyShares = await Promise.all(keySharesToBackup.map((keyShare)=>this.encryptKeyShare({
|
|
828
1196
|
keyShare,
|
|
829
1197
|
password
|
|
@@ -947,8 +1315,10 @@ class DynamicWalletClient {
|
|
|
947
1315
|
password: password != null ? password : this.environmentId
|
|
948
1316
|
})));
|
|
949
1317
|
if (storeRecoveredShares) {
|
|
950
|
-
this.
|
|
951
|
-
|
|
1318
|
+
await this.setClientKeySharesToLocalStorage({
|
|
1319
|
+
accountAddress,
|
|
1320
|
+
clientKeyShares: decryptedKeyShares,
|
|
1321
|
+
overwriteOrMerge: 'merge'
|
|
952
1322
|
});
|
|
953
1323
|
await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
|
|
954
1324
|
}
|
|
@@ -967,7 +1337,9 @@ class DynamicWalletClient {
|
|
|
967
1337
|
walletOperation: WalletOperation.REACH_ALL_PARTIES,
|
|
968
1338
|
password
|
|
969
1339
|
});
|
|
970
|
-
const clientKeyShares = this.
|
|
1340
|
+
const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
|
|
1341
|
+
accountAddress
|
|
1342
|
+
});
|
|
971
1343
|
if (clientKeyShares.length === 0) {
|
|
972
1344
|
throw new Error('No key shares found');
|
|
973
1345
|
}
|
|
@@ -1022,7 +1394,7 @@ class DynamicWalletClient {
|
|
|
1022
1394
|
await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
|
|
1023
1395
|
return ids;
|
|
1024
1396
|
}
|
|
1025
|
-
async restoreBackupFromGoogleDrive({ accountAddress, oauthAccountId, name, password }) {
|
|
1397
|
+
async restoreBackupFromGoogleDrive({ accountAddress, oauthAccountId, name, displayContainer, password }) {
|
|
1026
1398
|
await this.getWallet({
|
|
1027
1399
|
accountAddress
|
|
1028
1400
|
});
|
|
@@ -1050,71 +1422,27 @@ class DynamicWalletClient {
|
|
|
1050
1422
|
keyShare,
|
|
1051
1423
|
password
|
|
1052
1424
|
})));
|
|
1053
|
-
this.
|
|
1054
|
-
|
|
1425
|
+
await this.setClientKeySharesToLocalStorage({
|
|
1426
|
+
accountAddress,
|
|
1427
|
+
clientKeyShares: decryptedKeyShares,
|
|
1428
|
+
overwriteOrMerge: 'merge'
|
|
1055
1429
|
});
|
|
1430
|
+
if (this.useIframeStorage) {
|
|
1431
|
+
const { iframeDisplay } = await this.initializeIframeDisplayForContainer({
|
|
1432
|
+
container: displayContainer
|
|
1433
|
+
});
|
|
1434
|
+
iframeDisplay.displayClientShares(accountAddress);
|
|
1435
|
+
}
|
|
1056
1436
|
return decryptedKeyShares;
|
|
1057
1437
|
}
|
|
1058
|
-
async importRawPrivateKey({ chainName, privateKey, thresholdSignatureScheme, onError, onCeremonyComplete }) {
|
|
1059
|
-
const mpcSigner = getMPCSigner({
|
|
1060
|
-
chainName,
|
|
1061
|
-
baseRelayUrl: this.baseMPCRelayApiUrl
|
|
1062
|
-
});
|
|
1063
|
-
const clientKeygenInitResults = await this.clientInitializeKeyGen({
|
|
1064
|
-
chainName,
|
|
1065
|
-
thresholdSignatureScheme
|
|
1066
|
-
});
|
|
1067
|
-
const clientKeygenIds = clientKeygenInitResults.map((result)=>result.keygenId);
|
|
1068
|
-
const { roomId, serverKeygenIds } = await this.apiClient.importPrivateKey({
|
|
1069
|
-
chainName,
|
|
1070
|
-
clientKeygenIds,
|
|
1071
|
-
thresholdSignatureScheme,
|
|
1072
|
-
onError,
|
|
1073
|
-
onCeremonyComplete
|
|
1074
|
-
});
|
|
1075
|
-
const { threshold } = getTSSConfig(thresholdSignatureScheme);
|
|
1076
|
-
const clientKeygenResults = await Promise.all(clientKeygenInitResults.map(async (currentInit, index)=>{
|
|
1077
|
-
const otherClientKeygenIds = clientKeygenInitResults.filter((init)=>init.keygenId !== currentInit.keygenId).map((init)=>init.keygenId);
|
|
1078
|
-
if (index === 0) {
|
|
1079
|
-
const otherKeyGenIds = [
|
|
1080
|
-
...serverKeygenIds,
|
|
1081
|
-
...otherClientKeygenIds
|
|
1082
|
-
];
|
|
1083
|
-
const importerKeygenResult = await mpcSigner.importPrivateKeyImporter(roomId, threshold, privateKey, currentInit, otherKeyGenIds);
|
|
1084
|
-
return importerKeygenResult;
|
|
1085
|
-
} else {
|
|
1086
|
-
const recipientKeygenResult = await mpcSigner.importPrivateKeyRecipient(roomId, threshold, currentInit, [
|
|
1087
|
-
...serverKeygenIds,
|
|
1088
|
-
...otherClientKeygenIds
|
|
1089
|
-
]);
|
|
1090
|
-
return recipientKeygenResult;
|
|
1091
|
-
}
|
|
1092
|
-
}));
|
|
1093
|
-
const [clientKeygenResult] = clientKeygenResults;
|
|
1094
|
-
const rawPublicKey = await this.derivePublicKey({
|
|
1095
|
-
chainName,
|
|
1096
|
-
keyShare: clientKeygenResult,
|
|
1097
|
-
derivationPath: undefined
|
|
1098
|
-
});
|
|
1099
|
-
return {
|
|
1100
|
-
rawPublicKey,
|
|
1101
|
-
clientKeyShares: clientKeygenResults
|
|
1102
|
-
};
|
|
1103
|
-
}
|
|
1104
1438
|
async exportClientKeyshares({ accountAddress, password }) {
|
|
1105
1439
|
await this.verifyPassword({
|
|
1106
1440
|
accountAddress,
|
|
1107
1441
|
password,
|
|
1108
1442
|
walletOperation: WalletOperation.REACH_ALL_PARTIES
|
|
1109
1443
|
});
|
|
1110
|
-
await this.
|
|
1111
|
-
accountAddress
|
|
1112
|
-
walletOperation: WalletOperation.REACH_ALL_PARTIES,
|
|
1113
|
-
password
|
|
1114
|
-
});
|
|
1115
|
-
const clientKeyShares = await this.getClientKeyShares({
|
|
1116
|
-
accountAddress,
|
|
1117
|
-
password
|
|
1444
|
+
const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
|
|
1445
|
+
accountAddress
|
|
1118
1446
|
});
|
|
1119
1447
|
if (!accountAddress) {
|
|
1120
1448
|
throw new Error('Must provide an account address');
|
|
@@ -1136,12 +1464,14 @@ class DynamicWalletClient {
|
|
|
1136
1464
|
a.click();
|
|
1137
1465
|
}
|
|
1138
1466
|
async getClientKeyShares({ accountAddress, password }) {
|
|
1139
|
-
|
|
1467
|
+
await this.getWallet({
|
|
1140
1468
|
accountAddress,
|
|
1141
1469
|
password,
|
|
1142
1470
|
walletOperation: WalletOperation.REACH_THRESHOLD
|
|
1143
1471
|
});
|
|
1144
|
-
return
|
|
1472
|
+
return this.getClientKeySharesFromLocalStorage({
|
|
1473
|
+
accountAddress
|
|
1474
|
+
});
|
|
1145
1475
|
}
|
|
1146
1476
|
/**
|
|
1147
1477
|
* Helper function to check if the required wallet fields are present and valid
|
|
@@ -1168,7 +1498,6 @@ class DynamicWalletClient {
|
|
|
1168
1498
|
}
|
|
1169
1499
|
// check if wallet already exists with sufficient keyshares
|
|
1170
1500
|
if (existingWallet) {
|
|
1171
|
-
var _existingWallet_clientKeyShares;
|
|
1172
1501
|
const { shares } = this.recoverStrategy({
|
|
1173
1502
|
clientKeyShareBackupInfo: existingWallet.clientKeySharesBackupInfo || {
|
|
1174
1503
|
backups: getClientKeyShareBackupInfo()
|
|
@@ -1178,7 +1507,10 @@ class DynamicWalletClient {
|
|
|
1178
1507
|
shareCount
|
|
1179
1508
|
});
|
|
1180
1509
|
const { dynamic: requiredDynamicKeyShareIds = [] } = shares;
|
|
1181
|
-
|
|
1510
|
+
const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
|
|
1511
|
+
accountAddress
|
|
1512
|
+
});
|
|
1513
|
+
if (requiredDynamicKeyShareIds.length <= ((clientKeyShares == null ? void 0 : clientKeyShares.length) || 0)) {
|
|
1182
1514
|
keyshareCheck = true;
|
|
1183
1515
|
}
|
|
1184
1516
|
}
|
|
@@ -1250,7 +1582,9 @@ class DynamicWalletClient {
|
|
|
1250
1582
|
const clientKeySharesBackupInfo = await this.getWalletClientKeyShareBackupInfo({
|
|
1251
1583
|
accountAddress
|
|
1252
1584
|
});
|
|
1253
|
-
const clientKeyShares = this.
|
|
1585
|
+
const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
|
|
1586
|
+
accountAddress
|
|
1587
|
+
});
|
|
1254
1588
|
if (walletOperation === WalletOperation.REACH_ALL_PARTIES || walletOperation === WalletOperation.REFRESH || walletOperation === WalletOperation.RESHARE) {
|
|
1255
1589
|
return true;
|
|
1256
1590
|
}
|
|
@@ -1313,6 +1647,12 @@ class DynamicWalletClient {
|
|
|
1313
1647
|
walletOperation: walletOperation,
|
|
1314
1648
|
shareCount
|
|
1315
1649
|
});
|
|
1650
|
+
if (this.useIframeStorage) {
|
|
1651
|
+
var _this_iframeStorage;
|
|
1652
|
+
(_this_iframeStorage = this.iframeStorage) == null ? void 0 : _this_iframeStorage.setItem(`${accountAddress}`, JSON.stringify({
|
|
1653
|
+
clientKeyShares: decryptedKeyShares
|
|
1654
|
+
}));
|
|
1655
|
+
}
|
|
1316
1656
|
this.logger.debug('Recovered backup', decryptedKeyShares);
|
|
1317
1657
|
}
|
|
1318
1658
|
const walletCount = Object.keys(this.walletMap).length;
|
|
@@ -1345,13 +1685,13 @@ class DynamicWalletClient {
|
|
|
1345
1685
|
};
|
|
1346
1686
|
});
|
|
1347
1687
|
this.walletMap = wallets.reduce((acc, wallet)=>{
|
|
1348
|
-
var _acc_accountAddress;
|
|
1688
|
+
var _acc_wallet_accountAddress, _acc_accountAddress;
|
|
1349
1689
|
const accountAddress = wallet.accountAddress;
|
|
1350
1690
|
acc[wallet.accountAddress] = {
|
|
1351
1691
|
walletId: wallet.walletId,
|
|
1352
1692
|
chainName: wallet.chainName,
|
|
1353
1693
|
accountAddress: wallet.accountAddress,
|
|
1354
|
-
clientKeyShares: wallet.clientKeyShares || [],
|
|
1694
|
+
clientKeyShares: ((_acc_wallet_accountAddress = acc[wallet.accountAddress]) == null ? void 0 : _acc_wallet_accountAddress.clientKeyShares) || [],
|
|
1355
1695
|
clientKeySharesBackupInfo: wallet.clientKeySharesBackupInfo,
|
|
1356
1696
|
derivationPath: ((_acc_accountAddress = acc[accountAddress]) == null ? void 0 : _acc_accountAddress.derivationPath) || undefined,
|
|
1357
1697
|
thresholdSignatureScheme: wallet.thresholdSignatureScheme
|
|
@@ -1365,7 +1705,14 @@ class DynamicWalletClient {
|
|
|
1365
1705
|
this.logger = logger;
|
|
1366
1706
|
this.walletMap = {} // todo: store in session storage
|
|
1367
1707
|
;
|
|
1708
|
+
this.iframeStorage = null;
|
|
1709
|
+
this.iframeDisplay = null;
|
|
1368
1710
|
this.memoryStorage = null;
|
|
1711
|
+
this.messageTransport = null;
|
|
1712
|
+
this.iframe = null;
|
|
1713
|
+
this.useIframeStorage = false // TODO: remove this when iframe is deployed
|
|
1714
|
+
;
|
|
1715
|
+
this.iframeLoadPromise = null;
|
|
1369
1716
|
this.environmentId = environmentId;
|
|
1370
1717
|
this.storageKey = `${STORAGE_KEY}-${storageKey != null ? storageKey : environmentId}`;
|
|
1371
1718
|
this.baseMPCRelayApiUrl = baseMPCRelayApiUrl;
|
|
@@ -1383,9 +1730,12 @@ class DynamicWalletClient {
|
|
|
1383
1730
|
this.memoryStorage = {};
|
|
1384
1731
|
this.storage = memoryLocalStorageAdapter(this.memoryStorage);
|
|
1385
1732
|
}
|
|
1733
|
+
this.iframeDomain = IFRAME_DOMAIN;
|
|
1734
|
+
// Generate unique instanceId when client is created
|
|
1735
|
+
this.instanceId = crypto.randomUUID();
|
|
1386
1736
|
// initialize the client
|
|
1387
1737
|
this.initialize();
|
|
1388
1738
|
}
|
|
1389
1739
|
}
|
|
1390
1740
|
|
|
1391
|
-
export { DynamicWalletClient,
|
|
1741
|
+
export { DynamicWalletClient, base64ToBytes, bytesToBase64, ensureBase64Padding, getClientKeyShareBackupInfo, getClientKeyShareExportFileName, getMPCSignatureScheme, getMPCSigner, isBrowser, isHexString, mergeUniqueKeyShares, retryPromise, stringToBytes, timeoutPromise };
|