@dynamic-labs-wallet/browser 0.0.32 → 0.0.34
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 +359 -105
- package/index.esm.js +351 -107
- package/package.json +2 -2
- package/src/client.d.ts +90 -23
- package/src/client.d.ts.map +1 -1
- package/src/index.d.ts +1 -0
- package/src/index.d.ts.map +1 -1
- package/src/types.d.ts +26 -1
- package/src/types.d.ts.map +1 -1
- package/src/utils.d.ts +12 -0
- package/src/utils.d.ts.map +1 -1
package/index.cjs.js
CHANGED
|
@@ -63,6 +63,47 @@ const isHexString = (str)=>{
|
|
|
63
63
|
const getClientKeyShareExportFileName = ({ thresholdSignatureScheme, accountAddress })=>{
|
|
64
64
|
return `${CLIENT_KEYSHARE_EXPORT_FILENAME_PREFIX}-${thresholdSignatureScheme}-${accountAddress}.json`;
|
|
65
65
|
};
|
|
66
|
+
const getClientKeyShareBackupInfo = (params)=>{
|
|
67
|
+
var _params_walletProperties, _params_walletProperties_keyShares_;
|
|
68
|
+
const backups = {
|
|
69
|
+
[core.BackupLocation.DYNAMIC]: [],
|
|
70
|
+
[core.BackupLocation.GOOGLE_DRIVE]: [],
|
|
71
|
+
[core.BackupLocation.ICLOUD]: [],
|
|
72
|
+
[core.BackupLocation.USER]: [],
|
|
73
|
+
[core.BackupLocation.EXTERNAL]: []
|
|
74
|
+
};
|
|
75
|
+
if (!(params == null ? void 0 : (_params_walletProperties = params.walletProperties) == null ? void 0 : _params_walletProperties.keyShares)) {
|
|
76
|
+
return {
|
|
77
|
+
backups,
|
|
78
|
+
passwordEncrypted: false
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
params.walletProperties.keyShares.forEach((keyShare)=>{
|
|
82
|
+
if (backups[keyShare.backupLocation]) {
|
|
83
|
+
backups[keyShare.backupLocation].push(keyShare.id);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
const passwordEncrypted = Boolean((_params_walletProperties_keyShares_ = params.walletProperties.keyShares[0]) == null ? void 0 : _params_walletProperties_keyShares_.passwordEncrypted);
|
|
87
|
+
return {
|
|
88
|
+
backups,
|
|
89
|
+
passwordEncrypted
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Helper function to merge keyshares and remove duplicates based on pubkey and secretShare
|
|
94
|
+
* @param existingKeyShares - Array of existing keyshares
|
|
95
|
+
* @param newKeyShares - Array of new keyshares to merge
|
|
96
|
+
* @returns Array of merged unique keyshares
|
|
97
|
+
*/ const mergeUniqueKeyShares = (existingKeyShares, newKeyShares)=>{
|
|
98
|
+
const uniqueKeyShares = newKeyShares.filter((newShare)=>!existingKeyShares.some((existingShare)=>{
|
|
99
|
+
if (!(newShare == null ? void 0 : newShare.pubkey) || !(existingShare == null ? void 0 : existingShare.pubkey)) return false;
|
|
100
|
+
return newShare.pubkey.toString() === existingShare.pubkey.toString() && newShare.secretShare === existingShare.secretShare;
|
|
101
|
+
}));
|
|
102
|
+
return [
|
|
103
|
+
...existingKeyShares,
|
|
104
|
+
...uniqueKeyShares
|
|
105
|
+
];
|
|
106
|
+
};
|
|
66
107
|
|
|
67
108
|
const PBKDF2_ALGORITHM = 'PBKDF2';
|
|
68
109
|
const PBKDF2_ITERATIONS = 100000;
|
|
@@ -307,6 +348,18 @@ const localStorageWriteTest = {
|
|
|
307
348
|
}
|
|
308
349
|
});
|
|
309
350
|
|
|
351
|
+
var WalletOperation = /*#__PURE__*/ function(WalletOperation) {
|
|
352
|
+
WalletOperation["REACH_THRESHOLD"] = "REACH_THRESHOLD";
|
|
353
|
+
WalletOperation["REACH_ALL_PARTIES"] = "REACH_ALL_PARTIES";
|
|
354
|
+
WalletOperation["SIGN_MESSAGE"] = "SIGN_MESSAGE";
|
|
355
|
+
WalletOperation["SIGN_TRANSACTION"] = "SIGN_TRANSACTION";
|
|
356
|
+
WalletOperation["REFRESH"] = "REFRESH";
|
|
357
|
+
WalletOperation["RESHARE"] = "RESHARE";
|
|
358
|
+
WalletOperation["EXPORT_PRIVATE_KEY"] = "EXPORT_PRIVATE_KEY";
|
|
359
|
+
WalletOperation["NO_OPERATION"] = "NO_OPERATION";
|
|
360
|
+
return WalletOperation;
|
|
361
|
+
}({});
|
|
362
|
+
|
|
310
363
|
const logger = new logger$1.Logger('DynamicWaasWalletClient');
|
|
311
364
|
|
|
312
365
|
class DynamicWalletClient {
|
|
@@ -473,9 +526,16 @@ class DynamicWalletClient {
|
|
|
473
526
|
}
|
|
474
527
|
}
|
|
475
528
|
//todo: need to modify with imported flag
|
|
476
|
-
async sign({ accountAddress, message, chainName }) {
|
|
529
|
+
async sign({ accountAddress, message, chainName, password = undefined }) {
|
|
530
|
+
await this.verifyPassword({
|
|
531
|
+
accountAddress,
|
|
532
|
+
password,
|
|
533
|
+
walletOperation: WalletOperation.SIGN_MESSAGE
|
|
534
|
+
});
|
|
477
535
|
const wallet = await this.getWallet({
|
|
478
|
-
accountAddress
|
|
536
|
+
accountAddress,
|
|
537
|
+
password,
|
|
538
|
+
walletOperation: WalletOperation.SIGN_MESSAGE
|
|
479
539
|
});
|
|
480
540
|
// Perform the server sign
|
|
481
541
|
const data = await this.serverSign({
|
|
@@ -493,9 +553,16 @@ class DynamicWalletClient {
|
|
|
493
553
|
});
|
|
494
554
|
return signature;
|
|
495
555
|
}
|
|
496
|
-
async refreshWalletAccountShares({ accountAddress, chainName }) {
|
|
556
|
+
async refreshWalletAccountShares({ accountAddress, chainName, password = undefined }) {
|
|
557
|
+
await this.verifyPassword({
|
|
558
|
+
accountAddress,
|
|
559
|
+
password,
|
|
560
|
+
walletOperation: WalletOperation.REFRESH
|
|
561
|
+
});
|
|
497
562
|
const wallet = await this.getWallet({
|
|
498
|
-
accountAddress
|
|
563
|
+
accountAddress,
|
|
564
|
+
walletOperation: WalletOperation.REFRESH,
|
|
565
|
+
password
|
|
499
566
|
});
|
|
500
567
|
const mpcSigner = getMPCSigner({
|
|
501
568
|
chainName,
|
|
@@ -512,7 +579,7 @@ class DynamicWalletClient {
|
|
|
512
579
|
});
|
|
513
580
|
await this.storeEncryptedBackupByWallet({
|
|
514
581
|
accountAddress,
|
|
515
|
-
password:
|
|
582
|
+
password: password != null ? password : this.environmentId
|
|
516
583
|
});
|
|
517
584
|
return refreshResults;
|
|
518
585
|
}
|
|
@@ -565,9 +632,21 @@ class DynamicWalletClient {
|
|
|
565
632
|
existingClientKeyShares
|
|
566
633
|
};
|
|
567
634
|
}
|
|
568
|
-
async reshare({ chainName, accountAddress, oldThresholdSignatureScheme, newThresholdSignatureScheme }) {
|
|
635
|
+
async reshare({ chainName, accountAddress, oldThresholdSignatureScheme, newThresholdSignatureScheme, password = undefined }) {
|
|
636
|
+
await this.verifyPassword({
|
|
637
|
+
accountAddress,
|
|
638
|
+
password,
|
|
639
|
+
walletOperation: WalletOperation.RESHARE
|
|
640
|
+
});
|
|
641
|
+
const { existingClientShareCount } = core.getReshareConfig({
|
|
642
|
+
oldThresholdSignatureScheme,
|
|
643
|
+
newThresholdSignatureScheme
|
|
644
|
+
});
|
|
569
645
|
const wallet = await this.getWallet({
|
|
570
|
-
accountAddress
|
|
646
|
+
accountAddress,
|
|
647
|
+
walletOperation: WalletOperation.RESHARE,
|
|
648
|
+
shareCount: existingClientShareCount,
|
|
649
|
+
password
|
|
571
650
|
});
|
|
572
651
|
console.log(`Resharing from ${oldThresholdSignatureScheme} to ${newThresholdSignatureScheme}`);
|
|
573
652
|
const { newClientInitKeygenResults, newClientKeygenIds, existingClientKeygenIds, existingClientKeyShares } = await this.reshareStrategy({
|
|
@@ -609,13 +688,15 @@ class DynamicWalletClient {
|
|
|
609
688
|
});
|
|
610
689
|
await this.storeEncryptedBackupByWallet({
|
|
611
690
|
accountAddress,
|
|
612
|
-
password
|
|
691
|
+
password
|
|
613
692
|
});
|
|
614
693
|
return reshareResults;
|
|
615
694
|
}
|
|
616
|
-
async exportKey({ accountAddress, chainName }) {
|
|
695
|
+
async exportKey({ accountAddress, chainName, password = undefined }) {
|
|
617
696
|
const wallet = await this.getWallet({
|
|
618
|
-
accountAddress
|
|
697
|
+
accountAddress,
|
|
698
|
+
password,
|
|
699
|
+
walletOperation: WalletOperation.EXPORT_PRIVATE_KEY
|
|
619
700
|
});
|
|
620
701
|
const mpcSigner = getMPCSigner({
|
|
621
702
|
chainName,
|
|
@@ -690,9 +771,11 @@ class DynamicWalletClient {
|
|
|
690
771
|
const serializedEncryptedKeyShare = Buffer.from(JSON.stringify(encryptedKeyShare)).toString('base64');
|
|
691
772
|
return serializedEncryptedKeyShare;
|
|
692
773
|
}
|
|
693
|
-
async storeEncryptedBackupByWallet({ accountAddress, password }) {
|
|
774
|
+
async storeEncryptedBackupByWallet({ accountAddress, password = undefined, walletOperation = WalletOperation.REACH_ALL_PARTIES }) {
|
|
694
775
|
await this.getWallet({
|
|
695
|
-
accountAddress
|
|
776
|
+
accountAddress,
|
|
777
|
+
password,
|
|
778
|
+
walletOperation
|
|
696
779
|
});
|
|
697
780
|
const encryptedKeyShares = await Promise.all(this.walletMap[accountAddress].clientKeyShares.map((keyShare)=>this.encryptKeyShare({
|
|
698
781
|
keyShare,
|
|
@@ -705,6 +788,17 @@ class DynamicWalletClient {
|
|
|
705
788
|
});
|
|
706
789
|
return data;
|
|
707
790
|
}
|
|
791
|
+
async updatePassword({ accountAddress, existingPassword, newPassword }) {
|
|
792
|
+
await this.getWallet({
|
|
793
|
+
accountAddress,
|
|
794
|
+
password: existingPassword,
|
|
795
|
+
walletOperation: WalletOperation.REACH_ALL_PARTIES
|
|
796
|
+
});
|
|
797
|
+
await this.storeEncryptedBackupByWallet({
|
|
798
|
+
accountAddress,
|
|
799
|
+
password: newPassword
|
|
800
|
+
});
|
|
801
|
+
}
|
|
708
802
|
async decryptKeyShare({ keyShare, password }) {
|
|
709
803
|
const decodedKeyShare = JSON.parse(Buffer.from(keyShare, 'base64').toString());
|
|
710
804
|
const decryptedKeyShare = await decryptData({
|
|
@@ -714,28 +808,56 @@ class DynamicWalletClient {
|
|
|
714
808
|
const deserializedKeyShare = JSON.parse(decryptedKeyShare);
|
|
715
809
|
return deserializedKeyShare;
|
|
716
810
|
}
|
|
717
|
-
|
|
811
|
+
/**
|
|
812
|
+
* Helper function to determine keyshare recovery strategy for dynamic shares.
|
|
813
|
+
* For REFRESH operations, retrieves enough shares to meet the client threshold.
|
|
814
|
+
* For all other operations, retrieves just 1 share.
|
|
815
|
+
*
|
|
816
|
+
* @param clientKeyShareBackupInfo - Information about backed up key shares
|
|
817
|
+
* @param thresholdSignatureScheme - The signature scheme being used (2-of-2, 2-of-3, etc)
|
|
818
|
+
* @param walletOperation - The operation being performed (REFRESH, SIGN_MESSAGE, etc)
|
|
819
|
+
* @param shareCount - The number of shares to recover if specified for reshare operations
|
|
820
|
+
* @returns @shares: Object mapping backup locations to arrays of share IDs to recover
|
|
821
|
+
* @returns @requiredShareCount: The number of shares required to recover
|
|
822
|
+
*/ recoverStrategy({ clientKeyShareBackupInfo, thresholdSignatureScheme, walletOperation, shareCount = undefined }) {
|
|
823
|
+
const { backups } = clientKeyShareBackupInfo;
|
|
824
|
+
const { clientThreshold } = core.MPC_CONFIG[thresholdSignatureScheme];
|
|
825
|
+
let requiredShareCount = walletOperation === WalletOperation.REFRESH || walletOperation === WalletOperation.REACH_ALL_PARTIES || walletOperation === WalletOperation.RESHARE ? clientThreshold : 1;
|
|
826
|
+
// Override requiredShareCount if shareCount is provided
|
|
827
|
+
if (shareCount !== undefined) {
|
|
828
|
+
requiredShareCount = shareCount;
|
|
829
|
+
}
|
|
830
|
+
const dynamicShares = backups[core.BackupLocation.DYNAMIC].slice(0, requiredShareCount);
|
|
831
|
+
return {
|
|
832
|
+
shares: {
|
|
833
|
+
[core.BackupLocation.DYNAMIC]: dynamicShares
|
|
834
|
+
},
|
|
835
|
+
requiredShareCount
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
async recoverEncryptedBackupByWallet({ accountAddress, password, walletOperation, shareCount = undefined }) {
|
|
718
839
|
const wallet = this.walletMap[accountAddress];
|
|
719
|
-
this.logger.debug(
|
|
840
|
+
this.logger.debug(`recoverEncryptedBackupByWallet wallet: ${walletOperation}`, wallet);
|
|
841
|
+
const { shares } = this.recoverStrategy({
|
|
842
|
+
clientKeyShareBackupInfo: wallet.clientKeySharesBackupInfo,
|
|
843
|
+
thresholdSignatureScheme: wallet.thresholdSignatureScheme,
|
|
844
|
+
walletOperation,
|
|
845
|
+
shareCount
|
|
846
|
+
});
|
|
847
|
+
const { dynamic: dynamicKeyShareIds } = shares;
|
|
720
848
|
const data = await this.apiClient.recoverEncryptedBackupByWallet({
|
|
721
|
-
walletId: wallet.walletId
|
|
849
|
+
walletId: wallet.walletId,
|
|
850
|
+
keyShareIds: dynamicKeyShareIds
|
|
722
851
|
});
|
|
723
|
-
|
|
724
|
-
const dynamicKeyShares = data.keyShares.filter((keyShare)=>keyShare.encryptedAccountCredential !== null && keyShare.backupLocation === 'dynamic');
|
|
852
|
+
const dynamicKeyShares = data.keyShares.filter((keyShare)=>keyShare.encryptedAccountCredential !== null && keyShare.backupLocation === core.BackupLocation.DYNAMIC);
|
|
725
853
|
const decryptedKeyShares = await Promise.all(dynamicKeyShares.map((keyShare)=>this.decryptKeyShare({
|
|
726
854
|
keyShare: keyShare.encryptedAccountCredential,
|
|
727
855
|
password: password != null ? password : this.environmentId
|
|
728
856
|
})));
|
|
729
|
-
|
|
730
|
-
this.
|
|
731
|
-
walletId: wallet.walletId,
|
|
732
|
-
accountAddress,
|
|
733
|
-
chainName: data.chainName,
|
|
734
|
-
keyShare,
|
|
735
|
-
thresholdSignatureScheme: wallet.thresholdSignatureScheme,
|
|
736
|
-
derivationPath: wallet.derivationPath
|
|
737
|
-
});
|
|
857
|
+
this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
|
|
858
|
+
clientKeyShares: mergeUniqueKeyShares(this.walletMap[accountAddress].clientKeyShares || [], decryptedKeyShares)
|
|
738
859
|
});
|
|
860
|
+
await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
|
|
739
861
|
return decryptedKeyShares;
|
|
740
862
|
}
|
|
741
863
|
async restoreWallets() {
|
|
@@ -746,33 +868,11 @@ class DynamicWalletClient {
|
|
|
746
868
|
}
|
|
747
869
|
this.walletMap = JSON.parse(wallets);
|
|
748
870
|
}
|
|
749
|
-
async restoreBackupShare({ walletId, accountAddress, chainName, keyShare, thresholdSignatureScheme, derivationPath }) {
|
|
750
|
-
var _this_walletMap_accountAddress;
|
|
751
|
-
// Get existing shares if any
|
|
752
|
-
const existingShares = ((_this_walletMap_accountAddress = this.walletMap[accountAddress]) == null ? void 0 : _this_walletMap_accountAddress.clientKeyShares) || [];
|
|
753
|
-
// Check if this share already exists to prevent duplicates
|
|
754
|
-
const isDuplicate = existingShares.some((existingShare)=>{
|
|
755
|
-
var _existingShare_pubkey, _keyShare_pubkey;
|
|
756
|
-
return ((_existingShare_pubkey = existingShare.pubkey) == null ? void 0 : _existingShare_pubkey.toString()) === ((_keyShare_pubkey = keyShare.pubkey) == null ? void 0 : _keyShare_pubkey.toString()) && existingShare.secretShare === keyShare.secretShare;
|
|
757
|
-
});
|
|
758
|
-
// Only add the share if it's not a duplicate
|
|
759
|
-
const updatedShares = isDuplicate ? existingShares : [
|
|
760
|
-
...existingShares,
|
|
761
|
-
keyShare
|
|
762
|
-
];
|
|
763
|
-
this.walletMap[accountAddress] = {
|
|
764
|
-
walletId,
|
|
765
|
-
chainName,
|
|
766
|
-
accountAddress,
|
|
767
|
-
clientKeyShares: updatedShares,
|
|
768
|
-
thresholdSignatureScheme,
|
|
769
|
-
derivationPath
|
|
770
|
-
};
|
|
771
|
-
await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
|
|
772
|
-
}
|
|
773
871
|
async backupKeySharesToGoogleDrive({ accountAddress, fileName, oauthAccountId, password }) {
|
|
774
872
|
await this.getWallet({
|
|
775
|
-
accountAddress
|
|
873
|
+
accountAddress,
|
|
874
|
+
walletOperation: WalletOperation.REACH_ALL_PARTIES,
|
|
875
|
+
password
|
|
776
876
|
});
|
|
777
877
|
const clientKeyShares = this.walletMap[accountAddress].clientKeyShares;
|
|
778
878
|
if (clientKeyShares.length === 0) {
|
|
@@ -857,16 +957,8 @@ class DynamicWalletClient {
|
|
|
857
957
|
keyShare,
|
|
858
958
|
password
|
|
859
959
|
})));
|
|
860
|
-
const existingKeyShares = this.walletMap[accountAddress].clientKeyShares || [];
|
|
861
|
-
const uniqueKeyShares = decryptedKeyShares.filter((newShare)=>!existingKeyShares.some((existingShare)=>{
|
|
862
|
-
if (!(newShare == null ? void 0 : newShare.pubkey) || !(existingShare == null ? void 0 : existingShare.pubkey)) return false;
|
|
863
|
-
return newShare.pubkey.toString() === existingShare.pubkey.toString() && newShare.secretShare === existingShare.secretShare;
|
|
864
|
-
}));
|
|
865
960
|
this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
|
|
866
|
-
clientKeyShares: [
|
|
867
|
-
...existingKeyShares,
|
|
868
|
-
...uniqueKeyShares
|
|
869
|
-
]
|
|
961
|
+
clientKeyShares: mergeUniqueKeyShares(this.walletMap[accountAddress].clientKeyShares || [], decryptedKeyShares)
|
|
870
962
|
});
|
|
871
963
|
return decryptedKeyShares;
|
|
872
964
|
}
|
|
@@ -914,9 +1006,20 @@ class DynamicWalletClient {
|
|
|
914
1006
|
clientKeyShares: clientKeygenResults
|
|
915
1007
|
};
|
|
916
1008
|
}
|
|
917
|
-
async exportClientKeyshares({ accountAddress }) {
|
|
1009
|
+
async exportClientKeyshares({ accountAddress, password }) {
|
|
1010
|
+
await this.verifyPassword({
|
|
1011
|
+
accountAddress,
|
|
1012
|
+
password,
|
|
1013
|
+
walletOperation: WalletOperation.REACH_ALL_PARTIES
|
|
1014
|
+
});
|
|
1015
|
+
await this.getWallet({
|
|
1016
|
+
accountAddress,
|
|
1017
|
+
walletOperation: WalletOperation.REACH_ALL_PARTIES,
|
|
1018
|
+
password
|
|
1019
|
+
});
|
|
918
1020
|
const clientKeyShares = await this.getClientKeyShares({
|
|
919
|
-
accountAddress
|
|
1021
|
+
accountAddress,
|
|
1022
|
+
password
|
|
920
1023
|
});
|
|
921
1024
|
if (!accountAddress) {
|
|
922
1025
|
throw new Error('Must provide an account address');
|
|
@@ -937,75 +1040,216 @@ class DynamicWalletClient {
|
|
|
937
1040
|
a.download = `${CLIENT_KEYSHARE_EXPORT_FILENAME_PREFIX}-${accountAddress}.txt`;
|
|
938
1041
|
a.click();
|
|
939
1042
|
}
|
|
940
|
-
async getClientKeyShares({ accountAddress }) {
|
|
1043
|
+
async getClientKeyShares({ accountAddress, password }) {
|
|
941
1044
|
const wallet = await this.getWallet({
|
|
942
|
-
accountAddress
|
|
1045
|
+
accountAddress,
|
|
1046
|
+
password,
|
|
1047
|
+
walletOperation: WalletOperation.REACH_THRESHOLD
|
|
943
1048
|
});
|
|
944
1049
|
return wallet.clientKeyShares;
|
|
945
1050
|
}
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1051
|
+
/**
|
|
1052
|
+
* Helper function to check if the required wallet fields are present and valid
|
|
1053
|
+
* @param accountAddress - The account address of the wallet to check
|
|
1054
|
+
* @param walletOperation - The wallet operation that determines required fields
|
|
1055
|
+
* @returns boolean indicating if wallet needs to be re-fetched and restored from server
|
|
1056
|
+
*/ async checkWalletFields({ accountAddress, walletOperation = WalletOperation.REACH_THRESHOLD, shareCount }) {
|
|
1057
|
+
let keyshareCheck = false;
|
|
1058
|
+
let walletCheck = false;
|
|
1059
|
+
let thresholdSignatureSchemeCheck = false;
|
|
1060
|
+
// check if wallet exists
|
|
1061
|
+
const existingWallet = this.walletMap[accountAddress];
|
|
1062
|
+
if (existingWallet) {
|
|
1063
|
+
walletCheck = true;
|
|
1064
|
+
}
|
|
1065
|
+
// check if threshold signature scheme exists
|
|
1066
|
+
if (existingWallet == null ? void 0 : existingWallet.thresholdSignatureScheme) {
|
|
1067
|
+
thresholdSignatureSchemeCheck = true;
|
|
1068
|
+
}
|
|
1069
|
+
// check if wallet already exists with sufficient keyshares
|
|
1070
|
+
if (existingWallet) {
|
|
1071
|
+
var _existingWallet_clientKeyShares;
|
|
1072
|
+
const { shares } = this.recoverStrategy({
|
|
1073
|
+
clientKeyShareBackupInfo: existingWallet.clientKeySharesBackupInfo || {
|
|
1074
|
+
backups: getClientKeyShareBackupInfo()
|
|
1075
|
+
},
|
|
1076
|
+
thresholdSignatureScheme: existingWallet.thresholdSignatureScheme,
|
|
1077
|
+
walletOperation,
|
|
1078
|
+
shareCount
|
|
1079
|
+
});
|
|
1080
|
+
const { dynamic: requiredDynamicKeyShareIds = [] } = shares;
|
|
1081
|
+
if (requiredDynamicKeyShareIds.length <= (((_existingWallet_clientKeyShares = existingWallet.clientKeyShares) == null ? void 0 : _existingWallet_clientKeyShares.length) || 0)) {
|
|
1082
|
+
keyshareCheck = true;
|
|
974
1083
|
}
|
|
975
1084
|
}
|
|
1085
|
+
return walletCheck && thresholdSignatureSchemeCheck && keyshareCheck;
|
|
1086
|
+
}
|
|
1087
|
+
/**
|
|
1088
|
+
* verifyPassword attempts to recover and decrypt 1 client key share using the provided password
|
|
1089
|
+
* if successful, the key share is encrypted with the new password and stored
|
|
1090
|
+
* if unsuccessful, throws an error
|
|
1091
|
+
*/ async verifyPassword({ accountAddress, password = undefined, walletOperation = WalletOperation.NO_OPERATION }) {
|
|
1092
|
+
await this.getWallet({
|
|
1093
|
+
accountAddress,
|
|
1094
|
+
password,
|
|
1095
|
+
walletOperation
|
|
1096
|
+
});
|
|
1097
|
+
if (await this.requiresPasswordForOperation({
|
|
1098
|
+
accountAddress,
|
|
1099
|
+
walletOperation
|
|
1100
|
+
}) && !password) {
|
|
1101
|
+
throw new Error('Password is required for operation but not provided');
|
|
1102
|
+
}
|
|
1103
|
+
// silent return if no password is provided and operation does not require a password
|
|
1104
|
+
if (!password) {
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1107
|
+
const { backups } = await this.getWalletClientKeyShareBackupInfo({
|
|
1108
|
+
accountAddress
|
|
1109
|
+
});
|
|
1110
|
+
const { dynamic: dynamicKeyShareIds = [] } = backups;
|
|
1111
|
+
if (!dynamicKeyShareIds || dynamicKeyShareIds.length === 0) {
|
|
1112
|
+
throw new Error('No dynamic key shares found');
|
|
1113
|
+
}
|
|
1114
|
+
try {
|
|
1115
|
+
await this.recoverEncryptedBackupByWallet({
|
|
1116
|
+
accountAddress,
|
|
1117
|
+
password,
|
|
1118
|
+
walletOperation: WalletOperation.NO_OPERATION
|
|
1119
|
+
});
|
|
1120
|
+
} catch (error) {
|
|
1121
|
+
this.logger.error('Error in verifying password', error);
|
|
1122
|
+
throw new Error('Incorrect password');
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
async isPasswordEncrypted({ accountAddress }) {
|
|
1126
|
+
const clientKeySharesBackupInfo = await this.getWalletClientKeyShareBackupInfo({
|
|
1127
|
+
accountAddress
|
|
1128
|
+
});
|
|
1129
|
+
return clientKeySharesBackupInfo == null ? void 0 : clientKeySharesBackupInfo.passwordEncrypted;
|
|
1130
|
+
}
|
|
1131
|
+
/**
|
|
1132
|
+
* check if the operation requires a password
|
|
1133
|
+
*/ async requiresPasswordForOperation({ accountAddress, walletOperation = WalletOperation.REACH_THRESHOLD }) {
|
|
1134
|
+
const isEncrypted = await this.isPasswordEncrypted({
|
|
1135
|
+
accountAddress
|
|
1136
|
+
});
|
|
1137
|
+
if (!isEncrypted) {
|
|
1138
|
+
return false;
|
|
1139
|
+
}
|
|
1140
|
+
return this.requiresRestoreBackupSharesForOperation({
|
|
1141
|
+
accountAddress,
|
|
1142
|
+
walletOperation
|
|
1143
|
+
});
|
|
1144
|
+
}
|
|
1145
|
+
/**
|
|
1146
|
+
* check if the operation requires restoring backup shares
|
|
1147
|
+
*/ async requiresRestoreBackupSharesForOperation({ accountAddress, walletOperation = WalletOperation.REACH_THRESHOLD }) {
|
|
1148
|
+
const clientKeySharesBackupInfo = await this.getWalletClientKeyShareBackupInfo({
|
|
1149
|
+
accountAddress
|
|
1150
|
+
});
|
|
1151
|
+
const clientKeyShares = this.walletMap[accountAddress].clientKeyShares || [];
|
|
1152
|
+
if (walletOperation === WalletOperation.REACH_ALL_PARTIES || walletOperation === WalletOperation.REFRESH || walletOperation === WalletOperation.RESHARE) {
|
|
1153
|
+
return true;
|
|
1154
|
+
}
|
|
1155
|
+
const { requiredShareCount } = this.recoverStrategy({
|
|
1156
|
+
clientKeyShareBackupInfo: clientKeySharesBackupInfo,
|
|
1157
|
+
thresholdSignatureScheme: this.walletMap[accountAddress].thresholdSignatureScheme,
|
|
1158
|
+
walletOperation
|
|
1159
|
+
});
|
|
1160
|
+
if (clientKeyShares.length >= requiredShareCount) {
|
|
1161
|
+
return false;
|
|
1162
|
+
}
|
|
1163
|
+
return true;
|
|
1164
|
+
}
|
|
1165
|
+
async getWalletClientKeyShareBackupInfo({ accountAddress }) {
|
|
1166
|
+
var _this_walletMap_accountAddress_clientKeySharesBackupInfo_backups_BackupLocation_DYNAMIC, _this_walletMap_accountAddress_clientKeySharesBackupInfo_backups, _this_walletMap_accountAddress_clientKeySharesBackupInfo, _this_walletMap_accountAddress, _user_verifiedCredentials;
|
|
1167
|
+
// Return existing backup info if it exists
|
|
1168
|
+
if (((_this_walletMap_accountAddress = this.walletMap[accountAddress]) == null ? void 0 : (_this_walletMap_accountAddress_clientKeySharesBackupInfo = _this_walletMap_accountAddress.clientKeySharesBackupInfo) == null ? void 0 : (_this_walletMap_accountAddress_clientKeySharesBackupInfo_backups = _this_walletMap_accountAddress_clientKeySharesBackupInfo.backups) == null ? void 0 : (_this_walletMap_accountAddress_clientKeySharesBackupInfo_backups_BackupLocation_DYNAMIC = _this_walletMap_accountAddress_clientKeySharesBackupInfo_backups[core.BackupLocation.DYNAMIC]) == null ? void 0 : _this_walletMap_accountAddress_clientKeySharesBackupInfo_backups_BackupLocation_DYNAMIC.length) > 0) {
|
|
1169
|
+
return this.walletMap[accountAddress].clientKeySharesBackupInfo;
|
|
1170
|
+
}
|
|
1171
|
+
// Get backup info from server
|
|
1172
|
+
const user = await this.apiClient.getUser();
|
|
1173
|
+
const wallet = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.find((vc)=>vc.address.toLowerCase() === accountAddress.toLowerCase());
|
|
1174
|
+
return getClientKeyShareBackupInfo({
|
|
1175
|
+
walletProperties: wallet == null ? void 0 : wallet.walletProperties
|
|
1176
|
+
});
|
|
1177
|
+
}
|
|
1178
|
+
async getWallet({ accountAddress, walletOperation = WalletOperation.NO_OPERATION, shareCount = undefined, password = undefined }) {
|
|
1179
|
+
var _user_verifiedCredentials;
|
|
1180
|
+
const existingWalletCheck = await this.checkWalletFields({
|
|
1181
|
+
accountAddress,
|
|
1182
|
+
walletOperation,
|
|
1183
|
+
shareCount
|
|
1184
|
+
});
|
|
1185
|
+
if (existingWalletCheck) {
|
|
1186
|
+
this.logger.debug(`Wallet ${accountAddress} already exists`);
|
|
1187
|
+
return this.walletMap[accountAddress];
|
|
1188
|
+
}
|
|
1189
|
+
// Fetch and restore wallet from server
|
|
1190
|
+
const user = await this.apiClient.getUser();
|
|
1191
|
+
const wallet = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.find((vc)=>vc.address.toLowerCase() === accountAddress.toLowerCase());
|
|
1192
|
+
this.logger.debug('Restoring wallet', wallet);
|
|
1193
|
+
const walletProperties = wallet.walletProperties;
|
|
1194
|
+
this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
|
|
1195
|
+
walletId: wallet.id,
|
|
1196
|
+
chainName: wallet.chainName,
|
|
1197
|
+
accountAddress,
|
|
1198
|
+
thresholdSignatureScheme: walletProperties.thresholdSignatureScheme,
|
|
1199
|
+
derivationPath: walletProperties.derivationPath,
|
|
1200
|
+
clientKeySharesBackupInfo: getClientKeyShareBackupInfo({
|
|
1201
|
+
walletProperties
|
|
1202
|
+
})
|
|
1203
|
+
});
|
|
1204
|
+
if (walletOperation !== WalletOperation.NO_OPERATION && await this.requiresRestoreBackupSharesForOperation({
|
|
1205
|
+
accountAddress,
|
|
1206
|
+
walletOperation
|
|
1207
|
+
})) {
|
|
1208
|
+
const decryptedKeyShares = await this.recoverEncryptedBackupByWallet({
|
|
1209
|
+
accountAddress,
|
|
1210
|
+
password: password != null ? password : this.environmentId,
|
|
1211
|
+
walletOperation: walletOperation,
|
|
1212
|
+
shareCount
|
|
1213
|
+
});
|
|
1214
|
+
this.logger.debug('Recovered backup', decryptedKeyShares);
|
|
1215
|
+
}
|
|
976
1216
|
const walletCount = Object.keys(this.walletMap).length;
|
|
977
|
-
// if there are no wallets, throw an error
|
|
978
1217
|
if (walletCount === 0) {
|
|
979
1218
|
throw new Error('No wallets found');
|
|
980
1219
|
}
|
|
981
|
-
//
|
|
1220
|
+
// Return the only wallet if there's just one
|
|
982
1221
|
if (walletCount === 1) {
|
|
983
1222
|
return Object.values(this.walletMap)[0];
|
|
984
1223
|
}
|
|
985
|
-
if (!accountAddress) {
|
|
986
|
-
throw new Error('Must provide an account address');
|
|
987
|
-
}
|
|
988
1224
|
return this.walletMap[accountAddress];
|
|
989
1225
|
}
|
|
990
1226
|
async getWallets() {
|
|
991
1227
|
var _user_verifiedCredentials;
|
|
992
1228
|
const user = await this.apiClient.getUser();
|
|
993
1229
|
const waasWallets = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.filter((vc)=>vc.walletName === 'dynamicwaas');
|
|
994
|
-
const wallets = waasWallets.map((vc)=>
|
|
1230
|
+
const wallets = waasWallets.map((vc)=>{
|
|
1231
|
+
var _vc_walletProperties;
|
|
1232
|
+
return {
|
|
995
1233
|
walletId: vc.id,
|
|
996
1234
|
chainName: vc.chain,
|
|
997
|
-
accountAddress: vc.address
|
|
998
|
-
|
|
1235
|
+
accountAddress: vc.address,
|
|
1236
|
+
clientKeySharesBackupInfo: getClientKeyShareBackupInfo({
|
|
1237
|
+
walletProperties: vc.walletProperties || {}
|
|
1238
|
+
}),
|
|
1239
|
+
thresholdSignatureScheme: (_vc_walletProperties = vc.walletProperties) == null ? void 0 : _vc_walletProperties.thresholdSignatureScheme
|
|
1240
|
+
};
|
|
1241
|
+
});
|
|
999
1242
|
this.walletMap = wallets.reduce((acc, wallet)=>{
|
|
1000
|
-
var
|
|
1243
|
+
var _acc_wallet_accountAddress, _acc_accountAddress;
|
|
1001
1244
|
const accountAddress = wallet.accountAddress;
|
|
1002
1245
|
acc[wallet.accountAddress] = {
|
|
1003
1246
|
walletId: wallet.walletId,
|
|
1004
1247
|
chainName: wallet.chainName,
|
|
1005
|
-
accountAddress: accountAddress,
|
|
1006
|
-
clientKeyShares: ((
|
|
1007
|
-
|
|
1008
|
-
derivationPath: ((
|
|
1248
|
+
accountAddress: wallet.accountAddress,
|
|
1249
|
+
clientKeyShares: ((_acc_wallet_accountAddress = acc[wallet.accountAddress]) == null ? void 0 : _acc_wallet_accountAddress.clientKeyShares) || [],
|
|
1250
|
+
clientKeySharesBackupInfo: wallet.clientKeySharesBackupInfo,
|
|
1251
|
+
derivationPath: ((_acc_accountAddress = acc[accountAddress]) == null ? void 0 : _acc_accountAddress.derivationPath) || undefined,
|
|
1252
|
+
thresholdSignatureScheme: wallet.thresholdSignatureScheme
|
|
1009
1253
|
};
|
|
1010
1254
|
return acc;
|
|
1011
1255
|
}, {});
|
|
@@ -1088,8 +1332,18 @@ Object.defineProperty(exports, "MessageHash", {
|
|
|
1088
1332
|
get: function () { return web.MessageHash; }
|
|
1089
1333
|
});
|
|
1090
1334
|
exports.DynamicWalletClient = DynamicWalletClient;
|
|
1335
|
+
exports.WalletOperation = WalletOperation;
|
|
1336
|
+
exports.base64ToBytes = base64ToBytes;
|
|
1337
|
+
exports.bytesToBase64 = bytesToBase64;
|
|
1338
|
+
exports.ensureBase64Padding = ensureBase64Padding;
|
|
1339
|
+
exports.getClientKeyShareBackupInfo = getClientKeyShareBackupInfo;
|
|
1340
|
+
exports.getClientKeyShareExportFileName = getClientKeyShareExportFileName;
|
|
1091
1341
|
exports.getMPCSignatureScheme = getMPCSignatureScheme;
|
|
1092
1342
|
exports.getMPCSigner = getMPCSigner;
|
|
1343
|
+
exports.isBrowser = isBrowser;
|
|
1344
|
+
exports.isHexString = isHexString;
|
|
1345
|
+
exports.mergeUniqueKeyShares = mergeUniqueKeyShares;
|
|
1346
|
+
exports.stringToBytes = stringToBytes;
|
|
1093
1347
|
Object.keys(core).forEach(function (k) {
|
|
1094
1348
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
1095
1349
|
enumerable: true,
|