@dynamic-labs-wallet/browser 0.0.85 → 0.0.86

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
@@ -631,6 +631,9 @@ class DynamicWalletClient {
631
631
  };
632
632
  } catch (error) {
633
633
  this.logger.error('[DynamicWaasWalletClient]: Error keygen', error);
634
+ if (error instanceof core.AxiosError) {
635
+ core.handleAxiosError(error);
636
+ }
634
637
  throw error;
635
638
  }
636
639
  }
@@ -701,6 +704,9 @@ class DynamicWalletClient {
701
704
  };
702
705
  } catch (error) {
703
706
  this.logger.error('[DynamicWaasWalletClient]: Error in importRawPrivateKey', error);
707
+ if (error instanceof core.AxiosError) {
708
+ core.handleAxiosError(error);
709
+ }
704
710
  throw error;
705
711
  }
706
712
  }
@@ -739,91 +745,107 @@ class DynamicWalletClient {
739
745
  }
740
746
  //todo: need to modify with imported flag
741
747
  async sign({ accountAddress, message, chainName, password = undefined, isFormatted = false, signedSessionId }) {
742
- await this.verifyPassword({
743
- accountAddress,
744
- password,
745
- walletOperation: core.WalletOperation.SIGN_MESSAGE,
746
- signedSessionId
747
- });
748
- const wallet = await this.getWallet({
749
- accountAddress,
750
- password,
751
- walletOperation: core.WalletOperation.SIGN_MESSAGE,
752
- signedSessionId
753
- });
754
- // Perform the server sign
755
- const data = await this.serverSign({
756
- walletId: wallet.walletId,
757
- message,
758
- isFormatted
759
- });
760
- this.logger.debug('[DynamicWaasWalletClient] Server sign completed', {
761
- message,
762
- accountAddress,
763
- walletId: wallet.walletId,
764
- roomId: data.roomId
765
- });
766
- const derivationPath = wallet.derivationPath && wallet.derivationPath != '' ? new Uint32Array(Object.values(JSON.parse(wallet.derivationPath))) : undefined;
767
- // Perform the client sign and return the signature
768
- const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
769
- accountAddress
770
- });
771
- const signature = await this.clientSign({
772
- chainName,
773
- message,
774
- roomId: data.roomId,
775
- keyShare: clientKeyShares[0],
776
- derivationPath,
777
- isFormatted
778
- });
779
- this.logger.debug('[DynamicWaasWalletClient] Client sign completed', {
780
- chainName,
781
- message,
782
- roomId: data.roomId,
783
- derivationPath,
784
- isFormatted
785
- });
786
- return signature;
748
+ try {
749
+ await this.verifyPassword({
750
+ accountAddress,
751
+ password,
752
+ walletOperation: core.WalletOperation.SIGN_MESSAGE,
753
+ signedSessionId
754
+ });
755
+ const wallet = await this.getWallet({
756
+ accountAddress,
757
+ password,
758
+ walletOperation: core.WalletOperation.SIGN_MESSAGE,
759
+ signedSessionId
760
+ });
761
+ // Perform the server sign
762
+ const data = await this.serverSign({
763
+ walletId: wallet.walletId,
764
+ message,
765
+ isFormatted
766
+ });
767
+ this.logger.debug('[DynamicWaasWalletClient] Server sign completed', {
768
+ message,
769
+ accountAddress,
770
+ walletId: wallet.walletId,
771
+ roomId: data.roomId
772
+ });
773
+ const derivationPath = wallet.derivationPath && wallet.derivationPath != '' ? new Uint32Array(Object.values(JSON.parse(wallet.derivationPath))) : undefined;
774
+ // Perform the client sign and return the signature
775
+ const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
776
+ accountAddress
777
+ });
778
+ const signature = await this.clientSign({
779
+ chainName,
780
+ message,
781
+ roomId: data.roomId,
782
+ keyShare: clientKeyShares[0],
783
+ derivationPath,
784
+ isFormatted
785
+ });
786
+ this.logger.debug('[DynamicWaasWalletClient] Client sign completed', {
787
+ chainName,
788
+ message,
789
+ roomId: data.roomId,
790
+ derivationPath,
791
+ isFormatted
792
+ });
793
+ return signature;
794
+ } catch (error) {
795
+ this.logger.error('[DynamicWaasWalletClient]: Error in sign', error);
796
+ if (error instanceof core.AxiosError) {
797
+ core.handleAxiosError(error);
798
+ }
799
+ throw error;
800
+ }
787
801
  }
788
802
  async refreshWalletAccountShares({ accountAddress, chainName, password = undefined, signedSessionId }) {
789
- await this.verifyPassword({
790
- accountAddress,
791
- password,
792
- walletOperation: core.WalletOperation.REFRESH,
793
- signedSessionId
794
- });
795
- const wallet = await this.getWallet({
796
- accountAddress,
797
- walletOperation: core.WalletOperation.NO_OPERATION,
798
- password,
799
- signedSessionId
800
- });
801
- const mpcSigner = getMPCSigner({
802
- chainName,
803
- baseRelayUrl: this.baseMPCRelayApiUrl
804
- });
805
- // Create the room and refresh the shares
806
- const data = await this.apiClient.refreshWalletAccountShares({
807
- walletId: wallet.walletId
808
- });
809
- const roomId = data.roomId;
810
- const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
811
- accountAddress
812
- });
813
- const refreshResults = await Promise.all(clientKeyShares.map((clientKeyShare)=>mpcSigner.refresh(roomId, clientKeyShare)));
814
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
815
- clientKeySharesBackupInfo: getClientKeyShareBackupInfo()
816
- });
817
- await this.setClientKeySharesToLocalStorage({
818
- accountAddress,
819
- clientKeyShares: refreshResults,
820
- overwriteOrMerge: 'overwrite'
821
- });
822
- await this.storeEncryptedBackupByWallet({
823
- accountAddress,
824
- password: password != null ? password : this.environmentId,
825
- signedSessionId
826
- });
803
+ try {
804
+ await this.verifyPassword({
805
+ accountAddress,
806
+ password,
807
+ walletOperation: core.WalletOperation.REFRESH,
808
+ signedSessionId
809
+ });
810
+ const wallet = await this.getWallet({
811
+ accountAddress,
812
+ walletOperation: core.WalletOperation.NO_OPERATION,
813
+ password,
814
+ signedSessionId
815
+ });
816
+ const mpcSigner = getMPCSigner({
817
+ chainName,
818
+ baseRelayUrl: this.baseMPCRelayApiUrl
819
+ });
820
+ // Create the room and refresh the shares
821
+ const data = await this.apiClient.refreshWalletAccountShares({
822
+ walletId: wallet.walletId
823
+ });
824
+ const roomId = data.roomId;
825
+ const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
826
+ accountAddress
827
+ });
828
+ const refreshResults = await Promise.all(clientKeyShares.map((clientKeyShare)=>mpcSigner.refresh(roomId, clientKeyShare)));
829
+ this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
830
+ clientKeySharesBackupInfo: getClientKeyShareBackupInfo()
831
+ });
832
+ await this.setClientKeySharesToLocalStorage({
833
+ accountAddress,
834
+ clientKeyShares: refreshResults,
835
+ overwriteOrMerge: 'overwrite'
836
+ });
837
+ await this.storeEncryptedBackupByWallet({
838
+ accountAddress,
839
+ password: password != null ? password : this.environmentId,
840
+ signedSessionId
841
+ });
842
+ } catch (error) {
843
+ this.logger.error('[DynamicWaasWalletClient]: Error in refreshWalletAccountShares', error);
844
+ if (error instanceof core.AxiosError) {
845
+ core.handleAxiosError(error);
846
+ }
847
+ throw error;
848
+ }
827
849
  }
828
850
  async getExportId({ chainName, clientKeyShare }) {
829
851
  const mpcSigner = getMPCSigner({
@@ -877,68 +899,76 @@ class DynamicWalletClient {
877
899
  };
878
900
  }
879
901
  async reshare({ chainName, accountAddress, oldThresholdSignatureScheme, newThresholdSignatureScheme, password = undefined, signedSessionId }) {
880
- await this.verifyPassword({
881
- accountAddress,
882
- password,
883
- walletOperation: core.WalletOperation.RESHARE,
884
- signedSessionId
885
- });
886
- const { existingClientShareCount } = core.getReshareConfig({
887
- oldThresholdSignatureScheme,
888
- newThresholdSignatureScheme
889
- });
890
- const wallet = await this.getWallet({
891
- accountAddress,
892
- walletOperation: core.WalletOperation.NO_OPERATION,
893
- shareCount: existingClientShareCount,
894
- password,
895
- signedSessionId
896
- });
897
- const { newClientInitKeygenResults, newClientKeygenIds, existingClientKeygenIds, existingClientKeyShares } = await this.reshareStrategy({
898
- chainName,
899
- accountAddress,
900
- wallet,
901
- oldThresholdSignatureScheme,
902
- newThresholdSignatureScheme
903
- });
904
- const clientKeygenIds = [
905
- ...newClientKeygenIds,
906
- ...existingClientKeygenIds
907
- ];
908
- // Server to create the room and complete the server reshare logics
909
- const data = await this.apiClient.reshare({
910
- walletId: wallet.walletId,
911
- clientKeygenIds: clientKeygenIds,
912
- oldThresholdSignatureScheme,
913
- newThresholdSignatureScheme
914
- });
915
- const { roomId, serverKeygenIds, newServerKeygenIds = [] } = data;
916
- // Get the MPC config for the threshold signature scheme
917
- const oldMpcConfig = core.MPC_CONFIG[oldThresholdSignatureScheme];
918
- const newMpcConfig = core.MPC_CONFIG[newThresholdSignatureScheme];
919
- const allPartyKeygenIds = [
920
- ...clientKeygenIds,
921
- ...serverKeygenIds,
922
- ...newServerKeygenIds
923
- ];
924
- const mpcSigner = getMPCSigner({
925
- chainName,
926
- baseRelayUrl: this.baseMPCRelayApiUrl
927
- });
928
- const reshareResults = await Promise.all([
929
- ...newClientInitKeygenResults.map((keygenResult)=>mpcSigner.reshareNewParty(roomId, oldMpcConfig.threshold, newMpcConfig.threshold, keygenResult, allPartyKeygenIds)),
930
- ...existingClientKeyShares.map((keyShare)=>mpcSigner.reshareRemainingParty(roomId, newMpcConfig.threshold, keyShare, allPartyKeygenIds))
931
- ]);
932
- await this.setClientKeySharesToLocalStorage({
933
- accountAddress,
934
- clientKeyShares: reshareResults,
935
- overwriteOrMerge: 'overwrite'
936
- });
937
- await this.storeEncryptedBackupByWallet({
938
- accountAddress,
939
- password,
940
- signedSessionId
941
- });
902
+ try {
903
+ await this.verifyPassword({
904
+ accountAddress,
905
+ password,
906
+ walletOperation: core.WalletOperation.RESHARE,
907
+ signedSessionId
908
+ });
909
+ const { existingClientShareCount } = core.getReshareConfig({
910
+ oldThresholdSignatureScheme,
911
+ newThresholdSignatureScheme
912
+ });
913
+ const wallet = await this.getWallet({
914
+ accountAddress,
915
+ walletOperation: core.WalletOperation.NO_OPERATION,
916
+ shareCount: existingClientShareCount,
917
+ password,
918
+ signedSessionId
919
+ });
920
+ const { newClientInitKeygenResults, newClientKeygenIds, existingClientKeygenIds, existingClientKeyShares } = await this.reshareStrategy({
921
+ chainName,
922
+ accountAddress,
923
+ wallet,
924
+ oldThresholdSignatureScheme,
925
+ newThresholdSignatureScheme
926
+ });
927
+ const clientKeygenIds = [
928
+ ...newClientKeygenIds,
929
+ ...existingClientKeygenIds
930
+ ];
931
+ // Server to create the room and complete the server reshare logics
932
+ const data = await this.apiClient.reshare({
933
+ walletId: wallet.walletId,
934
+ clientKeygenIds: clientKeygenIds,
935
+ oldThresholdSignatureScheme,
936
+ newThresholdSignatureScheme
937
+ });
938
+ const { roomId, serverKeygenIds, newServerKeygenIds = [] } = data;
939
+ // Get the MPC config for the threshold signature scheme
940
+ const oldMpcConfig = core.MPC_CONFIG[oldThresholdSignatureScheme];
941
+ const newMpcConfig = core.MPC_CONFIG[newThresholdSignatureScheme];
942
+ const allPartyKeygenIds = [
943
+ ...clientKeygenIds,
944
+ ...serverKeygenIds,
945
+ ...newServerKeygenIds
946
+ ];
947
+ const mpcSigner = getMPCSigner({
948
+ chainName,
949
+ baseRelayUrl: this.baseMPCRelayApiUrl
950
+ });
951
+ const reshareResults = await Promise.all([
952
+ ...newClientInitKeygenResults.map((keygenResult)=>mpcSigner.reshareNewParty(roomId, oldMpcConfig.threshold, newMpcConfig.threshold, keygenResult, allPartyKeygenIds)),
953
+ ...existingClientKeyShares.map((keyShare)=>mpcSigner.reshareRemainingParty(roomId, newMpcConfig.threshold, keyShare, allPartyKeygenIds))
954
+ ]);
955
+ await this.setClientKeySharesToLocalStorage({
956
+ accountAddress,
957
+ clientKeyShares: reshareResults,
958
+ overwriteOrMerge: 'overwrite'
959
+ });
960
+ await this.storeEncryptedBackupByWallet({
961
+ accountAddress,
962
+ password,
963
+ signedSessionId
964
+ });
965
+ } catch (error) {
966
+ this.logger.error('[DynamicWaasWalletClient]: Error in reshare', error);
967
+ if (error instanceof core.AxiosError) {
968
+ core.handleAxiosError(error);
969
+ }
970
+ throw error;
971
+ }
942
972
  }
943
973
  async exportKey({ accountAddress, chainName, password = undefined, signedSessionId }) {
944
974
  try {
@@ -995,6 +1025,9 @@ class DynamicWalletClient {
995
1025
  };
996
1026
  } catch (error) {
997
1027
  this.logger.error('[DynamicWaasWalletClient]: Error in exportKey', error);
1028
+ if (error instanceof core.AxiosError) {
1029
+ core.handleAxiosError(error);
1030
+ }
998
1031
  throw error;
999
1032
  }
1000
1033
  }
@@ -1099,47 +1132,55 @@ class DynamicWalletClient {
1099
1132
  * @param {string} params.accountAddress - The account address of the wallet to backup
1100
1133
  * @param {string} [params.password] - Optional password for encrypting the key shares
1101
1134
  */ async storeEncryptedBackupByWallet({ accountAddress, clientKeyShares = undefined, password = undefined, signedSessionId }) {
1102
- const keySharesToBackup = clientKeyShares != null ? clientKeyShares : await this.getClientKeySharesFromLocalStorage({
1103
- accountAddress
1104
- });
1105
- const encryptedKeyShares = await Promise.all(keySharesToBackup.map((keyShare)=>this.encryptKeyShare({
1106
- keyShare,
1107
- password
1108
- })));
1109
- if (!this.walletMap[accountAddress].walletId) {
1110
- throw new Error(`WalletId not found for accountAddress: ${accountAddress}`);
1111
- }
1112
- // TODO(zfaizal2): throw error if signedSessionId is not provided after service deploy
1113
- const data = await this.apiClient.storeEncryptedBackupByWallet({
1114
- walletId: this.walletMap[accountAddress].walletId,
1115
- encryptedKeyShares,
1116
- passwordEncrypted: Boolean(password) && password !== this.environmentId,
1117
- signedSessionId
1118
- });
1119
- const hasGoogleDriveBackup = this.walletMap[accountAddress].clientKeySharesBackupInfo.backups[core.BackupLocation.GOOGLE_DRIVE].length > 0;
1120
- if (hasGoogleDriveBackup) {
1121
- const googleDriveKeyShareIds = await this.backupKeySharesToGoogleDrive({
1122
- accountAddress,
1123
- password,
1135
+ try {
1136
+ const keySharesToBackup = clientKeyShares != null ? clientKeyShares : await this.getClientKeySharesFromLocalStorage({
1137
+ accountAddress
1138
+ });
1139
+ const encryptedKeyShares = await Promise.all(keySharesToBackup.map((keyShare)=>this.encryptKeyShare({
1140
+ keyShare,
1141
+ password
1142
+ })));
1143
+ if (!this.walletMap[accountAddress].walletId) {
1144
+ throw new Error(`WalletId not found for accountAddress: ${accountAddress}`);
1145
+ }
1146
+ // TODO(zfaizal2): throw error if signedSessionId is not provided after service deploy
1147
+ const data = await this.apiClient.storeEncryptedBackupByWallet({
1148
+ walletId: this.walletMap[accountAddress].walletId,
1149
+ encryptedKeyShares,
1150
+ passwordEncrypted: Boolean(password) && password !== this.environmentId,
1124
1151
  signedSessionId
1125
1152
  });
1126
- data.keyShares.push({
1127
- backupLocation: core.BackupLocation.GOOGLE_DRIVE,
1128
- id: googleDriveKeyShareIds
1153
+ const hasGoogleDriveBackup = this.walletMap[accountAddress].clientKeySharesBackupInfo.backups[core.BackupLocation.GOOGLE_DRIVE].length > 0;
1154
+ if (hasGoogleDriveBackup) {
1155
+ const googleDriveKeyShareIds = await this.backupKeySharesToGoogleDrive({
1156
+ accountAddress,
1157
+ password,
1158
+ signedSessionId
1159
+ });
1160
+ data.keyShares.push({
1161
+ backupLocation: core.BackupLocation.GOOGLE_DRIVE,
1162
+ id: googleDriveKeyShareIds
1163
+ });
1164
+ }
1165
+ const updatedBackupInfo = getClientKeyShareBackupInfo({
1166
+ walletProperties: {
1167
+ derivationPath: this.walletMap[accountAddress].derivationPath,
1168
+ keyShares: data.keyShares,
1169
+ thresholdSignatureScheme: this.walletMap[accountAddress].thresholdSignatureScheme
1170
+ }
1129
1171
  });
1130
- }
1131
- const updatedBackupInfo = getClientKeyShareBackupInfo({
1132
- walletProperties: {
1133
- derivationPath: this.walletMap[accountAddress].derivationPath,
1134
- keyShares: data.keyShares,
1135
- thresholdSignatureScheme: this.walletMap[accountAddress].thresholdSignatureScheme
1172
+ this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
1173
+ clientKeySharesBackupInfo: updatedBackupInfo
1174
+ });
1175
+ await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
1176
+ return data;
1177
+ } catch (error) {
1178
+ this.logger.error('[DynamicWaasWalletClient]: Error in storeEncryptedBackupByWallet', error);
1179
+ if (error instanceof core.AxiosError) {
1180
+ core.handleAxiosError(error);
1136
1181
  }
1137
- });
1138
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
1139
- clientKeySharesBackupInfo: updatedBackupInfo
1140
- });
1141
- await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
1142
- return data;
1182
+ throw error;
1183
+ }
1143
1184
  }
1144
1185
  async storeEncryptedBackupByWalletWithRetry({ accountAddress, clientKeyShares, password, signedSessionId }) {
1145
1186
  await retryPromise(()=>this.storeEncryptedBackupByWallet({
@@ -1186,16 +1227,24 @@ class DynamicWalletClient {
1186
1227
  * @returns The Google OAuth Account ID
1187
1228
  * @throws Error if no Google OAuth account ID is found
1188
1229
  */ async getGoogleOauthAccountIdOrThrow(accountAddress) {
1189
- const user = await this.apiClient.getUser();
1190
- const oauthAccountId = getGoogleOAuthAccountId(user == null ? void 0 : user.verifiedCredentials);
1191
- if (!oauthAccountId) {
1192
- this.logger.error('No Google OAuth account ID found', {
1193
- user,
1194
- accountAddress
1195
- });
1196
- throw new Error('No Google OAuth account ID found');
1230
+ try {
1231
+ const user = await this.apiClient.getUser();
1232
+ const oauthAccountId = getGoogleOAuthAccountId(user == null ? void 0 : user.verifiedCredentials);
1233
+ if (!oauthAccountId) {
1234
+ this.logger.error('No Google OAuth account ID found', {
1235
+ user,
1236
+ accountAddress
1237
+ });
1238
+ throw new Error('No Google OAuth account ID found');
1239
+ }
1240
+ return oauthAccountId;
1241
+ } catch (error) {
1242
+ this.logger.error('[DynamicWaasWalletClient]: Error in getGoogleOauthAccountIdOrThrow', error);
1243
+ if (error instanceof core.AxiosError) {
1244
+ core.handleAxiosError(error);
1245
+ }
1246
+ throw error;
1197
1247
  }
1198
- return oauthAccountId;
1199
1248
  }
1200
1249
  /**
1201
1250
  * Helper function to determine keyshare recovery strategy for dynamic shares.
@@ -1225,34 +1274,39 @@ class DynamicWalletClient {
1225
1274
  };
1226
1275
  }
1227
1276
  async recoverEncryptedBackupByWallet({ accountAddress, password, walletOperation, signedSessionId, shareCount = undefined, storeRecoveredShares = true }) {
1228
- const wallet = this.walletMap[accountAddress];
1229
- this.logger.debug(`recoverEncryptedBackupByWallet wallet: ${walletOperation}`, wallet);
1230
- const { shares } = this.recoverStrategy({
1231
- clientKeyShareBackupInfo: wallet.clientKeySharesBackupInfo,
1232
- thresholdSignatureScheme: wallet.thresholdSignatureScheme,
1233
- walletOperation,
1234
- shareCount
1235
- });
1236
- const { dynamic: dynamicKeyShareIds } = shares;
1237
- const data = await this.apiClient.recoverEncryptedBackupByWallet({
1238
- walletId: wallet.walletId,
1239
- keyShareIds: dynamicKeyShareIds,
1240
- signedSessionId
1241
- });
1242
- const dynamicKeyShares = data.keyShares.filter((keyShare)=>keyShare.encryptedAccountCredential !== null && keyShare.backupLocation === core.BackupLocation.DYNAMIC);
1243
- const decryptedKeyShares = await Promise.all(dynamicKeyShares.map((keyShare)=>this.decryptKeyShare({
1244
- keyShare: keyShare.encryptedAccountCredential,
1245
- password: password != null ? password : this.environmentId
1246
- })));
1247
- if (storeRecoveredShares) {
1248
- await this.setClientKeySharesToLocalStorage({
1249
- accountAddress,
1250
- clientKeyShares: decryptedKeyShares,
1251
- overwriteOrMerge: 'merge'
1277
+ try {
1278
+ const wallet = this.walletMap[accountAddress];
1279
+ this.logger.debug(`recoverEncryptedBackupByWallet wallet: ${walletOperation}`, wallet);
1280
+ const { shares } = this.recoverStrategy({
1281
+ clientKeyShareBackupInfo: wallet.clientKeySharesBackupInfo,
1282
+ thresholdSignatureScheme: wallet.thresholdSignatureScheme,
1283
+ walletOperation,
1284
+ shareCount
1252
1285
  });
1253
- await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
1286
+ const { dynamic: dynamicKeyShareIds } = shares;
1287
+ const data = await this.apiClient.recoverEncryptedBackupByWallet({
1288
+ walletId: wallet.walletId,
1289
+ keyShareIds: dynamicKeyShareIds,
1290
+ signedSessionId
1291
+ });
1292
+ const dynamicKeyShares = data.keyShares.filter((keyShare)=>keyShare.encryptedAccountCredential !== null && keyShare.backupLocation === core.BackupLocation.DYNAMIC);
1293
+ const decryptedKeyShares = await Promise.all(dynamicKeyShares.map((keyShare)=>this.decryptKeyShare({
1294
+ keyShare: keyShare.encryptedAccountCredential,
1295
+ password: password != null ? password : this.environmentId
1296
+ })));
1297
+ if (storeRecoveredShares) {
1298
+ await this.setClientKeySharesToLocalStorage({
1299
+ accountAddress,
1300
+ clientKeyShares: decryptedKeyShares,
1301
+ overwriteOrMerge: 'merge'
1302
+ });
1303
+ await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
1304
+ }
1305
+ return decryptedKeyShares;
1306
+ } catch (error) {
1307
+ this.logger.error('[DynamicWaasWalletClient]: Error in recoverEncryptedBackupByWallet', error);
1308
+ throw error;
1254
1309
  }
1255
- return decryptedKeyShares;
1256
1310
  }
1257
1311
  async restoreWallets() {
1258
1312
  const wallets = await this.storage.getItem(this.storageKey);
@@ -1262,107 +1316,123 @@ class DynamicWalletClient {
1262
1316
  this.walletMap = JSON.parse(wallets);
1263
1317
  }
1264
1318
  async backupKeySharesToGoogleDrive({ accountAddress, password, signedSessionId }) {
1265
- await this.getWallet({
1266
- accountAddress,
1267
- walletOperation: core.WalletOperation.REACH_ALL_PARTIES,
1268
- password,
1269
- signedSessionId
1270
- });
1271
- const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
1272
- accountAddress
1273
- });
1274
- if (clientKeyShares.length === 0) {
1275
- throw new Error('No key shares found');
1276
- }
1277
- const encryptedKeyShares = await Promise.all(clientKeyShares.map((keyShare)=>this.encryptKeyShare({
1278
- keyShare,
1279
- password
1280
- })));
1281
- const oauthAccountId = await this.getGoogleOauthAccountIdOrThrow(accountAddress);
1282
- const accessToken = await this.apiClient.getAccessToken({
1283
- oauthAccountId
1284
- });
1285
- const thresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
1286
- const fileName = getClientKeyShareExportFileName({
1287
- thresholdSignatureScheme,
1288
- accountAddress
1289
- });
1290
- const backupData = createBackupData({
1291
- encryptedKeyShares,
1292
- accountAddress,
1293
- thresholdSignatureScheme
1294
- });
1295
- await uploadBackupToGoogleDrive({
1296
- accessToken,
1297
- fileName,
1298
- backupData,
1299
- accountAddress
1300
- });
1301
- const data = await this.apiClient.markKeySharesAsBackedUpGoogleDrive({
1302
- walletId: this.walletMap[accountAddress].walletId
1303
- });
1304
- await updateWalletMapWithBackupInfo({
1305
- data,
1306
- walletMap: this.walletMap,
1307
- accountAddress,
1308
- storage: this.storage,
1309
- storageKey: this.storageKey
1310
- });
1311
- }
1312
- async restoreBackupFromGoogleDrive({ accountAddress, password, signedSessionId }) {
1313
- await this.getWallet({
1314
- accountAddress,
1315
- signedSessionId
1316
- });
1317
- const oauthAccountId = await this.getGoogleOauthAccountIdOrThrow(accountAddress);
1318
- const accessToken = await this.apiClient.getAccessToken({
1319
- oauthAccountId
1320
- });
1321
- const thresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
1322
- const fileName = getClientKeyShareExportFileName({
1323
- thresholdSignatureScheme,
1324
- accountAddress
1325
- });
1326
- let backupData = null;
1327
1319
  try {
1328
- backupData = await retryPromise(()=>downloadFileFromGoogleDrive({
1329
- accessToken,
1330
- fileName
1331
- }));
1332
- } catch (error) {
1333
- this.logger.error('Failed to download backup from Google Drive', {
1320
+ await this.getWallet({
1321
+ accountAddress,
1322
+ walletOperation: core.WalletOperation.REACH_ALL_PARTIES,
1323
+ password,
1324
+ signedSessionId
1325
+ });
1326
+ const clientKeyShares = await this.getClientKeySharesFromLocalStorage({
1327
+ accountAddress
1328
+ });
1329
+ if (clientKeyShares.length === 0) {
1330
+ throw new Error('No key shares found');
1331
+ }
1332
+ const encryptedKeyShares = await Promise.all(clientKeyShares.map((keyShare)=>this.encryptKeyShare({
1333
+ keyShare,
1334
+ password
1335
+ })));
1336
+ const oauthAccountId = await this.getGoogleOauthAccountIdOrThrow(accountAddress);
1337
+ const accessToken = await this.apiClient.getAccessToken({
1338
+ oauthAccountId
1339
+ });
1340
+ const thresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
1341
+ const fileName = getClientKeyShareExportFileName({
1342
+ thresholdSignatureScheme,
1343
+ accountAddress
1344
+ });
1345
+ const backupData = createBackupData({
1346
+ encryptedKeyShares,
1334
1347
  accountAddress,
1348
+ thresholdSignatureScheme
1349
+ });
1350
+ await uploadBackupToGoogleDrive({
1351
+ accessToken,
1335
1352
  fileName,
1336
- error
1353
+ backupData,
1354
+ accountAddress
1337
1355
  });
1338
- throw new Error('Failed to restore backup from Google Drive');
1339
- }
1340
- if (!backupData) {
1341
- this.logger.error('No backup file found', {
1356
+ const data = await this.apiClient.markKeySharesAsBackedUpGoogleDrive({
1357
+ walletId: this.walletMap[accountAddress].walletId
1358
+ });
1359
+ await updateWalletMapWithBackupInfo({
1360
+ data,
1361
+ walletMap: this.walletMap,
1342
1362
  accountAddress,
1343
- fileName
1363
+ storage: this.storage,
1364
+ storageKey: this.storageKey
1344
1365
  });
1345
- throw new Error('No backup file found');
1366
+ } catch (error) {
1367
+ this.logger.error('[DynamicWaasWalletClient]: Error in backupKeySharesToGoogleDrive', error);
1368
+ if (error instanceof core.AxiosError) {
1369
+ core.handleAxiosError(error);
1370
+ }
1371
+ throw error;
1346
1372
  }
1347
- // Validate the backup data structure
1348
- if (!backupData.keyShares || !backupData.metadata) {
1349
- this.logger.error('Invalid backup format: missing keyShares or metadata', {
1373
+ }
1374
+ async restoreBackupFromGoogleDrive({ accountAddress, password, signedSessionId }) {
1375
+ try {
1376
+ await this.getWallet({
1377
+ accountAddress,
1378
+ signedSessionId
1379
+ });
1380
+ const oauthAccountId = await this.getGoogleOauthAccountIdOrThrow(accountAddress);
1381
+ const accessToken = await this.apiClient.getAccessToken({
1382
+ oauthAccountId
1383
+ });
1384
+ const thresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
1385
+ const fileName = getClientKeyShareExportFileName({
1386
+ thresholdSignatureScheme,
1387
+ accountAddress
1388
+ });
1389
+ let backupData = null;
1390
+ try {
1391
+ backupData = await retryPromise(()=>downloadFileFromGoogleDrive({
1392
+ accessToken,
1393
+ fileName
1394
+ }));
1395
+ } catch (error) {
1396
+ this.logger.error('Failed to download backup from Google Drive', {
1397
+ accountAddress,
1398
+ fileName,
1399
+ error
1400
+ });
1401
+ throw new Error('Failed to restore backup from Google Drive');
1402
+ }
1403
+ if (!backupData) {
1404
+ this.logger.error('No backup file found', {
1405
+ accountAddress,
1406
+ fileName
1407
+ });
1408
+ throw new Error('No backup file found');
1409
+ }
1410
+ // Validate the backup data structure
1411
+ if (!backupData.keyShares || !backupData.metadata) {
1412
+ this.logger.error('Invalid backup format: missing keyShares or metadata', {
1413
+ accountAddress,
1414
+ fileName
1415
+ });
1416
+ throw new Error('Invalid backup format: missing keyShares or metadata');
1417
+ }
1418
+ const { keyShares } = backupData;
1419
+ const decryptedKeyShares = await Promise.all(keyShares.map((keyShare)=>this.decryptKeyShare({
1420
+ keyShare,
1421
+ password
1422
+ })));
1423
+ await this.setClientKeySharesToLocalStorage({
1350
1424
  accountAddress,
1351
- fileName
1425
+ clientKeyShares: decryptedKeyShares,
1426
+ overwriteOrMerge: 'merge'
1352
1427
  });
1353
- throw new Error('Invalid backup format: missing keyShares or metadata');
1428
+ return decryptedKeyShares;
1429
+ } catch (error) {
1430
+ this.logger.error('[DynamicWaasWalletClient]: Error in restoreBackupFromGoogleDrive', error);
1431
+ if (error instanceof core.AxiosError) {
1432
+ core.handleAxiosError(error);
1433
+ }
1434
+ throw error;
1354
1435
  }
1355
- const { keyShares } = backupData;
1356
- const decryptedKeyShares = await Promise.all(keyShares.map((keyShare)=>this.decryptKeyShare({
1357
- keyShare,
1358
- password
1359
- })));
1360
- await this.setClientKeySharesToLocalStorage({
1361
- accountAddress,
1362
- clientKeyShares: decryptedKeyShares,
1363
- overwriteOrMerge: 'merge'
1364
- });
1365
- return decryptedKeyShares;
1366
1436
  }
1367
1437
  async exportClientKeyshares({ accountAddress, password, signedSessionId }) {
1368
1438
  await this.verifyPassword({
@@ -1533,107 +1603,131 @@ class DynamicWalletClient {
1533
1603
  return true;
1534
1604
  }
1535
1605
  async getWalletClientKeyShareBackupInfo({ accountAddress }) {
1536
- var _this_walletMap_accountAddress_clientKeySharesBackupInfo_backups_BackupLocation_DYNAMIC, _this_walletMap_accountAddress_clientKeySharesBackupInfo_backups, _this_walletMap_accountAddress_clientKeySharesBackupInfo, _this_walletMap_accountAddress, _user_verifiedCredentials;
1537
- // Return existing backup info if it exists
1538
- 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) {
1539
- return this.walletMap[accountAddress].clientKeySharesBackupInfo;
1606
+ try {
1607
+ var _this_walletMap_accountAddress_clientKeySharesBackupInfo_backups_BackupLocation_DYNAMIC, _this_walletMap_accountAddress_clientKeySharesBackupInfo_backups, _this_walletMap_accountAddress_clientKeySharesBackupInfo, _this_walletMap_accountAddress, _user_verifiedCredentials;
1608
+ // Return existing backup info if it exists
1609
+ 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) {
1610
+ return this.walletMap[accountAddress].clientKeySharesBackupInfo;
1611
+ }
1612
+ // Get backup info from server
1613
+ const user = await this.apiClient.getUser();
1614
+ const wallet = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.find((vc)=>vc.address.toLowerCase() === accountAddress.toLowerCase());
1615
+ return getClientKeyShareBackupInfo({
1616
+ walletProperties: wallet == null ? void 0 : wallet.walletProperties
1617
+ });
1618
+ } catch (error) {
1619
+ this.logger.error('[DynamicWaasWalletClient]: Error in getWalletClientKeyShareBackupInfo', error);
1620
+ if (error instanceof core.AxiosError) {
1621
+ core.handleAxiosError(error);
1622
+ }
1623
+ throw error;
1540
1624
  }
1541
- // Get backup info from server
1542
- const user = await this.apiClient.getUser();
1543
- const wallet = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.find((vc)=>vc.address.toLowerCase() === accountAddress.toLowerCase());
1544
- return getClientKeyShareBackupInfo({
1545
- walletProperties: wallet == null ? void 0 : wallet.walletProperties
1546
- });
1547
1625
  }
1548
1626
  async getWallet({ accountAddress, walletOperation = core.WalletOperation.NO_OPERATION, shareCount = undefined, password = undefined, signedSessionId }) {
1549
- var _user_verifiedCredentials;
1550
- const existingWalletCheck = await this.checkWalletFields({
1551
- accountAddress,
1552
- walletOperation,
1553
- shareCount
1554
- });
1555
- if (existingWalletCheck) {
1556
- this.logger.debug(`Wallet ${accountAddress} already exists`);
1557
- return this.walletMap[accountAddress];
1558
- }
1559
- // Fetch and restore wallet from server
1560
- const user = await this.apiClient.getUser();
1561
- const wallet = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.find((vc)=>vc.address.toLowerCase() === accountAddress.toLowerCase());
1562
- this.logger.debug('Restoring wallet', wallet);
1563
- const walletProperties = wallet.walletProperties;
1564
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
1565
- walletId: wallet.id,
1566
- chainName: wallet.chainName,
1567
- accountAddress,
1568
- thresholdSignatureScheme: walletProperties.thresholdSignatureScheme,
1569
- derivationPath: walletProperties.derivationPath,
1570
- clientKeySharesBackupInfo: getClientKeyShareBackupInfo({
1571
- walletProperties
1572
- })
1573
- });
1574
- if (walletOperation !== core.WalletOperation.NO_OPERATION && await this.requiresRestoreBackupSharesForOperation({
1575
- accountAddress,
1576
- walletOperation
1577
- })) {
1578
- // TODO(zfaizal2): throw error if signedSessionId is not provided after service deploy
1579
- const decryptedKeyShares = await this.recoverEncryptedBackupByWallet({
1627
+ try {
1628
+ var _user_verifiedCredentials;
1629
+ const existingWalletCheck = await this.checkWalletFields({
1580
1630
  accountAddress,
1581
- password: password != null ? password : this.environmentId,
1582
- walletOperation: walletOperation,
1583
- signedSessionId,
1631
+ walletOperation,
1584
1632
  shareCount
1585
1633
  });
1586
- const existingKeyShares = await this.getClientKeySharesFromLocalStorage({
1587
- accountAddress
1588
- });
1589
- await this.setClientKeySharesToLocalStorage({
1634
+ if (existingWalletCheck) {
1635
+ this.logger.debug(`Wallet ${accountAddress} already exists`);
1636
+ return this.walletMap[accountAddress];
1637
+ }
1638
+ // Fetch and restore wallet from server
1639
+ const user = await this.apiClient.getUser();
1640
+ const wallet = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.find((vc)=>vc.address.toLowerCase() === accountAddress.toLowerCase());
1641
+ this.logger.debug('Restoring wallet', wallet);
1642
+ const walletProperties = wallet.walletProperties;
1643
+ this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
1644
+ walletId: wallet.id,
1645
+ chainName: wallet.chainName,
1590
1646
  accountAddress,
1591
- clientKeyShares: mergeUniqueKeyShares(existingKeyShares, decryptedKeyShares)
1647
+ thresholdSignatureScheme: walletProperties.thresholdSignatureScheme,
1648
+ derivationPath: walletProperties.derivationPath,
1649
+ clientKeySharesBackupInfo: getClientKeyShareBackupInfo({
1650
+ walletProperties
1651
+ })
1592
1652
  });
1593
- this.logger.debug('Recovered backup', decryptedKeyShares);
1594
- }
1595
- const walletCount = Object.keys(this.walletMap).length;
1596
- if (walletCount === 0) {
1597
- throw new Error('No wallets found');
1598
- }
1599
- // Return the only wallet if there's just one
1600
- if (walletCount === 1) {
1601
- return Object.values(this.walletMap)[0];
1653
+ if (walletOperation !== core.WalletOperation.NO_OPERATION && await this.requiresRestoreBackupSharesForOperation({
1654
+ accountAddress,
1655
+ walletOperation
1656
+ })) {
1657
+ // TODO(zfaizal2): throw error if signedSessionId is not provided after service deploy
1658
+ const decryptedKeyShares = await this.recoverEncryptedBackupByWallet({
1659
+ accountAddress,
1660
+ password: password != null ? password : this.environmentId,
1661
+ walletOperation: walletOperation,
1662
+ signedSessionId,
1663
+ shareCount
1664
+ });
1665
+ const existingKeyShares = await this.getClientKeySharesFromLocalStorage({
1666
+ accountAddress
1667
+ });
1668
+ await this.setClientKeySharesToLocalStorage({
1669
+ accountAddress,
1670
+ clientKeyShares: mergeUniqueKeyShares(existingKeyShares, decryptedKeyShares)
1671
+ });
1672
+ this.logger.debug('Recovered backup', decryptedKeyShares);
1673
+ }
1674
+ const walletCount = Object.keys(this.walletMap).length;
1675
+ if (walletCount === 0) {
1676
+ throw new Error('No wallets found');
1677
+ }
1678
+ // Return the only wallet if there's just one
1679
+ if (walletCount === 1) {
1680
+ return Object.values(this.walletMap)[0];
1681
+ }
1682
+ return this.walletMap[accountAddress];
1683
+ } catch (error) {
1684
+ this.logger.error('[DynamicWaasWalletClient]: Error in getWallet', error);
1685
+ if (error instanceof core.AxiosError) {
1686
+ core.handleAxiosError(error);
1687
+ }
1688
+ throw error;
1602
1689
  }
1603
- return this.walletMap[accountAddress];
1604
1690
  }
1605
1691
  async getWallets() {
1606
- var _user_verifiedCredentials;
1607
- const user = await this.apiClient.getUser();
1608
- const waasWallets = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.filter((vc)=>vc.walletName === 'dynamicwaas');
1609
- const wallets = waasWallets.map((vc)=>{
1610
- var _this_walletMap_vc_address, _vc_walletProperties;
1611
- var _this_walletMap_vc_address_derivationPath;
1612
- return {
1613
- walletId: vc.id,
1614
- chainName: vc.chain,
1615
- accountAddress: vc.address,
1616
- clientKeySharesBackupInfo: getClientKeyShareBackupInfo({
1617
- walletProperties: vc.walletProperties || {}
1618
- }),
1619
- derivationPath: (_this_walletMap_vc_address_derivationPath = (_this_walletMap_vc_address = this.walletMap[vc.address]) == null ? void 0 : _this_walletMap_vc_address.derivationPath) != null ? _this_walletMap_vc_address_derivationPath : undefined,
1620
- thresholdSignatureScheme: (_vc_walletProperties = vc.walletProperties) == null ? void 0 : _vc_walletProperties.thresholdSignatureScheme
1621
- };
1622
- });
1623
- this.walletMap = wallets.reduce((acc, wallet)=>{
1624
- var _acc_accountAddress;
1625
- const accountAddress = wallet.accountAddress;
1626
- acc[wallet.accountAddress] = {
1627
- walletId: wallet.walletId,
1628
- chainName: wallet.chainName,
1629
- accountAddress: wallet.accountAddress,
1630
- clientKeySharesBackupInfo: wallet.clientKeySharesBackupInfo,
1631
- derivationPath: ((_acc_accountAddress = acc[accountAddress]) == null ? void 0 : _acc_accountAddress.derivationPath) || undefined,
1632
- thresholdSignatureScheme: wallet.thresholdSignatureScheme
1633
- };
1634
- return acc;
1635
- }, {});
1636
- return wallets;
1692
+ try {
1693
+ var _user_verifiedCredentials;
1694
+ const user = await this.apiClient.getUser();
1695
+ const waasWallets = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.filter((vc)=>vc.walletName === 'dynamicwaas');
1696
+ const wallets = waasWallets.map((vc)=>{
1697
+ var _this_walletMap_vc_address, _vc_walletProperties;
1698
+ var _this_walletMap_vc_address_derivationPath;
1699
+ return {
1700
+ walletId: vc.id,
1701
+ chainName: vc.chain,
1702
+ accountAddress: vc.address,
1703
+ clientKeySharesBackupInfo: getClientKeyShareBackupInfo({
1704
+ walletProperties: vc.walletProperties || {}
1705
+ }),
1706
+ derivationPath: (_this_walletMap_vc_address_derivationPath = (_this_walletMap_vc_address = this.walletMap[vc.address]) == null ? void 0 : _this_walletMap_vc_address.derivationPath) != null ? _this_walletMap_vc_address_derivationPath : undefined,
1707
+ thresholdSignatureScheme: (_vc_walletProperties = vc.walletProperties) == null ? void 0 : _vc_walletProperties.thresholdSignatureScheme
1708
+ };
1709
+ });
1710
+ this.walletMap = wallets.reduce((acc, wallet)=>{
1711
+ var _acc_accountAddress;
1712
+ const accountAddress = wallet.accountAddress;
1713
+ acc[wallet.accountAddress] = {
1714
+ walletId: wallet.walletId,
1715
+ chainName: wallet.chainName,
1716
+ accountAddress: wallet.accountAddress,
1717
+ clientKeySharesBackupInfo: wallet.clientKeySharesBackupInfo,
1718
+ derivationPath: ((_acc_accountAddress = acc[accountAddress]) == null ? void 0 : _acc_accountAddress.derivationPath) || undefined,
1719
+ thresholdSignatureScheme: wallet.thresholdSignatureScheme
1720
+ };
1721
+ return acc;
1722
+ }, {});
1723
+ return wallets;
1724
+ } catch (error) {
1725
+ this.logger.error('[DynamicWaasWalletClient]: Error in getWallets', error);
1726
+ if (error instanceof core.AxiosError) {
1727
+ core.handleAxiosError(error);
1728
+ }
1729
+ throw error;
1730
+ }
1637
1731
  }
1638
1732
  constructor({ environmentId, authToken, baseApiUrl, baseMPCRelayApiUrl, storageKey, debug }){
1639
1733
  this.initializePromise = null;