@dynamic-labs-wallet/browser 0.0.259 → 0.0.261

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
@@ -221,6 +221,11 @@ const ensureBase64Padding = (str)=>{
221
221
  ]);
222
222
  };
223
223
 
224
+ const INVALID_PASSWORD_ERROR = 'Decryption failed: Invalid password. Please check your password and try again.';
225
+ /**
226
+ * Check if an error is an OperationError from SubtleCrypto.decrypt,
227
+ * which indicates authentication failure (wrong password/derived key)
228
+ */ const isInvalidPasswordError = (error)=>error instanceof Error && error.name === 'OperationError';
224
229
  /**
225
230
  * Get the appropriate key derivation function based on the encryption config
226
231
  */ const getKey = async (params, encryptionConfig)=>{
@@ -309,10 +314,15 @@ const ensureBase64Padding = (str)=>{
309
314
  }, key, cipherBytes);
310
315
  return new TextDecoder().decode(decryptedData);
311
316
  } catch (retryError) {
312
- // If retry also fails, throw the original error with additional context
317
+ if (isInvalidPasswordError(retryError)) {
318
+ throw new Error(INVALID_PASSWORD_ERROR);
319
+ }
313
320
  throw new Error(`Decryption failed after retry with parallelism=1: ${retryError}`);
314
321
  }
315
322
  }
323
+ if (isInvalidPasswordError(error)) {
324
+ throw new Error(INVALID_PASSWORD_ERROR);
325
+ }
316
326
  throw new Error('Decryption failed: ' + error);
317
327
  }
318
328
  };
@@ -505,6 +515,12 @@ const ERROR_EXPORT_PRIVATE_KEY = '[DynamicWaasWalletClient]: Error exporting pri
505
515
  const ERROR_IMPORT_PRIVATE_KEY = '[DynamicWaasWalletClient]: Error importing private key';
506
516
  const ERROR_PUBLIC_KEY_MISMATCH = 'Mismatch between the public keys of the server and the ones provided';
507
517
 
518
+ /**
519
+ * Normalizes an address to lowercase for consistent map key lookups.
520
+ * This ensures that addresses with different casing (e.g., EIP-55 checksummed vs lowercase)
521
+ * resolve to the same wallet entry.
522
+ */ const normalizeAddress = (address)=>address.toLowerCase();
523
+
508
524
  // eslint-disable-next-line @nx/enforce-module-boundaries
509
525
  const isBrowser = ()=>typeof window !== 'undefined';
510
526
  /**
@@ -695,6 +711,16 @@ const downloadStringAsFile = ({ filename, content, mimeType = 'application/json'
695
711
  a.click();
696
712
  URL.revokeObjectURL(url);
697
713
  };
714
+ /**
715
+ * Checks if a wallet has cached encrypted shares in storage.
716
+ */ const hasEncryptedSharesCached = async ({ accountAddress, backupInfo, storage })=>{
717
+ if (!(backupInfo == null ? void 0 : backupInfo.passwordEncrypted)) {
718
+ return false;
719
+ }
720
+ const encryptedStorageKey = `${normalizeAddress(accountAddress)}${core.ENCRYPTED_SHARES_STORAGE_SUFFIX}`;
721
+ const encryptedData = await storage.getItem(encryptedStorageKey);
722
+ return !!encryptedData;
723
+ };
698
724
  /**
699
725
  * Checks if an error is a public key mismatch error that can be recovered
700
726
  * by re-fetching the client key share from backup.
@@ -1239,6 +1265,7 @@ const hasDelegatedBackup = (backupInfo)=>{
1239
1265
  * Get or create the heavy operation queue for a wallet.
1240
1266
  * Heavy operations (refresh/reshare/recover) run with concurrency=1.
1241
1267
  */ static getHeavyOpQueue(accountAddress) {
1268
+ accountAddress = normalizeAddress(accountAddress);
1242
1269
  if (!this.heavyOpQueues.has(accountAddress)) {
1243
1270
  const queue = new PQueue({
1244
1271
  concurrency: 1,
@@ -1258,6 +1285,7 @@ const hasDelegatedBackup = (backupInfo)=>{
1258
1285
  * Get or create the sign queue for a wallet.
1259
1286
  * Sign operations run with unlimited concurrency (they're read-only on key shares).
1260
1287
  */ static getSignQueue(accountAddress) {
1288
+ accountAddress = normalizeAddress(accountAddress);
1261
1289
  if (!this.signQueues.has(accountAddress)) {
1262
1290
  const queue = new PQueue({
1263
1291
  concurrency: Infinity,
@@ -1276,12 +1304,14 @@ const hasDelegatedBackup = (backupInfo)=>{
1276
1304
  /**
1277
1305
  * Check if wallet has heavy operations in progress
1278
1306
  */ static isHeavyOpInProgress(accountAddress) {
1307
+ accountAddress = normalizeAddress(accountAddress);
1279
1308
  const queue = this.heavyOpQueues.get(accountAddress);
1280
1309
  return queue ? queue.size > 0 || queue.pending > 0 : false;
1281
1310
  }
1282
1311
  /**
1283
1312
  * Check if wallet has operations in any queue (heavy or sign)
1284
1313
  */ static isWalletBusy(accountAddress) {
1314
+ accountAddress = normalizeAddress(accountAddress);
1285
1315
  const heavyQueue = this.heavyOpQueues.get(accountAddress);
1286
1316
  const signQueue = this.signQueues.get(accountAddress);
1287
1317
  const heavyBusy = heavyQueue ? heavyQueue.size > 0 || heavyQueue.pending > 0 : false;
@@ -1291,22 +1321,22 @@ const hasDelegatedBackup = (backupInfo)=>{
1291
1321
  /**
1292
1322
  * Check if recovery is in progress for a wallet
1293
1323
  */ static isRecoveryInProgress(accountAddress) {
1294
- return this.pendingRecoveryPromises.has(accountAddress);
1324
+ return this.pendingRecoveryPromises.has(normalizeAddress(accountAddress));
1295
1325
  }
1296
1326
  /**
1297
1327
  * Get existing pending recovery promise if one exists
1298
1328
  */ static getPendingRecoveryPromise(accountAddress) {
1299
- return this.pendingRecoveryPromises.get(accountAddress);
1329
+ return this.pendingRecoveryPromises.get(normalizeAddress(accountAddress));
1300
1330
  }
1301
1331
  /**
1302
1332
  * Track a pending recovery promise
1303
1333
  */ static setPendingRecoveryPromise(accountAddress, promise) {
1304
- this.pendingRecoveryPromises.set(accountAddress, promise);
1334
+ this.pendingRecoveryPromises.set(normalizeAddress(accountAddress), promise);
1305
1335
  }
1306
1336
  /**
1307
1337
  * Clear pending recovery promise for a wallet
1308
1338
  */ static clearPendingRecoveryPromise(accountAddress) {
1309
- this.pendingRecoveryPromises.delete(accountAddress);
1339
+ this.pendingRecoveryPromises.delete(normalizeAddress(accountAddress));
1310
1340
  }
1311
1341
  /**
1312
1342
  * Queue a heavy operation with type validation.
@@ -1318,6 +1348,7 @@ const hasDelegatedBackup = (backupInfo)=>{
1318
1348
  * @param callback - The operation to execute
1319
1349
  * @throws Error if operation is not a valid heavy queue operation
1320
1350
  */ static async queueHeavyOperation(accountAddress, operation, callback) {
1351
+ accountAddress = normalizeAddress(accountAddress);
1321
1352
  // Runtime validation to catch any type assertion bypasses
1322
1353
  if (!isHeavyQueueOperation(operation)) {
1323
1354
  throw new Error(`Invalid heavy queue operation: ${operation}. Must be REFRESH, RESHARE, or RECOVER.`);
@@ -1348,6 +1379,7 @@ const hasDelegatedBackup = (backupInfo)=>{
1348
1379
  * @throws Error if operation is not a valid sign queue operation
1349
1380
  * @returns Promise resolving to the sign result
1350
1381
  */ static async queueSignOperation(accountAddress, operation, callback) {
1382
+ accountAddress = normalizeAddress(accountAddress);
1351
1383
  // Runtime validation to catch any type assertion bypasses
1352
1384
  if (!isSignQueueOperation(operation)) {
1353
1385
  throw new Error(`Invalid sign queue operation: ${operation}. Must be SIGN_MESSAGE or SIGN_TRANSACTION.`);
@@ -1383,6 +1415,7 @@ const hasDelegatedBackup = (backupInfo)=>{
1383
1415
  * @throws Error if operation is not a valid recover queue operation
1384
1416
  * @returns Promise resolving to the recovery result
1385
1417
  */ static async queueRecoverOperation(accountAddress, operation, callback) {
1418
+ accountAddress = normalizeAddress(accountAddress);
1386
1419
  // Runtime validation to catch any type assertion bypasses
1387
1420
  if (!isRecoverQueueOperation(operation)) {
1388
1421
  throw new Error(`Invalid recover queue operation: ${operation}. Must be RECOVER.`);
@@ -1667,6 +1700,19 @@ class DynamicWalletClient {
1667
1700
  */ static resetStaticState() {
1668
1701
  WalletQueueManager.resetForTesting();
1669
1702
  }
1703
+ /**
1704
+ * Get wallet properties from the wallet map using normalized address.
1705
+ * Normalizes the address to lowercase for consistent lookups regardless of input casing.
1706
+ */ getWalletFromMap(accountAddress) {
1707
+ return this.walletMap[normalizeAddress(accountAddress)];
1708
+ }
1709
+ /**
1710
+ * Update wallet properties in the wallet map using normalized address.
1711
+ * Normalizes the address to lowercase for consistent storage regardless of input casing.
1712
+ */ updateWalletMap(accountAddress, updates) {
1713
+ const normalizedAddr = normalizeAddress(accountAddress);
1714
+ this.walletMap[normalizedAddr] = _extends({}, this.walletMap[normalizedAddr], updates);
1715
+ }
1670
1716
  getAuthMode() {
1671
1717
  return this.authMode;
1672
1718
  }
@@ -2365,7 +2411,7 @@ class DynamicWalletClient {
2365
2411
  * from walletMap, with fallback to deriving it from derivationPath.
2366
2412
  */ getBitcoinConfigForChain(chainName, accountAddress) {
2367
2413
  if (chainName !== 'BTC') return undefined;
2368
- const walletProperties = this.walletMap[accountAddress];
2414
+ const walletProperties = this.getWalletFromMap(accountAddress);
2369
2415
  let addressType = walletProperties == null ? void 0 : walletProperties.addressType;
2370
2416
  // Fallback: derive addressType from derivationPath if not explicitly set
2371
2417
  if (!addressType && (walletProperties == null ? void 0 : walletProperties.derivationPath)) {
@@ -2504,9 +2550,11 @@ class DynamicWalletClient {
2504
2550
  * }>} Object containing new and existing client keygen results, IDs and shares
2505
2551
  * @todo Support higher to lower reshare strategies
2506
2552
  */ async reshareStrategy({ chainName, wallet, accountAddress, oldThresholdSignatureScheme, newThresholdSignatureScheme }) {
2553
+ const bitcoinConfig = this.getBitcoinConfigForChain(chainName, accountAddress);
2507
2554
  const mpcSigner = getMPCSigner({
2508
2555
  chainName,
2509
- baseRelayUrl: this.baseMPCRelayApiUrl
2556
+ baseRelayUrl: this.baseMPCRelayApiUrl,
2557
+ bitcoinConfig
2510
2558
  });
2511
2559
  // Determine share counts based on threshold signature schemes
2512
2560
  const { newClientShareCount, existingClientShareCount } = core.getReshareConfig({
@@ -2524,7 +2572,8 @@ class DynamicWalletClient {
2524
2572
  })).slice(0, existingClientShareCount);
2525
2573
  const existingClientKeygenIds = await Promise.all(existingClientKeyShares.map(async (keyShare)=>await this.getExportId({
2526
2574
  chainName,
2527
- clientKeyShare: keyShare
2575
+ clientKeyShare: keyShare,
2576
+ bitcoinConfig
2528
2577
  })));
2529
2578
  return {
2530
2579
  newClientInitKeygenResults,
@@ -2582,6 +2631,7 @@ class DynamicWalletClient {
2582
2631
  ...newClientKeygenIds,
2583
2632
  ...existingClientKeygenIds
2584
2633
  ];
2634
+ const bitcoinConfig = this.getBitcoinConfigForChain(chainName, accountAddress);
2585
2635
  // Server to create the room and complete the server reshare logics
2586
2636
  const data = await this.apiClient.reshare({
2587
2637
  walletId: wallet.walletId,
@@ -2602,7 +2652,6 @@ class DynamicWalletClient {
2602
2652
  ...serverKeygenIds,
2603
2653
  ...newServerKeygenIds
2604
2654
  ];
2605
- const bitcoinConfig = this.getBitcoinConfigForChain(chainName, accountAddress);
2606
2655
  const mpcSigner = getMPCSigner({
2607
2656
  chainName,
2608
2657
  baseRelayUrl: this.baseMPCRelayApiUrl,
@@ -2681,7 +2730,7 @@ class DynamicWalletClient {
2681
2730
  allShares: allClientShares
2682
2731
  });
2683
2732
  }
2684
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
2733
+ this.updateWalletMap(accountAddress, {
2685
2734
  thresholdSignatureScheme: newThresholdSignatureScheme
2686
2735
  });
2687
2736
  // store client key shares to storage (localStorage or secureStorage)
@@ -2710,7 +2759,7 @@ class DynamicWalletClient {
2710
2759
  }
2711
2760
  });
2712
2761
  // reset user wallet when reshare fails, this would allow the client to recover wallets from an active state
2713
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
2762
+ this.updateWalletMap(accountAddress, {
2714
2763
  thresholdSignatureScheme: oldThresholdSignatureScheme
2715
2764
  });
2716
2765
  await this.setClientKeySharesToStorage({
@@ -2723,7 +2772,6 @@ class DynamicWalletClient {
2723
2772
  }
2724
2773
  async performDelegationOperation({ accountAddress, password, signedSessionId, mfaToken, newThresholdSignatureScheme, revokeDelegation = false, operationName }) {
2725
2774
  try {
2726
- var _this_walletMap_accountAddress;
2727
2775
  const delegateToProjectEnvironment = this.featureFlags && this.featureFlags[core.FEATURE_FLAGS.ENABLE_DELEGATED_KEY_SHARES_FLAG] === true;
2728
2776
  if (!delegateToProjectEnvironment) {
2729
2777
  throw new Error('Delegation is not allowed for this project environment');
@@ -2737,11 +2785,12 @@ class DynamicWalletClient {
2737
2785
  if (wallet.chainName === 'SUI') {
2738
2786
  throw new Error('Delegation is not allowed for SUI');
2739
2787
  }
2740
- const currentThresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
2788
+ const walletData = this.getWalletFromMap(accountAddress);
2789
+ const currentThresholdSignatureScheme = walletData.thresholdSignatureScheme;
2741
2790
  // Get active cloud providers to maintain existing backups
2742
- const activeProviders = getActiveCloudProviders((_this_walletMap_accountAddress = this.walletMap[accountAddress]) == null ? void 0 : _this_walletMap_accountAddress.clientKeySharesBackupInfo);
2791
+ const activeProviders = getActiveCloudProviders(walletData == null ? void 0 : walletData.clientKeySharesBackupInfo);
2743
2792
  await this.reshare({
2744
- chainName: this.walletMap[accountAddress].chainName,
2793
+ chainName: walletData.chainName,
2745
2794
  accountAddress,
2746
2795
  oldThresholdSignatureScheme: currentThresholdSignatureScheme,
2747
2796
  newThresholdSignatureScheme,
@@ -2772,7 +2821,7 @@ class DynamicWalletClient {
2772
2821
  newThresholdSignatureScheme: core.ThresholdSignatureScheme.TWO_OF_THREE,
2773
2822
  operationName: 'delegateKeyShares'
2774
2823
  });
2775
- const backupInfo = this.walletMap[accountAddress].clientKeySharesBackupInfo;
2824
+ const backupInfo = this.getWalletFromMap(accountAddress).clientKeySharesBackupInfo;
2776
2825
  const delegatedKeyShares = backupInfo.backups[core.BackupLocation.DELEGATED] || [];
2777
2826
  return delegatedKeyShares;
2778
2827
  }
@@ -2971,6 +3020,7 @@ class DynamicWalletClient {
2971
3020
  /**
2972
3021
  * helper function to store encrypted backup by wallet from iframe local storage
2973
3022
  */ async getClientKeySharesFromLocalStorage({ accountAddress }) {
3023
+ accountAddress = normalizeAddress(accountAddress);
2974
3024
  const walletObject = await this.storage.getItem(accountAddress);
2975
3025
  if (!walletObject) {
2976
3026
  this.logger.debug(`[DynamicWaasWalletClient] No item found in iframe local storage for accountAddress: ${accountAddress}`);
@@ -2999,6 +3049,7 @@ class DynamicWalletClient {
2999
3049
  * Helper function to get client key shares from storage.
3000
3050
  * Uses secureStorage when available (mobile), otherwise falls back to localStorage (browser).
3001
3051
  */ async getClientKeySharesFromStorage({ accountAddress }) {
3052
+ accountAddress = normalizeAddress(accountAddress);
3002
3053
  // Use secure storage if available (mobile)
3003
3054
  if (this.secureStorage) {
3004
3055
  try {
@@ -3031,7 +3082,7 @@ class DynamicWalletClient {
3031
3082
  * @param derivationPath - Optional derivation path (will be computed from chainConfig if not provided)
3032
3083
  * @param additionalProps - Any chain-specific additional properties to merge
3033
3084
  */ initializeWalletMapEntry({ accountAddress, walletId, chainName, thresholdSignatureScheme, derivationPath, additionalProps = {} }) {
3034
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
3085
+ this.updateWalletMap(accountAddress, _extends({
3035
3086
  accountAddress,
3036
3087
  walletId,
3037
3088
  chainName,
@@ -3040,7 +3091,7 @@ class DynamicWalletClient {
3040
3091
  derivationPath
3041
3092
  } : {}, {
3042
3093
  clientKeySharesBackupInfo: getClientKeyShareBackupInfo()
3043
- }, additionalProps);
3094
+ }, additionalProps));
3044
3095
  this.logger.debug('walletMap initialized for wallet', {
3045
3096
  context: {
3046
3097
  accountAddress,
@@ -3054,6 +3105,7 @@ class DynamicWalletClient {
3054
3105
  * Helper function to store client key shares in storage.
3055
3106
  * Uses secureStorage when available (mobile), otherwise falls back to localStorage (browser).
3056
3107
  */ async setClientKeySharesToLocalStorage({ accountAddress, clientKeyShares, overwriteOrMerge = 'merge' }) {
3108
+ accountAddress = normalizeAddress(accountAddress);
3057
3109
  const stringifiedClientKeyShares = JSON.stringify({
3058
3110
  clientKeyShares: overwriteOrMerge === 'overwrite' ? clientKeyShares : mergeUniqueKeyShares(await this.getClientKeySharesFromLocalStorage({
3059
3111
  accountAddress
@@ -3065,6 +3117,7 @@ class DynamicWalletClient {
3065
3117
  * Helper function to store client key shares in storage.
3066
3118
  * Uses secureStorage when available (mobile), otherwise falls back to localStorage (browser).
3067
3119
  */ async setClientKeySharesToStorage({ accountAddress, clientKeyShares, overwriteOrMerge = 'merge' }) {
3120
+ accountAddress = normalizeAddress(accountAddress);
3068
3121
  // Use secure storage if available (mobile)
3069
3122
  if (this.secureStorage) {
3070
3123
  try {
@@ -3110,8 +3163,8 @@ class DynamicWalletClient {
3110
3163
  async backupSharesWithDistribution({ accountAddress, password, signedSessionId, distribution, preserveDelegatedLocation = false }) {
3111
3164
  const dynamicRequestId = uuid.v4();
3112
3165
  try {
3113
- var _this_walletMap_accountAddress;
3114
- if (!((_this_walletMap_accountAddress = this.walletMap[accountAddress]) == null ? void 0 : _this_walletMap_accountAddress.walletId)) {
3166
+ const walletData = this.getWalletFromMap(accountAddress);
3167
+ if (!(walletData == null ? void 0 : walletData.walletId)) {
3115
3168
  const error = new Error(`WalletId not found for accountAddress ${accountAddress}`);
3116
3169
  logError({
3117
3170
  message: 'Error in backupSharesWithDistribution, wallet or walletId not found from the wallet map',
@@ -3131,7 +3184,7 @@ class DynamicWalletClient {
3131
3184
  password
3132
3185
  })));
3133
3186
  const data = await this.apiClient.storeEncryptedBackupByWallet({
3134
- walletId: this.walletMap[accountAddress].walletId,
3187
+ walletId: walletData.walletId,
3135
3188
  encryptedKeyShares: encryptedDynamicShares,
3136
3189
  passwordEncrypted: isPasswordEncrypted,
3137
3190
  encryptionVersion: ENCRYPTION_VERSION_CURRENT,
@@ -3177,7 +3230,7 @@ class DynamicWalletClient {
3177
3230
  var _publicKey_key_keyId;
3178
3231
  const encryptedDelegatedKeyShareEnvelope = await encryptDelegatedKeyShare(JSON.stringify(distribution.delegatedShare), publicKey == null ? void 0 : (_publicKey_key1 = publicKey.key) == null ? void 0 : _publicKey_key1.publicKeyPemB64, (_publicKey_key_keyId = publicKey == null ? void 0 : (_publicKey_key2 = publicKey.key) == null ? void 0 : _publicKey_key2.keyId) != null ? _publicKey_key_keyId : publicKey == null ? void 0 : publicKey.keyId);
3179
3232
  const { status } = await this.apiClient.publishDelegatedKeyShare({
3180
- walletId: this.walletMap[accountAddress].walletId,
3233
+ walletId: walletData.walletId,
3181
3234
  encryptedKeyShare: encryptedDelegatedKeyShareEnvelope,
3182
3235
  signedSessionId,
3183
3236
  requiresSignedSessionId: this.requiresSignedSessionId(),
@@ -3199,23 +3252,23 @@ class DynamicWalletClient {
3199
3252
  });
3200
3253
  }
3201
3254
  const backupData = await this.apiClient.markKeySharesAsBackedUp({
3202
- walletId: this.walletMap[accountAddress].walletId,
3255
+ walletId: walletData.walletId,
3203
3256
  locations,
3204
3257
  dynamicRequestId
3205
3258
  });
3206
3259
  const updatedBackupInfo = getClientKeyShareBackupInfo({
3207
3260
  walletProperties: {
3208
- derivationPath: this.walletMap[accountAddress].derivationPath,
3261
+ derivationPath: walletData.derivationPath,
3209
3262
  keyShares: backupData.locationsWithKeyShares.map((ks)=>({
3210
3263
  id: ks.keyShareId,
3211
3264
  backupLocation: ks.location,
3212
3265
  externalKeyShareId: ks.externalKeyShareId,
3213
3266
  passwordEncrypted: isPasswordEncrypted
3214
3267
  })),
3215
- thresholdSignatureScheme: this.walletMap[accountAddress].thresholdSignatureScheme
3268
+ thresholdSignatureScheme: walletData.thresholdSignatureScheme
3216
3269
  }
3217
3270
  });
3218
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
3271
+ this.updateWalletMap(accountAddress, {
3219
3272
  clientKeySharesBackupInfo: updatedBackupInfo
3220
3273
  });
3221
3274
  await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
@@ -3263,16 +3316,17 @@ class DynamicWalletClient {
3263
3316
  * @param params.backupToGoogleDrive - Whether to backup to Google Drive (defaults to false)
3264
3317
  * @returns Promise with backup metadata including share locations and IDs
3265
3318
  */ async storeEncryptedBackupByWallet({ accountAddress, clientKeyShares = undefined, password = undefined, signedSessionId, cloudProviders = [], delegatedKeyshare = undefined }) {
3266
- var _this_walletMap_accountAddress, _this_walletMap_accountAddress1;
3319
+ var _this_getWalletFromMap;
3267
3320
  const keySharesToBackup = clientKeyShares != null ? clientKeyShares : await this.getClientKeySharesFromStorage({
3268
3321
  accountAddress
3269
3322
  });
3270
3323
  // Check if we should backup to cloud providers (either requested or already exists)
3271
- const activeCloudProviders = getActiveCloudProviders((_this_walletMap_accountAddress = this.walletMap[accountAddress]) == null ? void 0 : _this_walletMap_accountAddress.clientKeySharesBackupInfo);
3324
+ const walletBackupInfo = (_this_getWalletFromMap = this.getWalletFromMap(accountAddress)) == null ? void 0 : _this_getWalletFromMap.clientKeySharesBackupInfo;
3325
+ const activeCloudProviders = getActiveCloudProviders(walletBackupInfo);
3272
3326
  const shouldBackupToCloudProviders = cloudProviders.length > 0 || activeCloudProviders.length > 0;
3273
3327
  // Use requested providers, or fall back to existing active providers
3274
3328
  const providersToBackup = cloudProviders.length > 0 ? cloudProviders : activeCloudProviders;
3275
- const hasExistingDelegation = hasDelegatedBackup((_this_walletMap_accountAddress1 = this.walletMap[accountAddress]) == null ? void 0 : _this_walletMap_accountAddress1.clientKeySharesBackupInfo);
3329
+ const hasExistingDelegation = hasDelegatedBackup(walletBackupInfo);
3276
3330
  let distribution;
3277
3331
  let preserveDelegatedLocation = false;
3278
3332
  // Generic distribution logic - works with any cloud providers
@@ -3436,7 +3490,7 @@ class DynamicWalletClient {
3436
3490
  }
3437
3491
  async internalRecoverEncryptedBackupByWallet({ accountAddress, password, walletOperation, signedSessionId, shareCount = undefined, storeRecoveredShares = true, mfaToken }) {
3438
3492
  try {
3439
- const wallet = this.walletMap[accountAddress];
3493
+ const wallet = this.getWalletFromMap(accountAddress);
3440
3494
  this.logger.debug(`recoverEncryptedBackupByWallet wallet: ${walletOperation}`, wallet);
3441
3495
  const { shares } = this.recoverStrategy({
3442
3496
  clientKeyShareBackupInfo: wallet.clientKeySharesBackupInfo,
@@ -3484,7 +3538,12 @@ class DynamicWalletClient {
3484
3538
  if (!wallets) {
3485
3539
  return;
3486
3540
  }
3487
- this.walletMap = JSON.parse(wallets);
3541
+ const parsedWallets = JSON.parse(wallets);
3542
+ this.walletMap = Object.keys(parsedWallets).reduce((acc, key)=>{
3543
+ const normalizedKey = normalizeAddress(key);
3544
+ acc[normalizedKey] = parsedWallets[key];
3545
+ return acc;
3546
+ }, {});
3488
3547
  }
3489
3548
  /**
3490
3549
  * Internal helper method that handles the complete flow for ensuring wallet key shares are backed up to a cloud provider.
@@ -3498,11 +3557,12 @@ class DynamicWalletClient {
3498
3557
  password,
3499
3558
  signedSessionId
3500
3559
  });
3501
- const currentThresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
3560
+ const walletData = this.getWalletFromMap(accountAddress);
3561
+ const currentThresholdSignatureScheme = walletData.thresholdSignatureScheme;
3502
3562
  if (currentThresholdSignatureScheme === core.ThresholdSignatureScheme.TWO_OF_TWO) {
3503
3563
  // Reshare to 2-of-3, which will automatically handle the backup distribution
3504
3564
  await this.reshare({
3505
- chainName: this.walletMap[accountAddress].chainName,
3565
+ chainName: walletData.chainName,
3506
3566
  accountAddress,
3507
3567
  oldThresholdSignatureScheme: currentThresholdSignatureScheme,
3508
3568
  newThresholdSignatureScheme: core.ThresholdSignatureScheme.TWO_OF_THREE,
@@ -3612,7 +3672,7 @@ class DynamicWalletClient {
3612
3672
  const accessToken = await this.apiClient.getAccessToken({
3613
3673
  oauthAccountId
3614
3674
  });
3615
- const thresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
3675
+ const thresholdSignatureScheme = this.getWalletFromMap(accountAddress).thresholdSignatureScheme;
3616
3676
  const fileName = getClientKeyShareExportFileName({
3617
3677
  thresholdSignatureScheme,
3618
3678
  accountAddress,
@@ -3652,7 +3712,7 @@ class DynamicWalletClient {
3652
3712
  if (encryptedKeyShares.length === 0) {
3653
3713
  throw new Error('No key shares found');
3654
3714
  }
3655
- const thresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
3715
+ const thresholdSignatureScheme = this.getWalletFromMap(accountAddress).thresholdSignatureScheme;
3656
3716
  const backupData = createBackupData({
3657
3717
  encryptedKeyShares,
3658
3718
  accountAddress,
@@ -3681,7 +3741,7 @@ class DynamicWalletClient {
3681
3741
  const accessToken = await this.apiClient.getAccessToken({
3682
3742
  oauthAccountId
3683
3743
  });
3684
- const thresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
3744
+ const thresholdSignatureScheme = this.getWalletFromMap(accountAddress).thresholdSignatureScheme;
3685
3745
  const backupFileName = getClientKeyShareExportFileName({
3686
3746
  thresholdSignatureScheme,
3687
3747
  accountAddress,
@@ -3757,6 +3817,7 @@ class DynamicWalletClient {
3757
3817
  }
3758
3818
  }
3759
3819
  async exportClientKeyshares({ accountAddress, password, signedSessionId }) {
3820
+ var _this_getWalletFromMap;
3760
3821
  await this.verifyPassword({
3761
3822
  accountAddress,
3762
3823
  password,
@@ -3768,7 +3829,7 @@ class DynamicWalletClient {
3768
3829
  }
3769
3830
  // Ensure client key shares exist before export
3770
3831
  const clientKeyShares = await this.ensureClientShare(accountAddress);
3771
- const derivationPath = this.walletMap[accountAddress].derivationPath;
3832
+ const derivationPath = (_this_getWalletFromMap = this.getWalletFromMap(accountAddress)) == null ? void 0 : _this_getWalletFromMap.derivationPath;
3772
3833
  const text = JSON.stringify({
3773
3834
  keyShares: clientKeyShares,
3774
3835
  derivationPath
@@ -3801,7 +3862,7 @@ class DynamicWalletClient {
3801
3862
  let thresholdSignatureSchemeCheck = false;
3802
3863
  let derivationPathCheck = false;
3803
3864
  // check if wallet exists
3804
- const existingWallet = this.walletMap[accountAddress];
3865
+ const existingWallet = this.getWalletFromMap(accountAddress);
3805
3866
  if (existingWallet) {
3806
3867
  walletCheck = true;
3807
3868
  }
@@ -3839,7 +3900,7 @@ class DynamicWalletClient {
3839
3900
  * and decryption without storing the restored key shares. If unsuccessful, it throws an error.
3840
3901
  */ async verifyPassword({ accountAddress, password = undefined, walletOperation = core.WalletOperation.NO_OPERATION, signedSessionId }) {
3841
3902
  // Only load wallet if it's not already loaded (to avoid double eager loading)
3842
- if (!this.walletMap[accountAddress]) {
3903
+ if (!this.getWalletFromMap(accountAddress)) {
3843
3904
  await this.getWallet({
3844
3905
  accountAddress,
3845
3906
  walletOperation,
@@ -3898,7 +3959,7 @@ class DynamicWalletClient {
3898
3959
  });
3899
3960
  const { requiredShareCount } = this.recoverStrategy({
3900
3961
  clientKeyShareBackupInfo: clientKeySharesBackupInfo,
3901
- thresholdSignatureScheme: this.walletMap[accountAddress].thresholdSignatureScheme,
3962
+ thresholdSignatureScheme: this.getWalletFromMap(accountAddress).thresholdSignatureScheme,
3902
3963
  walletOperation
3903
3964
  });
3904
3965
  if (clientKeyShares.length >= requiredShareCount) {
@@ -3909,10 +3970,11 @@ class DynamicWalletClient {
3909
3970
  async getWalletClientKeyShareBackupInfo({ accountAddress }) {
3910
3971
  const dynamicRequestId = uuid.v4();
3911
3972
  try {
3912
- var _this_walletMap_accountAddress_clientKeySharesBackupInfo_backups_BackupLocation_DYNAMIC, _this_walletMap_accountAddress_clientKeySharesBackupInfo_backups, _this_walletMap_accountAddress_clientKeySharesBackupInfo, _this_walletMap_accountAddress, _user_verifiedCredentials;
3973
+ var _this_getWalletFromMap, _walletBackupInfo_backups_BackupLocation_DYNAMIC, _walletBackupInfo_backups, _user_verifiedCredentials;
3913
3974
  // Return existing backup info if it exists
3914
- 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) {
3915
- return this.walletMap[accountAddress].clientKeySharesBackupInfo;
3975
+ const walletBackupInfo = (_this_getWalletFromMap = this.getWalletFromMap(accountAddress)) == null ? void 0 : _this_getWalletFromMap.clientKeySharesBackupInfo;
3976
+ if (walletBackupInfo && ((_walletBackupInfo_backups = walletBackupInfo.backups) == null ? void 0 : (_walletBackupInfo_backups_BackupLocation_DYNAMIC = _walletBackupInfo_backups[core.BackupLocation.DYNAMIC]) == null ? void 0 : _walletBackupInfo_backups_BackupLocation_DYNAMIC.length) > 0) {
3977
+ return walletBackupInfo;
3916
3978
  }
3917
3979
  // Get backup info from server
3918
3980
  const user = await this.apiClient.getUser(dynamicRequestId);
@@ -3943,30 +4005,36 @@ class DynamicWalletClient {
3943
4005
  });
3944
4006
  if (existingWalletCheck) {
3945
4007
  this.logger.debug(`[DynamicWaasWalletClient] Wallet ${accountAddress} already exists`);
3946
- return this.walletMap[accountAddress];
4008
+ const wallet = this.getWalletFromMap(accountAddress);
4009
+ if (!wallet) {
4010
+ throw new Error(`Wallet not found for address: ${accountAddress}`);
4011
+ }
4012
+ return wallet;
3947
4013
  }
3948
- // Fetch and restore wallet from server
4014
+ // Fetch and restore all waas wallets from server
3949
4015
  const user = await this.apiClient.getUser(dynamicRequestId);
3950
- const wallet = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.find((vc)=>vc.address.toLowerCase() === accountAddress.toLowerCase());
3951
- this.logger.debug('[DynamicWaasWalletClient] Restoring wallet', wallet);
3952
- const walletProperties = wallet.walletProperties;
3953
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
3954
- walletId: wallet.id,
3955
- chainName: core.verifiedCredentialNameToChainEnum[wallet.chain],
3956
- accountAddress,
3957
- thresholdSignatureScheme: walletProperties.thresholdSignatureScheme,
3958
- derivationPath: walletProperties.derivationPath,
3959
- clientKeySharesBackupInfo: getClientKeyShareBackupInfo({
3960
- walletProperties
3961
- }),
3962
- addressType: walletProperties.addressType
3963
- });
4016
+ const waasWallets = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.filter((vc)=>vc.walletName === 'dynamicwaas');
4017
+ for (const vc of waasWallets != null ? waasWallets : []){
4018
+ const addr = vc.address;
4019
+ const props = vc.walletProperties;
4020
+ this.updateWalletMap(addr, {
4021
+ walletId: vc.id,
4022
+ chainName: core.verifiedCredentialNameToChainEnum[vc.chain],
4023
+ accountAddress: addr,
4024
+ thresholdSignatureScheme: props == null ? void 0 : props.thresholdSignatureScheme,
4025
+ derivationPath: props == null ? void 0 : props.derivationPath,
4026
+ clientKeySharesBackupInfo: getClientKeyShareBackupInfo({
4027
+ walletProperties: props
4028
+ }),
4029
+ addressType: props == null ? void 0 : props.addressType
4030
+ });
4031
+ }
3964
4032
  if (walletOperation !== core.WalletOperation.NO_OPERATION && await this.requiresRestoreBackupSharesForOperation({
3965
4033
  accountAddress,
3966
4034
  walletOperation
3967
4035
  })) {
3968
4036
  var _walletData_clientKeySharesBackupInfo;
3969
- const walletData = this.walletMap[accountAddress];
4037
+ const walletData = this.getWalletFromMap(accountAddress);
3970
4038
  var _walletData_clientKeySharesBackupInfo_passwordEncrypted;
3971
4039
  const isPasswordEncrypted = (_walletData_clientKeySharesBackupInfo_passwordEncrypted = (_walletData_clientKeySharesBackupInfo = walletData.clientKeySharesBackupInfo) == null ? void 0 : _walletData_clientKeySharesBackupInfo.passwordEncrypted) != null ? _walletData_clientKeySharesBackupInfo_passwordEncrypted : false;
3972
4040
  // Password-encrypted wallet without password - fetch and cache for eager loading
@@ -3984,14 +4052,19 @@ class DynamicWalletClient {
3984
4052
  requiresSignedSessionId: this.requiresSignedSessionId()
3985
4053
  });
3986
4054
  // Cache encrypted shares for later decryption by unlockWallet
3987
- const encryptedStorageKey = `${accountAddress}${core.ENCRYPTED_SHARES_STORAGE_SUFFIX}`;
4055
+ const encryptedStorageKey = `${normalizeAddress(accountAddress)}${core.ENCRYPTED_SHARES_STORAGE_SUFFIX}`;
3988
4056
  await this.storage.setItem(encryptedStorageKey, JSON.stringify(data));
3989
4057
  // Update wallet state to locked
3990
- this.walletMap[accountAddress] = _extends({}, walletData, {
4058
+ this.updateWalletMap(accountAddress, {
3991
4059
  walletReadyState: core.WalletReadyState.ENCRYPTED
3992
4060
  });
4061
+ await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
3993
4062
  // Return wallet in locked state (no error for eager loading)
3994
- return this.walletMap[accountAddress];
4063
+ const wallet = this.getWalletFromMap(accountAddress);
4064
+ if (!wallet) {
4065
+ throw new Error(`Wallet not found for address: ${accountAddress}`);
4066
+ }
4067
+ return wallet;
3995
4068
  }
3996
4069
  // TODO(zfaizal2): throw error if signedSessionId is not provided after service deploy
3997
4070
  const decryptedKeyShares = await this.recoverEncryptedBackupByWallet({
@@ -4018,7 +4091,11 @@ class DynamicWalletClient {
4018
4091
  if (walletCount === 1) {
4019
4092
  return Object.values(this.walletMap)[0];
4020
4093
  }
4021
- return this.walletMap[accountAddress];
4094
+ const wallet = this.getWalletFromMap(accountAddress);
4095
+ if (!wallet) {
4096
+ throw new Error(`Wallet not found for address: ${accountAddress}`);
4097
+ }
4098
+ return wallet;
4022
4099
  } catch (error) {
4023
4100
  logError({
4024
4101
  message: 'Error in getWallet',
@@ -4049,17 +4126,21 @@ class DynamicWalletClient {
4049
4126
  * @returns WalletRecoveryState indicating the wallet's lock state and share availability
4050
4127
  * @throws Error if recovery fails or no shares available after recovery
4051
4128
  */ async getWalletRecoveryState({ accountAddress, signedSessionId, password }) {
4052
- const walletData = this.walletMap[accountAddress];
4129
+ const walletData = this.getWalletFromMap(accountAddress);
4053
4130
  if (!walletData) {
4054
4131
  throw new Error(`Wallet not found for address: ${accountAddress}`);
4055
4132
  }
4056
4133
  let clientKeyShares = await this.getClientKeySharesFromStorage({
4057
4134
  accountAddress
4058
4135
  });
4059
- // If no local shares and signedSessionId provided, trigger recovery via getWallet
4136
+ let hasEncryptedShares = await hasEncryptedSharesCached({
4137
+ accountAddress,
4138
+ backupInfo: walletData.clientKeySharesBackupInfo,
4139
+ storage: this.storage
4140
+ });
4141
+ // If no local shares and no cached encrypted shares, trigger recovery via getWallet
4060
4142
  // getWallet -> recoverEncryptedBackupByWallet handles deduplication via inFlightRecovery
4061
- if (clientKeyShares.length === 0 && signedSessionId) {
4062
- var _walletData_clientKeySharesBackupInfo;
4143
+ if (clientKeyShares.length === 0 && !hasEncryptedShares && signedSessionId) {
4063
4144
  await this.getWallet({
4064
4145
  accountAddress,
4065
4146
  walletOperation: core.WalletOperation.RECOVER,
@@ -4070,15 +4151,11 @@ class DynamicWalletClient {
4070
4151
  clientKeyShares = await this.getClientKeySharesFromStorage({
4071
4152
  accountAddress
4072
4153
  });
4073
- var _walletData_clientKeySharesBackupInfo_passwordEncrypted;
4074
- // For password-encrypted wallets, also check for cached encrypted shares
4075
- const isPasswordEncrypted = (_walletData_clientKeySharesBackupInfo_passwordEncrypted = (_walletData_clientKeySharesBackupInfo = walletData.clientKeySharesBackupInfo) == null ? void 0 : _walletData_clientKeySharesBackupInfo.passwordEncrypted) != null ? _walletData_clientKeySharesBackupInfo_passwordEncrypted : false;
4076
- let hasEncryptedShares = false;
4077
- if (isPasswordEncrypted && clientKeyShares.length === 0) {
4078
- const encryptedStorageKey = `${accountAddress}${core.ENCRYPTED_SHARES_STORAGE_SUFFIX}`;
4079
- const encryptedData = await this.storage.getItem(encryptedStorageKey);
4080
- hasEncryptedShares = !!encryptedData;
4081
- }
4154
+ hasEncryptedShares = await hasEncryptedSharesCached({
4155
+ accountAddress,
4156
+ backupInfo: walletData.clientKeySharesBackupInfo,
4157
+ storage: this.storage
4158
+ });
4082
4159
  if (clientKeyShares.length === 0 && !hasEncryptedShares) {
4083
4160
  throw new Error(`No key shares available for wallet ${accountAddress} after recovery`);
4084
4161
  }
@@ -4099,15 +4176,15 @@ class DynamicWalletClient {
4099
4176
  */ async unlockWallet({ accountAddress, password, signedSessionId }) {
4100
4177
  const dynamicRequestId = uuid.v4();
4101
4178
  try {
4102
- if (!this.walletMap[accountAddress]) {
4179
+ if (!this.getWalletFromMap(accountAddress)) {
4103
4180
  await this.getWallet({
4104
4181
  accountAddress,
4105
4182
  walletOperation: core.WalletOperation.NO_OPERATION,
4106
4183
  signedSessionId
4107
4184
  });
4108
4185
  }
4109
- const wallet = this.walletMap[accountAddress];
4110
- const encryptedStorageKey = `${accountAddress}${core.ENCRYPTED_SHARES_STORAGE_SUFFIX}`;
4186
+ const normalizedAccountAddress = normalizeAddress(accountAddress);
4187
+ const encryptedStorageKey = `${normalizedAccountAddress}${core.ENCRYPTED_SHARES_STORAGE_SUFFIX}`;
4111
4188
  let encryptedData = await this.storage.getItem(encryptedStorageKey);
4112
4189
  // If no cached encrypted shares, fetch via getWallet with RECOVER
4113
4190
  if (!encryptedData) {
@@ -4121,24 +4198,41 @@ class DynamicWalletClient {
4121
4198
  if (!encryptedData) {
4122
4199
  throw new Error('No encrypted shares found for wallet');
4123
4200
  }
4124
- const data = JSON.parse(encryptedData);
4125
- // Decrypt the key shares
4126
- const decryptedKeyShares = await Promise.all(data.keyShares.map((keyShare)=>this.decryptKeyShare({
4127
- keyShare: keyShare.encryptedAccountCredential,
4128
- password
4129
- })));
4130
- await this.setClientKeySharesToStorage({
4201
+ // Decrypt the requested wallet
4202
+ await this.decryptAndStoreWalletShares({
4131
4203
  accountAddress,
4132
- clientKeyShares: decryptedKeyShares
4204
+ encryptedData,
4205
+ password
4133
4206
  });
4134
- this.walletMap[accountAddress] = _extends({}, wallet, {
4135
- walletReadyState: core.WalletReadyState.READY
4207
+ // Decrypt all other password-encrypted wallets with the same password
4208
+ const otherEncryptedWallets = Object.entries(this.walletMap).filter(([addr, w])=>{
4209
+ var _w_clientKeySharesBackupInfo;
4210
+ return addr !== normalizedAccountAddress && w.walletReadyState !== core.WalletReadyState.READY && ((_w_clientKeySharesBackupInfo = w.clientKeySharesBackupInfo) == null ? void 0 : _w_clientKeySharesBackupInfo.passwordEncrypted);
4136
4211
  });
4212
+ await Promise.all(otherEncryptedWallets.map(async ([otherAddr])=>{
4213
+ try {
4214
+ const otherEncryptedStorageKey = `${otherAddr}${core.ENCRYPTED_SHARES_STORAGE_SUFFIX}`;
4215
+ const otherEncryptedData = await this.storage.getItem(otherEncryptedStorageKey);
4216
+ if (!otherEncryptedData) {
4217
+ return;
4218
+ }
4219
+ await this.decryptAndStoreWalletShares({
4220
+ accountAddress: otherAddr,
4221
+ encryptedData: otherEncryptedData,
4222
+ password
4223
+ });
4224
+ } catch (err) {
4225
+ this.logger.debug('[DynamicWaasWalletClient] Failed to unlock additional wallet', {
4226
+ accountAddress: otherAddr,
4227
+ error: err
4228
+ });
4229
+ }
4230
+ }));
4137
4231
  await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
4138
4232
  this.logger.debug('[DynamicWaasWalletClient] Wallet unlocked successfully', {
4139
4233
  accountAddress
4140
4234
  });
4141
- return this.walletMap[accountAddress];
4235
+ return this.getWalletFromMap(accountAddress);
4142
4236
  } catch (error) {
4143
4237
  logError({
4144
4238
  message: 'Error in unlockWallet',
@@ -4151,6 +4245,22 @@ class DynamicWalletClient {
4151
4245
  throw error;
4152
4246
  }
4153
4247
  }
4248
+ /**
4249
+ * Decrypts cached encrypted key shares for a wallet and stores them locally.
4250
+ */ async decryptAndStoreWalletShares({ accountAddress, encryptedData, password }) {
4251
+ const data = JSON.parse(encryptedData);
4252
+ const decryptedKeyShares = await Promise.all(data.keyShares.map((keyShare)=>this.decryptKeyShare({
4253
+ keyShare: keyShare.encryptedAccountCredential,
4254
+ password
4255
+ })));
4256
+ await this.setClientKeySharesToStorage({
4257
+ accountAddress,
4258
+ clientKeyShares: decryptedKeyShares
4259
+ });
4260
+ this.updateWalletMap(accountAddress, {
4261
+ walletReadyState: core.WalletReadyState.READY
4262
+ });
4263
+ }
4154
4264
  async getWallets() {
4155
4265
  const dynamicRequestId = uuid.v4();
4156
4266
  try {
@@ -4159,8 +4269,8 @@ class DynamicWalletClient {
4159
4269
  this.userId = user.id;
4160
4270
  const waasWallets = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.filter((vc)=>vc.walletName === 'dynamicwaas');
4161
4271
  const wallets = waasWallets.map((vc)=>{
4162
- var _this_walletMap_vc_address, _vc_walletProperties, _vc_walletProperties1;
4163
- var _this_walletMap_vc_address_derivationPath;
4272
+ var _this_getWalletFromMap, _vc_walletProperties, _vc_walletProperties1;
4273
+ var _this_getWalletFromMap_derivationPath;
4164
4274
  return {
4165
4275
  walletId: vc.id,
4166
4276
  chainName: vc.chain,
@@ -4168,23 +4278,24 @@ class DynamicWalletClient {
4168
4278
  clientKeySharesBackupInfo: getClientKeyShareBackupInfo({
4169
4279
  walletProperties: vc.walletProperties || {}
4170
4280
  }),
4171
- 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,
4281
+ derivationPath: (_this_getWalletFromMap_derivationPath = (_this_getWalletFromMap = this.getWalletFromMap(vc.address)) == null ? void 0 : _this_getWalletFromMap.derivationPath) != null ? _this_getWalletFromMap_derivationPath : undefined,
4172
4282
  thresholdSignatureScheme: (_vc_walletProperties = vc.walletProperties) == null ? void 0 : _vc_walletProperties.thresholdSignatureScheme,
4173
4283
  addressType: (_vc_walletProperties1 = vc.walletProperties) == null ? void 0 : _vc_walletProperties1.addressType
4174
4284
  };
4175
4285
  });
4286
+ const existingWalletMap = this.walletMap;
4176
4287
  this.walletMap = wallets.reduce((acc, wallet)=>{
4177
- var _acc_accountAddress;
4178
- const accountAddress = wallet.accountAddress;
4179
- acc[wallet.accountAddress] = {
4288
+ const normalizedAddress = normalizeAddress(wallet.accountAddress);
4289
+ const existingWallet = existingWalletMap[normalizedAddress];
4290
+ acc[normalizedAddress] = {
4180
4291
  walletId: wallet.walletId,
4181
4292
  chainName: wallet.chainName,
4182
4293
  accountAddress: wallet.accountAddress,
4183
4294
  clientKeySharesBackupInfo: wallet.clientKeySharesBackupInfo,
4184
- derivationPath: ((_acc_accountAddress = acc[accountAddress]) == null ? void 0 : _acc_accountAddress.derivationPath) || undefined,
4295
+ derivationPath: existingWallet == null ? void 0 : existingWallet.derivationPath,
4185
4296
  thresholdSignatureScheme: wallet.thresholdSignatureScheme,
4186
4297
  addressType: wallet.addressType,
4187
- walletReadyState: core.WalletReadyState.READY
4298
+ walletReadyState: existingWallet == null ? void 0 : existingWallet.walletReadyState
4188
4299
  };
4189
4300
  return acc;
4190
4301
  }, {});
@@ -4469,6 +4580,7 @@ exports.getMPCSignatureScheme = getMPCSignatureScheme;
4469
4580
  exports.getMPCSigner = getMPCSigner;
4470
4581
  exports.hasCloudProviderBackup = hasCloudProviderBackup;
4471
4582
  exports.hasDelegatedBackup = hasDelegatedBackup;
4583
+ exports.hasEncryptedSharesCached = hasEncryptedSharesCached;
4472
4584
  exports.initializeCloudKit = initializeCloudKit;
4473
4585
  exports.isBrowser = isBrowser;
4474
4586
  exports.isHeavyQueueOperation = isHeavyQueueOperation;