@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 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: undefined
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: undefined
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
- async recoverEncryptedBackupByWallet({ accountAddress, password }) {
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('recoverEncryptedBackupByWallet wallet', wallet);
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
- // TODO: allow handling backup from other sources
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
- decryptedKeyShares.forEach((keyShare)=>{
730
- this.restoreBackupShare({
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
- async getWallet({ accountAddress }) {
947
- if (accountAddress) {
948
- if (this.walletMap[accountAddress] && this.walletMap[accountAddress].clientKeyShares.length > 0 && this.walletMap[accountAddress].thresholdSignatureScheme) {
949
- this.logger.debug('Wallet already exists', this.walletMap[accountAddress]);
950
- return this.walletMap[accountAddress];
951
- } else {
952
- var _user_verifiedCredentials;
953
- this.logger.debug('Wallet needs to be restored', this.walletMap[accountAddress]);
954
- const user = await this.apiClient.getUser();
955
- const wallet = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.find((vc)=>vc.address.toLowerCase() === accountAddress.toLowerCase());
956
- this.logger.debug('Restoring wallet', wallet);
957
- const clientShares = wallet.walletProperties.keyShares.filter((ks)=>ks.backupLocation === 'dynamic');
958
- this.logger.debug('clientShares', clientShares);
959
- const walletProperties = wallet.walletProperties;
960
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
961
- walletId: wallet.id,
962
- chainName: wallet.chainName,
963
- accountAddress,
964
- thresholdSignatureScheme: walletProperties.thresholdSignatureScheme,
965
- derivationPath: walletProperties.derivationPath
966
- });
967
- // restore backup
968
- const decryptedKeyShares = await this.recoverEncryptedBackupByWallet({
969
- accountAddress,
970
- password: this.environmentId
971
- });
972
- //todo: check to see if their are other backups ie google drive, etc
973
- this.logger.debug('Recovered backup', decryptedKeyShares);
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
- // if there is only one wallet, return it by default
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 _acc_accountAddress, _acc_accountAddress1, _acc_accountAddress2;
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: ((_acc_accountAddress = acc[accountAddress]) == null ? void 0 : _acc_accountAddress.clientKeyShares) || [],
1007
- thresholdSignatureScheme: ((_acc_accountAddress1 = acc[accountAddress]) == null ? void 0 : _acc_accountAddress1.thresholdSignatureScheme) || undefined,
1008
- derivationPath: ((_acc_accountAddress2 = acc[accountAddress]) == null ? void 0 : _acc_accountAddress2.derivationPath) || undefined
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,