@dynamic-labs-wallet/browser 0.0.260 → 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.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import { BitcoinAddressType, SigningAlgorithm, MPC_RELAY_PROD_API_URL, getMPCChainConfig, AuthMode, BackupLocation, WalletOperation, WalletReadyState, parseNamespacedVersion, FEATURE_FLAGS, ThresholdSignatureScheme, getClientThreshold, MPC_CONFIG, getTSSConfig, serializeMessageForForwardMPC, getReshareConfig, verifiedCredentialNameToChainEnum, ENCRYPTED_SHARES_STORAGE_SUFFIX, DynamicApiClient, getEnvironmentFromUrl, IFRAME_DOMAIN_MAP } from '@dynamic-labs-wallet/core';
1
+ import { BitcoinAddressType, SigningAlgorithm, MPC_RELAY_PROD_API_URL, getMPCChainConfig, AuthMode, BackupLocation, ENCRYPTED_SHARES_STORAGE_SUFFIX, WalletOperation, WalletReadyState, parseNamespacedVersion, FEATURE_FLAGS, ThresholdSignatureScheme, getClientThreshold, MPC_CONFIG, getTSSConfig, serializeMessageForForwardMPC, getReshareConfig, verifiedCredentialNameToChainEnum, DynamicApiClient, getEnvironmentFromUrl, IFRAME_DOMAIN_MAP } from '@dynamic-labs-wallet/core';
2
2
  export * from '@dynamic-labs-wallet/core';
3
3
  import { BIP340, ExportableEd25519, Ecdsa, MessageHash, EcdsaSignature, EcdsaKeygenResult, ExportableEd25519KeygenResult, BIP340KeygenResult } from '#internal/web';
4
4
  export { BIP340, BIP340InitKeygenResult, BIP340KeygenResult, Ecdsa, EcdsaInitKeygenResult, EcdsaKeygenResult, EcdsaPublicKey, EcdsaSignature, Ed25519, Ed25519InitKeygenResult, Ed25519KeygenResult, MessageHash } from '#internal/web';
@@ -222,6 +222,11 @@ const ensureBase64Padding = (str)=>{
222
222
  ]);
223
223
  };
224
224
 
225
+ const INVALID_PASSWORD_ERROR = 'Decryption failed: Invalid password. Please check your password and try again.';
226
+ /**
227
+ * Check if an error is an OperationError from SubtleCrypto.decrypt,
228
+ * which indicates authentication failure (wrong password/derived key)
229
+ */ const isInvalidPasswordError = (error)=>error instanceof Error && error.name === 'OperationError';
225
230
  /**
226
231
  * Get the appropriate key derivation function based on the encryption config
227
232
  */ const getKey = async (params, encryptionConfig)=>{
@@ -310,10 +315,15 @@ const ensureBase64Padding = (str)=>{
310
315
  }, key, cipherBytes);
311
316
  return new TextDecoder().decode(decryptedData);
312
317
  } catch (retryError) {
313
- // If retry also fails, throw the original error with additional context
318
+ if (isInvalidPasswordError(retryError)) {
319
+ throw new Error(INVALID_PASSWORD_ERROR);
320
+ }
314
321
  throw new Error(`Decryption failed after retry with parallelism=1: ${retryError}`);
315
322
  }
316
323
  }
324
+ if (isInvalidPasswordError(error)) {
325
+ throw new Error(INVALID_PASSWORD_ERROR);
326
+ }
317
327
  throw new Error('Decryption failed: ' + error);
318
328
  }
319
329
  };
@@ -506,6 +516,12 @@ const ERROR_EXPORT_PRIVATE_KEY = '[DynamicWaasWalletClient]: Error exporting pri
506
516
  const ERROR_IMPORT_PRIVATE_KEY = '[DynamicWaasWalletClient]: Error importing private key';
507
517
  const ERROR_PUBLIC_KEY_MISMATCH = 'Mismatch between the public keys of the server and the ones provided';
508
518
 
519
+ /**
520
+ * Normalizes an address to lowercase for consistent map key lookups.
521
+ * This ensures that addresses with different casing (e.g., EIP-55 checksummed vs lowercase)
522
+ * resolve to the same wallet entry.
523
+ */ const normalizeAddress = (address)=>address.toLowerCase();
524
+
509
525
  // eslint-disable-next-line @nx/enforce-module-boundaries
510
526
  const isBrowser = ()=>typeof window !== 'undefined';
511
527
  /**
@@ -696,6 +712,16 @@ const downloadStringAsFile = ({ filename, content, mimeType = 'application/json'
696
712
  a.click();
697
713
  URL.revokeObjectURL(url);
698
714
  };
715
+ /**
716
+ * Checks if a wallet has cached encrypted shares in storage.
717
+ */ const hasEncryptedSharesCached = async ({ accountAddress, backupInfo, storage })=>{
718
+ if (!(backupInfo == null ? void 0 : backupInfo.passwordEncrypted)) {
719
+ return false;
720
+ }
721
+ const encryptedStorageKey = `${normalizeAddress(accountAddress)}${ENCRYPTED_SHARES_STORAGE_SUFFIX}`;
722
+ const encryptedData = await storage.getItem(encryptedStorageKey);
723
+ return !!encryptedData;
724
+ };
699
725
  /**
700
726
  * Checks if an error is a public key mismatch error that can be recovered
701
727
  * by re-fetching the client key share from backup.
@@ -1240,6 +1266,7 @@ const hasDelegatedBackup = (backupInfo)=>{
1240
1266
  * Get or create the heavy operation queue for a wallet.
1241
1267
  * Heavy operations (refresh/reshare/recover) run with concurrency=1.
1242
1268
  */ static getHeavyOpQueue(accountAddress) {
1269
+ accountAddress = normalizeAddress(accountAddress);
1243
1270
  if (!this.heavyOpQueues.has(accountAddress)) {
1244
1271
  const queue = new PQueue({
1245
1272
  concurrency: 1,
@@ -1259,6 +1286,7 @@ const hasDelegatedBackup = (backupInfo)=>{
1259
1286
  * Get or create the sign queue for a wallet.
1260
1287
  * Sign operations run with unlimited concurrency (they're read-only on key shares).
1261
1288
  */ static getSignQueue(accountAddress) {
1289
+ accountAddress = normalizeAddress(accountAddress);
1262
1290
  if (!this.signQueues.has(accountAddress)) {
1263
1291
  const queue = new PQueue({
1264
1292
  concurrency: Infinity,
@@ -1277,12 +1305,14 @@ const hasDelegatedBackup = (backupInfo)=>{
1277
1305
  /**
1278
1306
  * Check if wallet has heavy operations in progress
1279
1307
  */ static isHeavyOpInProgress(accountAddress) {
1308
+ accountAddress = normalizeAddress(accountAddress);
1280
1309
  const queue = this.heavyOpQueues.get(accountAddress);
1281
1310
  return queue ? queue.size > 0 || queue.pending > 0 : false;
1282
1311
  }
1283
1312
  /**
1284
1313
  * Check if wallet has operations in any queue (heavy or sign)
1285
1314
  */ static isWalletBusy(accountAddress) {
1315
+ accountAddress = normalizeAddress(accountAddress);
1286
1316
  const heavyQueue = this.heavyOpQueues.get(accountAddress);
1287
1317
  const signQueue = this.signQueues.get(accountAddress);
1288
1318
  const heavyBusy = heavyQueue ? heavyQueue.size > 0 || heavyQueue.pending > 0 : false;
@@ -1292,22 +1322,22 @@ const hasDelegatedBackup = (backupInfo)=>{
1292
1322
  /**
1293
1323
  * Check if recovery is in progress for a wallet
1294
1324
  */ static isRecoveryInProgress(accountAddress) {
1295
- return this.pendingRecoveryPromises.has(accountAddress);
1325
+ return this.pendingRecoveryPromises.has(normalizeAddress(accountAddress));
1296
1326
  }
1297
1327
  /**
1298
1328
  * Get existing pending recovery promise if one exists
1299
1329
  */ static getPendingRecoveryPromise(accountAddress) {
1300
- return this.pendingRecoveryPromises.get(accountAddress);
1330
+ return this.pendingRecoveryPromises.get(normalizeAddress(accountAddress));
1301
1331
  }
1302
1332
  /**
1303
1333
  * Track a pending recovery promise
1304
1334
  */ static setPendingRecoveryPromise(accountAddress, promise) {
1305
- this.pendingRecoveryPromises.set(accountAddress, promise);
1335
+ this.pendingRecoveryPromises.set(normalizeAddress(accountAddress), promise);
1306
1336
  }
1307
1337
  /**
1308
1338
  * Clear pending recovery promise for a wallet
1309
1339
  */ static clearPendingRecoveryPromise(accountAddress) {
1310
- this.pendingRecoveryPromises.delete(accountAddress);
1340
+ this.pendingRecoveryPromises.delete(normalizeAddress(accountAddress));
1311
1341
  }
1312
1342
  /**
1313
1343
  * Queue a heavy operation with type validation.
@@ -1319,6 +1349,7 @@ const hasDelegatedBackup = (backupInfo)=>{
1319
1349
  * @param callback - The operation to execute
1320
1350
  * @throws Error if operation is not a valid heavy queue operation
1321
1351
  */ static async queueHeavyOperation(accountAddress, operation, callback) {
1352
+ accountAddress = normalizeAddress(accountAddress);
1322
1353
  // Runtime validation to catch any type assertion bypasses
1323
1354
  if (!isHeavyQueueOperation(operation)) {
1324
1355
  throw new Error(`Invalid heavy queue operation: ${operation}. Must be REFRESH, RESHARE, or RECOVER.`);
@@ -1349,6 +1380,7 @@ const hasDelegatedBackup = (backupInfo)=>{
1349
1380
  * @throws Error if operation is not a valid sign queue operation
1350
1381
  * @returns Promise resolving to the sign result
1351
1382
  */ static async queueSignOperation(accountAddress, operation, callback) {
1383
+ accountAddress = normalizeAddress(accountAddress);
1352
1384
  // Runtime validation to catch any type assertion bypasses
1353
1385
  if (!isSignQueueOperation(operation)) {
1354
1386
  throw new Error(`Invalid sign queue operation: ${operation}. Must be SIGN_MESSAGE or SIGN_TRANSACTION.`);
@@ -1384,6 +1416,7 @@ const hasDelegatedBackup = (backupInfo)=>{
1384
1416
  * @throws Error if operation is not a valid recover queue operation
1385
1417
  * @returns Promise resolving to the recovery result
1386
1418
  */ static async queueRecoverOperation(accountAddress, operation, callback) {
1419
+ accountAddress = normalizeAddress(accountAddress);
1387
1420
  // Runtime validation to catch any type assertion bypasses
1388
1421
  if (!isRecoverQueueOperation(operation)) {
1389
1422
  throw new Error(`Invalid recover queue operation: ${operation}. Must be RECOVER.`);
@@ -1668,6 +1701,19 @@ class DynamicWalletClient {
1668
1701
  */ static resetStaticState() {
1669
1702
  WalletQueueManager.resetForTesting();
1670
1703
  }
1704
+ /**
1705
+ * Get wallet properties from the wallet map using normalized address.
1706
+ * Normalizes the address to lowercase for consistent lookups regardless of input casing.
1707
+ */ getWalletFromMap(accountAddress) {
1708
+ return this.walletMap[normalizeAddress(accountAddress)];
1709
+ }
1710
+ /**
1711
+ * Update wallet properties in the wallet map using normalized address.
1712
+ * Normalizes the address to lowercase for consistent storage regardless of input casing.
1713
+ */ updateWalletMap(accountAddress, updates) {
1714
+ const normalizedAddr = normalizeAddress(accountAddress);
1715
+ this.walletMap[normalizedAddr] = _extends({}, this.walletMap[normalizedAddr], updates);
1716
+ }
1671
1717
  getAuthMode() {
1672
1718
  return this.authMode;
1673
1719
  }
@@ -2366,7 +2412,7 @@ class DynamicWalletClient {
2366
2412
  * from walletMap, with fallback to deriving it from derivationPath.
2367
2413
  */ getBitcoinConfigForChain(chainName, accountAddress) {
2368
2414
  if (chainName !== 'BTC') return undefined;
2369
- const walletProperties = this.walletMap[accountAddress];
2415
+ const walletProperties = this.getWalletFromMap(accountAddress);
2370
2416
  let addressType = walletProperties == null ? void 0 : walletProperties.addressType;
2371
2417
  // Fallback: derive addressType from derivationPath if not explicitly set
2372
2418
  if (!addressType && (walletProperties == null ? void 0 : walletProperties.derivationPath)) {
@@ -2685,7 +2731,7 @@ class DynamicWalletClient {
2685
2731
  allShares: allClientShares
2686
2732
  });
2687
2733
  }
2688
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
2734
+ this.updateWalletMap(accountAddress, {
2689
2735
  thresholdSignatureScheme: newThresholdSignatureScheme
2690
2736
  });
2691
2737
  // store client key shares to storage (localStorage or secureStorage)
@@ -2714,7 +2760,7 @@ class DynamicWalletClient {
2714
2760
  }
2715
2761
  });
2716
2762
  // reset user wallet when reshare fails, this would allow the client to recover wallets from an active state
2717
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
2763
+ this.updateWalletMap(accountAddress, {
2718
2764
  thresholdSignatureScheme: oldThresholdSignatureScheme
2719
2765
  });
2720
2766
  await this.setClientKeySharesToStorage({
@@ -2727,7 +2773,6 @@ class DynamicWalletClient {
2727
2773
  }
2728
2774
  async performDelegationOperation({ accountAddress, password, signedSessionId, mfaToken, newThresholdSignatureScheme, revokeDelegation = false, operationName }) {
2729
2775
  try {
2730
- var _this_walletMap_accountAddress;
2731
2776
  const delegateToProjectEnvironment = this.featureFlags && this.featureFlags[FEATURE_FLAGS.ENABLE_DELEGATED_KEY_SHARES_FLAG] === true;
2732
2777
  if (!delegateToProjectEnvironment) {
2733
2778
  throw new Error('Delegation is not allowed for this project environment');
@@ -2741,11 +2786,12 @@ class DynamicWalletClient {
2741
2786
  if (wallet.chainName === 'SUI') {
2742
2787
  throw new Error('Delegation is not allowed for SUI');
2743
2788
  }
2744
- const currentThresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
2789
+ const walletData = this.getWalletFromMap(accountAddress);
2790
+ const currentThresholdSignatureScheme = walletData.thresholdSignatureScheme;
2745
2791
  // Get active cloud providers to maintain existing backups
2746
- const activeProviders = getActiveCloudProviders((_this_walletMap_accountAddress = this.walletMap[accountAddress]) == null ? void 0 : _this_walletMap_accountAddress.clientKeySharesBackupInfo);
2792
+ const activeProviders = getActiveCloudProviders(walletData == null ? void 0 : walletData.clientKeySharesBackupInfo);
2747
2793
  await this.reshare({
2748
- chainName: this.walletMap[accountAddress].chainName,
2794
+ chainName: walletData.chainName,
2749
2795
  accountAddress,
2750
2796
  oldThresholdSignatureScheme: currentThresholdSignatureScheme,
2751
2797
  newThresholdSignatureScheme,
@@ -2776,7 +2822,7 @@ class DynamicWalletClient {
2776
2822
  newThresholdSignatureScheme: ThresholdSignatureScheme.TWO_OF_THREE,
2777
2823
  operationName: 'delegateKeyShares'
2778
2824
  });
2779
- const backupInfo = this.walletMap[accountAddress].clientKeySharesBackupInfo;
2825
+ const backupInfo = this.getWalletFromMap(accountAddress).clientKeySharesBackupInfo;
2780
2826
  const delegatedKeyShares = backupInfo.backups[BackupLocation.DELEGATED] || [];
2781
2827
  return delegatedKeyShares;
2782
2828
  }
@@ -2975,6 +3021,7 @@ class DynamicWalletClient {
2975
3021
  /**
2976
3022
  * helper function to store encrypted backup by wallet from iframe local storage
2977
3023
  */ async getClientKeySharesFromLocalStorage({ accountAddress }) {
3024
+ accountAddress = normalizeAddress(accountAddress);
2978
3025
  const walletObject = await this.storage.getItem(accountAddress);
2979
3026
  if (!walletObject) {
2980
3027
  this.logger.debug(`[DynamicWaasWalletClient] No item found in iframe local storage for accountAddress: ${accountAddress}`);
@@ -3003,6 +3050,7 @@ class DynamicWalletClient {
3003
3050
  * Helper function to get client key shares from storage.
3004
3051
  * Uses secureStorage when available (mobile), otherwise falls back to localStorage (browser).
3005
3052
  */ async getClientKeySharesFromStorage({ accountAddress }) {
3053
+ accountAddress = normalizeAddress(accountAddress);
3006
3054
  // Use secure storage if available (mobile)
3007
3055
  if (this.secureStorage) {
3008
3056
  try {
@@ -3035,7 +3083,7 @@ class DynamicWalletClient {
3035
3083
  * @param derivationPath - Optional derivation path (will be computed from chainConfig if not provided)
3036
3084
  * @param additionalProps - Any chain-specific additional properties to merge
3037
3085
  */ initializeWalletMapEntry({ accountAddress, walletId, chainName, thresholdSignatureScheme, derivationPath, additionalProps = {} }) {
3038
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
3086
+ this.updateWalletMap(accountAddress, _extends({
3039
3087
  accountAddress,
3040
3088
  walletId,
3041
3089
  chainName,
@@ -3044,7 +3092,7 @@ class DynamicWalletClient {
3044
3092
  derivationPath
3045
3093
  } : {}, {
3046
3094
  clientKeySharesBackupInfo: getClientKeyShareBackupInfo()
3047
- }, additionalProps);
3095
+ }, additionalProps));
3048
3096
  this.logger.debug('walletMap initialized for wallet', {
3049
3097
  context: {
3050
3098
  accountAddress,
@@ -3058,6 +3106,7 @@ class DynamicWalletClient {
3058
3106
  * Helper function to store client key shares in storage.
3059
3107
  * Uses secureStorage when available (mobile), otherwise falls back to localStorage (browser).
3060
3108
  */ async setClientKeySharesToLocalStorage({ accountAddress, clientKeyShares, overwriteOrMerge = 'merge' }) {
3109
+ accountAddress = normalizeAddress(accountAddress);
3061
3110
  const stringifiedClientKeyShares = JSON.stringify({
3062
3111
  clientKeyShares: overwriteOrMerge === 'overwrite' ? clientKeyShares : mergeUniqueKeyShares(await this.getClientKeySharesFromLocalStorage({
3063
3112
  accountAddress
@@ -3069,6 +3118,7 @@ class DynamicWalletClient {
3069
3118
  * Helper function to store client key shares in storage.
3070
3119
  * Uses secureStorage when available (mobile), otherwise falls back to localStorage (browser).
3071
3120
  */ async setClientKeySharesToStorage({ accountAddress, clientKeyShares, overwriteOrMerge = 'merge' }) {
3121
+ accountAddress = normalizeAddress(accountAddress);
3072
3122
  // Use secure storage if available (mobile)
3073
3123
  if (this.secureStorage) {
3074
3124
  try {
@@ -3114,8 +3164,8 @@ class DynamicWalletClient {
3114
3164
  async backupSharesWithDistribution({ accountAddress, password, signedSessionId, distribution, preserveDelegatedLocation = false }) {
3115
3165
  const dynamicRequestId = v4();
3116
3166
  try {
3117
- var _this_walletMap_accountAddress;
3118
- if (!((_this_walletMap_accountAddress = this.walletMap[accountAddress]) == null ? void 0 : _this_walletMap_accountAddress.walletId)) {
3167
+ const walletData = this.getWalletFromMap(accountAddress);
3168
+ if (!(walletData == null ? void 0 : walletData.walletId)) {
3119
3169
  const error = new Error(`WalletId not found for accountAddress ${accountAddress}`);
3120
3170
  logError({
3121
3171
  message: 'Error in backupSharesWithDistribution, wallet or walletId not found from the wallet map',
@@ -3135,7 +3185,7 @@ class DynamicWalletClient {
3135
3185
  password
3136
3186
  })));
3137
3187
  const data = await this.apiClient.storeEncryptedBackupByWallet({
3138
- walletId: this.walletMap[accountAddress].walletId,
3188
+ walletId: walletData.walletId,
3139
3189
  encryptedKeyShares: encryptedDynamicShares,
3140
3190
  passwordEncrypted: isPasswordEncrypted,
3141
3191
  encryptionVersion: ENCRYPTION_VERSION_CURRENT,
@@ -3181,7 +3231,7 @@ class DynamicWalletClient {
3181
3231
  var _publicKey_key_keyId;
3182
3232
  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);
3183
3233
  const { status } = await this.apiClient.publishDelegatedKeyShare({
3184
- walletId: this.walletMap[accountAddress].walletId,
3234
+ walletId: walletData.walletId,
3185
3235
  encryptedKeyShare: encryptedDelegatedKeyShareEnvelope,
3186
3236
  signedSessionId,
3187
3237
  requiresSignedSessionId: this.requiresSignedSessionId(),
@@ -3203,23 +3253,23 @@ class DynamicWalletClient {
3203
3253
  });
3204
3254
  }
3205
3255
  const backupData = await this.apiClient.markKeySharesAsBackedUp({
3206
- walletId: this.walletMap[accountAddress].walletId,
3256
+ walletId: walletData.walletId,
3207
3257
  locations,
3208
3258
  dynamicRequestId
3209
3259
  });
3210
3260
  const updatedBackupInfo = getClientKeyShareBackupInfo({
3211
3261
  walletProperties: {
3212
- derivationPath: this.walletMap[accountAddress].derivationPath,
3262
+ derivationPath: walletData.derivationPath,
3213
3263
  keyShares: backupData.locationsWithKeyShares.map((ks)=>({
3214
3264
  id: ks.keyShareId,
3215
3265
  backupLocation: ks.location,
3216
3266
  externalKeyShareId: ks.externalKeyShareId,
3217
3267
  passwordEncrypted: isPasswordEncrypted
3218
3268
  })),
3219
- thresholdSignatureScheme: this.walletMap[accountAddress].thresholdSignatureScheme
3269
+ thresholdSignatureScheme: walletData.thresholdSignatureScheme
3220
3270
  }
3221
3271
  });
3222
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
3272
+ this.updateWalletMap(accountAddress, {
3223
3273
  clientKeySharesBackupInfo: updatedBackupInfo
3224
3274
  });
3225
3275
  await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
@@ -3267,16 +3317,17 @@ class DynamicWalletClient {
3267
3317
  * @param params.backupToGoogleDrive - Whether to backup to Google Drive (defaults to false)
3268
3318
  * @returns Promise with backup metadata including share locations and IDs
3269
3319
  */ async storeEncryptedBackupByWallet({ accountAddress, clientKeyShares = undefined, password = undefined, signedSessionId, cloudProviders = [], delegatedKeyshare = undefined }) {
3270
- var _this_walletMap_accountAddress, _this_walletMap_accountAddress1;
3320
+ var _this_getWalletFromMap;
3271
3321
  const keySharesToBackup = clientKeyShares != null ? clientKeyShares : await this.getClientKeySharesFromStorage({
3272
3322
  accountAddress
3273
3323
  });
3274
3324
  // Check if we should backup to cloud providers (either requested or already exists)
3275
- const activeCloudProviders = getActiveCloudProviders((_this_walletMap_accountAddress = this.walletMap[accountAddress]) == null ? void 0 : _this_walletMap_accountAddress.clientKeySharesBackupInfo);
3325
+ const walletBackupInfo = (_this_getWalletFromMap = this.getWalletFromMap(accountAddress)) == null ? void 0 : _this_getWalletFromMap.clientKeySharesBackupInfo;
3326
+ const activeCloudProviders = getActiveCloudProviders(walletBackupInfo);
3276
3327
  const shouldBackupToCloudProviders = cloudProviders.length > 0 || activeCloudProviders.length > 0;
3277
3328
  // Use requested providers, or fall back to existing active providers
3278
3329
  const providersToBackup = cloudProviders.length > 0 ? cloudProviders : activeCloudProviders;
3279
- const hasExistingDelegation = hasDelegatedBackup((_this_walletMap_accountAddress1 = this.walletMap[accountAddress]) == null ? void 0 : _this_walletMap_accountAddress1.clientKeySharesBackupInfo);
3330
+ const hasExistingDelegation = hasDelegatedBackup(walletBackupInfo);
3280
3331
  let distribution;
3281
3332
  let preserveDelegatedLocation = false;
3282
3333
  // Generic distribution logic - works with any cloud providers
@@ -3440,7 +3491,7 @@ class DynamicWalletClient {
3440
3491
  }
3441
3492
  async internalRecoverEncryptedBackupByWallet({ accountAddress, password, walletOperation, signedSessionId, shareCount = undefined, storeRecoveredShares = true, mfaToken }) {
3442
3493
  try {
3443
- const wallet = this.walletMap[accountAddress];
3494
+ const wallet = this.getWalletFromMap(accountAddress);
3444
3495
  this.logger.debug(`recoverEncryptedBackupByWallet wallet: ${walletOperation}`, wallet);
3445
3496
  const { shares } = this.recoverStrategy({
3446
3497
  clientKeyShareBackupInfo: wallet.clientKeySharesBackupInfo,
@@ -3488,7 +3539,12 @@ class DynamicWalletClient {
3488
3539
  if (!wallets) {
3489
3540
  return;
3490
3541
  }
3491
- this.walletMap = JSON.parse(wallets);
3542
+ const parsedWallets = JSON.parse(wallets);
3543
+ this.walletMap = Object.keys(parsedWallets).reduce((acc, key)=>{
3544
+ const normalizedKey = normalizeAddress(key);
3545
+ acc[normalizedKey] = parsedWallets[key];
3546
+ return acc;
3547
+ }, {});
3492
3548
  }
3493
3549
  /**
3494
3550
  * Internal helper method that handles the complete flow for ensuring wallet key shares are backed up to a cloud provider.
@@ -3502,11 +3558,12 @@ class DynamicWalletClient {
3502
3558
  password,
3503
3559
  signedSessionId
3504
3560
  });
3505
- const currentThresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
3561
+ const walletData = this.getWalletFromMap(accountAddress);
3562
+ const currentThresholdSignatureScheme = walletData.thresholdSignatureScheme;
3506
3563
  if (currentThresholdSignatureScheme === ThresholdSignatureScheme.TWO_OF_TWO) {
3507
3564
  // Reshare to 2-of-3, which will automatically handle the backup distribution
3508
3565
  await this.reshare({
3509
- chainName: this.walletMap[accountAddress].chainName,
3566
+ chainName: walletData.chainName,
3510
3567
  accountAddress,
3511
3568
  oldThresholdSignatureScheme: currentThresholdSignatureScheme,
3512
3569
  newThresholdSignatureScheme: ThresholdSignatureScheme.TWO_OF_THREE,
@@ -3616,7 +3673,7 @@ class DynamicWalletClient {
3616
3673
  const accessToken = await this.apiClient.getAccessToken({
3617
3674
  oauthAccountId
3618
3675
  });
3619
- const thresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
3676
+ const thresholdSignatureScheme = this.getWalletFromMap(accountAddress).thresholdSignatureScheme;
3620
3677
  const fileName = getClientKeyShareExportFileName({
3621
3678
  thresholdSignatureScheme,
3622
3679
  accountAddress,
@@ -3656,7 +3713,7 @@ class DynamicWalletClient {
3656
3713
  if (encryptedKeyShares.length === 0) {
3657
3714
  throw new Error('No key shares found');
3658
3715
  }
3659
- const thresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
3716
+ const thresholdSignatureScheme = this.getWalletFromMap(accountAddress).thresholdSignatureScheme;
3660
3717
  const backupData = createBackupData({
3661
3718
  encryptedKeyShares,
3662
3719
  accountAddress,
@@ -3685,7 +3742,7 @@ class DynamicWalletClient {
3685
3742
  const accessToken = await this.apiClient.getAccessToken({
3686
3743
  oauthAccountId
3687
3744
  });
3688
- const thresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
3745
+ const thresholdSignatureScheme = this.getWalletFromMap(accountAddress).thresholdSignatureScheme;
3689
3746
  const backupFileName = getClientKeyShareExportFileName({
3690
3747
  thresholdSignatureScheme,
3691
3748
  accountAddress,
@@ -3761,6 +3818,7 @@ class DynamicWalletClient {
3761
3818
  }
3762
3819
  }
3763
3820
  async exportClientKeyshares({ accountAddress, password, signedSessionId }) {
3821
+ var _this_getWalletFromMap;
3764
3822
  await this.verifyPassword({
3765
3823
  accountAddress,
3766
3824
  password,
@@ -3772,7 +3830,7 @@ class DynamicWalletClient {
3772
3830
  }
3773
3831
  // Ensure client key shares exist before export
3774
3832
  const clientKeyShares = await this.ensureClientShare(accountAddress);
3775
- const derivationPath = this.walletMap[accountAddress].derivationPath;
3833
+ const derivationPath = (_this_getWalletFromMap = this.getWalletFromMap(accountAddress)) == null ? void 0 : _this_getWalletFromMap.derivationPath;
3776
3834
  const text = JSON.stringify({
3777
3835
  keyShares: clientKeyShares,
3778
3836
  derivationPath
@@ -3805,7 +3863,7 @@ class DynamicWalletClient {
3805
3863
  let thresholdSignatureSchemeCheck = false;
3806
3864
  let derivationPathCheck = false;
3807
3865
  // check if wallet exists
3808
- const existingWallet = this.walletMap[accountAddress];
3866
+ const existingWallet = this.getWalletFromMap(accountAddress);
3809
3867
  if (existingWallet) {
3810
3868
  walletCheck = true;
3811
3869
  }
@@ -3843,7 +3901,7 @@ class DynamicWalletClient {
3843
3901
  * and decryption without storing the restored key shares. If unsuccessful, it throws an error.
3844
3902
  */ async verifyPassword({ accountAddress, password = undefined, walletOperation = WalletOperation.NO_OPERATION, signedSessionId }) {
3845
3903
  // Only load wallet if it's not already loaded (to avoid double eager loading)
3846
- if (!this.walletMap[accountAddress]) {
3904
+ if (!this.getWalletFromMap(accountAddress)) {
3847
3905
  await this.getWallet({
3848
3906
  accountAddress,
3849
3907
  walletOperation,
@@ -3902,7 +3960,7 @@ class DynamicWalletClient {
3902
3960
  });
3903
3961
  const { requiredShareCount } = this.recoverStrategy({
3904
3962
  clientKeyShareBackupInfo: clientKeySharesBackupInfo,
3905
- thresholdSignatureScheme: this.walletMap[accountAddress].thresholdSignatureScheme,
3963
+ thresholdSignatureScheme: this.getWalletFromMap(accountAddress).thresholdSignatureScheme,
3906
3964
  walletOperation
3907
3965
  });
3908
3966
  if (clientKeyShares.length >= requiredShareCount) {
@@ -3913,10 +3971,11 @@ class DynamicWalletClient {
3913
3971
  async getWalletClientKeyShareBackupInfo({ accountAddress }) {
3914
3972
  const dynamicRequestId = v4();
3915
3973
  try {
3916
- var _this_walletMap_accountAddress_clientKeySharesBackupInfo_backups_BackupLocation_DYNAMIC, _this_walletMap_accountAddress_clientKeySharesBackupInfo_backups, _this_walletMap_accountAddress_clientKeySharesBackupInfo, _this_walletMap_accountAddress, _user_verifiedCredentials;
3974
+ var _this_getWalletFromMap, _walletBackupInfo_backups_BackupLocation_DYNAMIC, _walletBackupInfo_backups, _user_verifiedCredentials;
3917
3975
  // Return existing backup info if it exists
3918
- 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[BackupLocation.DYNAMIC]) == null ? void 0 : _this_walletMap_accountAddress_clientKeySharesBackupInfo_backups_BackupLocation_DYNAMIC.length) > 0) {
3919
- return this.walletMap[accountAddress].clientKeySharesBackupInfo;
3976
+ const walletBackupInfo = (_this_getWalletFromMap = this.getWalletFromMap(accountAddress)) == null ? void 0 : _this_getWalletFromMap.clientKeySharesBackupInfo;
3977
+ if (walletBackupInfo && ((_walletBackupInfo_backups = walletBackupInfo.backups) == null ? void 0 : (_walletBackupInfo_backups_BackupLocation_DYNAMIC = _walletBackupInfo_backups[BackupLocation.DYNAMIC]) == null ? void 0 : _walletBackupInfo_backups_BackupLocation_DYNAMIC.length) > 0) {
3978
+ return walletBackupInfo;
3920
3979
  }
3921
3980
  // Get backup info from server
3922
3981
  const user = await this.apiClient.getUser(dynamicRequestId);
@@ -3947,30 +4006,36 @@ class DynamicWalletClient {
3947
4006
  });
3948
4007
  if (existingWalletCheck) {
3949
4008
  this.logger.debug(`[DynamicWaasWalletClient] Wallet ${accountAddress} already exists`);
3950
- return this.walletMap[accountAddress];
4009
+ const wallet = this.getWalletFromMap(accountAddress);
4010
+ if (!wallet) {
4011
+ throw new Error(`Wallet not found for address: ${accountAddress}`);
4012
+ }
4013
+ return wallet;
3951
4014
  }
3952
- // Fetch and restore wallet from server
4015
+ // Fetch and restore all waas wallets from server
3953
4016
  const user = await this.apiClient.getUser(dynamicRequestId);
3954
- const wallet = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.find((vc)=>vc.address.toLowerCase() === accountAddress.toLowerCase());
3955
- this.logger.debug('[DynamicWaasWalletClient] Restoring wallet', wallet);
3956
- const walletProperties = wallet.walletProperties;
3957
- this.walletMap[accountAddress] = _extends({}, this.walletMap[accountAddress], {
3958
- walletId: wallet.id,
3959
- chainName: verifiedCredentialNameToChainEnum[wallet.chain],
3960
- accountAddress,
3961
- thresholdSignatureScheme: walletProperties.thresholdSignatureScheme,
3962
- derivationPath: walletProperties.derivationPath,
3963
- clientKeySharesBackupInfo: getClientKeyShareBackupInfo({
3964
- walletProperties
3965
- }),
3966
- addressType: walletProperties.addressType
3967
- });
4017
+ const waasWallets = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.filter((vc)=>vc.walletName === 'dynamicwaas');
4018
+ for (const vc of waasWallets != null ? waasWallets : []){
4019
+ const addr = vc.address;
4020
+ const props = vc.walletProperties;
4021
+ this.updateWalletMap(addr, {
4022
+ walletId: vc.id,
4023
+ chainName: verifiedCredentialNameToChainEnum[vc.chain],
4024
+ accountAddress: addr,
4025
+ thresholdSignatureScheme: props == null ? void 0 : props.thresholdSignatureScheme,
4026
+ derivationPath: props == null ? void 0 : props.derivationPath,
4027
+ clientKeySharesBackupInfo: getClientKeyShareBackupInfo({
4028
+ walletProperties: props
4029
+ }),
4030
+ addressType: props == null ? void 0 : props.addressType
4031
+ });
4032
+ }
3968
4033
  if (walletOperation !== WalletOperation.NO_OPERATION && await this.requiresRestoreBackupSharesForOperation({
3969
4034
  accountAddress,
3970
4035
  walletOperation
3971
4036
  })) {
3972
4037
  var _walletData_clientKeySharesBackupInfo;
3973
- const walletData = this.walletMap[accountAddress];
4038
+ const walletData = this.getWalletFromMap(accountAddress);
3974
4039
  var _walletData_clientKeySharesBackupInfo_passwordEncrypted;
3975
4040
  const isPasswordEncrypted = (_walletData_clientKeySharesBackupInfo_passwordEncrypted = (_walletData_clientKeySharesBackupInfo = walletData.clientKeySharesBackupInfo) == null ? void 0 : _walletData_clientKeySharesBackupInfo.passwordEncrypted) != null ? _walletData_clientKeySharesBackupInfo_passwordEncrypted : false;
3976
4041
  // Password-encrypted wallet without password - fetch and cache for eager loading
@@ -3988,14 +4053,19 @@ class DynamicWalletClient {
3988
4053
  requiresSignedSessionId: this.requiresSignedSessionId()
3989
4054
  });
3990
4055
  // Cache encrypted shares for later decryption by unlockWallet
3991
- const encryptedStorageKey = `${accountAddress}${ENCRYPTED_SHARES_STORAGE_SUFFIX}`;
4056
+ const encryptedStorageKey = `${normalizeAddress(accountAddress)}${ENCRYPTED_SHARES_STORAGE_SUFFIX}`;
3992
4057
  await this.storage.setItem(encryptedStorageKey, JSON.stringify(data));
3993
4058
  // Update wallet state to locked
3994
- this.walletMap[accountAddress] = _extends({}, walletData, {
4059
+ this.updateWalletMap(accountAddress, {
3995
4060
  walletReadyState: WalletReadyState.ENCRYPTED
3996
4061
  });
4062
+ await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
3997
4063
  // Return wallet in locked state (no error for eager loading)
3998
- return this.walletMap[accountAddress];
4064
+ const wallet = this.getWalletFromMap(accountAddress);
4065
+ if (!wallet) {
4066
+ throw new Error(`Wallet not found for address: ${accountAddress}`);
4067
+ }
4068
+ return wallet;
3999
4069
  }
4000
4070
  // TODO(zfaizal2): throw error if signedSessionId is not provided after service deploy
4001
4071
  const decryptedKeyShares = await this.recoverEncryptedBackupByWallet({
@@ -4022,7 +4092,11 @@ class DynamicWalletClient {
4022
4092
  if (walletCount === 1) {
4023
4093
  return Object.values(this.walletMap)[0];
4024
4094
  }
4025
- return this.walletMap[accountAddress];
4095
+ const wallet = this.getWalletFromMap(accountAddress);
4096
+ if (!wallet) {
4097
+ throw new Error(`Wallet not found for address: ${accountAddress}`);
4098
+ }
4099
+ return wallet;
4026
4100
  } catch (error) {
4027
4101
  logError({
4028
4102
  message: 'Error in getWallet',
@@ -4053,17 +4127,21 @@ class DynamicWalletClient {
4053
4127
  * @returns WalletRecoveryState indicating the wallet's lock state and share availability
4054
4128
  * @throws Error if recovery fails or no shares available after recovery
4055
4129
  */ async getWalletRecoveryState({ accountAddress, signedSessionId, password }) {
4056
- const walletData = this.walletMap[accountAddress];
4130
+ const walletData = this.getWalletFromMap(accountAddress);
4057
4131
  if (!walletData) {
4058
4132
  throw new Error(`Wallet not found for address: ${accountAddress}`);
4059
4133
  }
4060
4134
  let clientKeyShares = await this.getClientKeySharesFromStorage({
4061
4135
  accountAddress
4062
4136
  });
4063
- // If no local shares and signedSessionId provided, trigger recovery via getWallet
4137
+ let hasEncryptedShares = await hasEncryptedSharesCached({
4138
+ accountAddress,
4139
+ backupInfo: walletData.clientKeySharesBackupInfo,
4140
+ storage: this.storage
4141
+ });
4142
+ // If no local shares and no cached encrypted shares, trigger recovery via getWallet
4064
4143
  // getWallet -> recoverEncryptedBackupByWallet handles deduplication via inFlightRecovery
4065
- if (clientKeyShares.length === 0 && signedSessionId) {
4066
- var _walletData_clientKeySharesBackupInfo;
4144
+ if (clientKeyShares.length === 0 && !hasEncryptedShares && signedSessionId) {
4067
4145
  await this.getWallet({
4068
4146
  accountAddress,
4069
4147
  walletOperation: WalletOperation.RECOVER,
@@ -4074,15 +4152,11 @@ class DynamicWalletClient {
4074
4152
  clientKeyShares = await this.getClientKeySharesFromStorage({
4075
4153
  accountAddress
4076
4154
  });
4077
- var _walletData_clientKeySharesBackupInfo_passwordEncrypted;
4078
- // For password-encrypted wallets, also check for cached encrypted shares
4079
- const isPasswordEncrypted = (_walletData_clientKeySharesBackupInfo_passwordEncrypted = (_walletData_clientKeySharesBackupInfo = walletData.clientKeySharesBackupInfo) == null ? void 0 : _walletData_clientKeySharesBackupInfo.passwordEncrypted) != null ? _walletData_clientKeySharesBackupInfo_passwordEncrypted : false;
4080
- let hasEncryptedShares = false;
4081
- if (isPasswordEncrypted && clientKeyShares.length === 0) {
4082
- const encryptedStorageKey = `${accountAddress}${ENCRYPTED_SHARES_STORAGE_SUFFIX}`;
4083
- const encryptedData = await this.storage.getItem(encryptedStorageKey);
4084
- hasEncryptedShares = !!encryptedData;
4085
- }
4155
+ hasEncryptedShares = await hasEncryptedSharesCached({
4156
+ accountAddress,
4157
+ backupInfo: walletData.clientKeySharesBackupInfo,
4158
+ storage: this.storage
4159
+ });
4086
4160
  if (clientKeyShares.length === 0 && !hasEncryptedShares) {
4087
4161
  throw new Error(`No key shares available for wallet ${accountAddress} after recovery`);
4088
4162
  }
@@ -4103,15 +4177,15 @@ class DynamicWalletClient {
4103
4177
  */ async unlockWallet({ accountAddress, password, signedSessionId }) {
4104
4178
  const dynamicRequestId = v4();
4105
4179
  try {
4106
- if (!this.walletMap[accountAddress]) {
4180
+ if (!this.getWalletFromMap(accountAddress)) {
4107
4181
  await this.getWallet({
4108
4182
  accountAddress,
4109
4183
  walletOperation: WalletOperation.NO_OPERATION,
4110
4184
  signedSessionId
4111
4185
  });
4112
4186
  }
4113
- const wallet = this.walletMap[accountAddress];
4114
- const encryptedStorageKey = `${accountAddress}${ENCRYPTED_SHARES_STORAGE_SUFFIX}`;
4187
+ const normalizedAccountAddress = normalizeAddress(accountAddress);
4188
+ const encryptedStorageKey = `${normalizedAccountAddress}${ENCRYPTED_SHARES_STORAGE_SUFFIX}`;
4115
4189
  let encryptedData = await this.storage.getItem(encryptedStorageKey);
4116
4190
  // If no cached encrypted shares, fetch via getWallet with RECOVER
4117
4191
  if (!encryptedData) {
@@ -4125,24 +4199,41 @@ class DynamicWalletClient {
4125
4199
  if (!encryptedData) {
4126
4200
  throw new Error('No encrypted shares found for wallet');
4127
4201
  }
4128
- const data = JSON.parse(encryptedData);
4129
- // Decrypt the key shares
4130
- const decryptedKeyShares = await Promise.all(data.keyShares.map((keyShare)=>this.decryptKeyShare({
4131
- keyShare: keyShare.encryptedAccountCredential,
4132
- password
4133
- })));
4134
- await this.setClientKeySharesToStorage({
4202
+ // Decrypt the requested wallet
4203
+ await this.decryptAndStoreWalletShares({
4135
4204
  accountAddress,
4136
- clientKeyShares: decryptedKeyShares
4205
+ encryptedData,
4206
+ password
4137
4207
  });
4138
- this.walletMap[accountAddress] = _extends({}, wallet, {
4139
- walletReadyState: WalletReadyState.READY
4208
+ // Decrypt all other password-encrypted wallets with the same password
4209
+ const otherEncryptedWallets = Object.entries(this.walletMap).filter(([addr, w])=>{
4210
+ var _w_clientKeySharesBackupInfo;
4211
+ return addr !== normalizedAccountAddress && w.walletReadyState !== WalletReadyState.READY && ((_w_clientKeySharesBackupInfo = w.clientKeySharesBackupInfo) == null ? void 0 : _w_clientKeySharesBackupInfo.passwordEncrypted);
4140
4212
  });
4213
+ await Promise.all(otherEncryptedWallets.map(async ([otherAddr])=>{
4214
+ try {
4215
+ const otherEncryptedStorageKey = `${otherAddr}${ENCRYPTED_SHARES_STORAGE_SUFFIX}`;
4216
+ const otherEncryptedData = await this.storage.getItem(otherEncryptedStorageKey);
4217
+ if (!otherEncryptedData) {
4218
+ return;
4219
+ }
4220
+ await this.decryptAndStoreWalletShares({
4221
+ accountAddress: otherAddr,
4222
+ encryptedData: otherEncryptedData,
4223
+ password
4224
+ });
4225
+ } catch (err) {
4226
+ this.logger.debug('[DynamicWaasWalletClient] Failed to unlock additional wallet', {
4227
+ accountAddress: otherAddr,
4228
+ error: err
4229
+ });
4230
+ }
4231
+ }));
4141
4232
  await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
4142
4233
  this.logger.debug('[DynamicWaasWalletClient] Wallet unlocked successfully', {
4143
4234
  accountAddress
4144
4235
  });
4145
- return this.walletMap[accountAddress];
4236
+ return this.getWalletFromMap(accountAddress);
4146
4237
  } catch (error) {
4147
4238
  logError({
4148
4239
  message: 'Error in unlockWallet',
@@ -4155,6 +4246,22 @@ class DynamicWalletClient {
4155
4246
  throw error;
4156
4247
  }
4157
4248
  }
4249
+ /**
4250
+ * Decrypts cached encrypted key shares for a wallet and stores them locally.
4251
+ */ async decryptAndStoreWalletShares({ accountAddress, encryptedData, password }) {
4252
+ const data = JSON.parse(encryptedData);
4253
+ const decryptedKeyShares = await Promise.all(data.keyShares.map((keyShare)=>this.decryptKeyShare({
4254
+ keyShare: keyShare.encryptedAccountCredential,
4255
+ password
4256
+ })));
4257
+ await this.setClientKeySharesToStorage({
4258
+ accountAddress,
4259
+ clientKeyShares: decryptedKeyShares
4260
+ });
4261
+ this.updateWalletMap(accountAddress, {
4262
+ walletReadyState: WalletReadyState.READY
4263
+ });
4264
+ }
4158
4265
  async getWallets() {
4159
4266
  const dynamicRequestId = v4();
4160
4267
  try {
@@ -4163,8 +4270,8 @@ class DynamicWalletClient {
4163
4270
  this.userId = user.id;
4164
4271
  const waasWallets = (_user_verifiedCredentials = user.verifiedCredentials) == null ? void 0 : _user_verifiedCredentials.filter((vc)=>vc.walletName === 'dynamicwaas');
4165
4272
  const wallets = waasWallets.map((vc)=>{
4166
- var _this_walletMap_vc_address, _vc_walletProperties, _vc_walletProperties1;
4167
- var _this_walletMap_vc_address_derivationPath;
4273
+ var _this_getWalletFromMap, _vc_walletProperties, _vc_walletProperties1;
4274
+ var _this_getWalletFromMap_derivationPath;
4168
4275
  return {
4169
4276
  walletId: vc.id,
4170
4277
  chainName: vc.chain,
@@ -4172,23 +4279,24 @@ class DynamicWalletClient {
4172
4279
  clientKeySharesBackupInfo: getClientKeyShareBackupInfo({
4173
4280
  walletProperties: vc.walletProperties || {}
4174
4281
  }),
4175
- 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,
4282
+ derivationPath: (_this_getWalletFromMap_derivationPath = (_this_getWalletFromMap = this.getWalletFromMap(vc.address)) == null ? void 0 : _this_getWalletFromMap.derivationPath) != null ? _this_getWalletFromMap_derivationPath : undefined,
4176
4283
  thresholdSignatureScheme: (_vc_walletProperties = vc.walletProperties) == null ? void 0 : _vc_walletProperties.thresholdSignatureScheme,
4177
4284
  addressType: (_vc_walletProperties1 = vc.walletProperties) == null ? void 0 : _vc_walletProperties1.addressType
4178
4285
  };
4179
4286
  });
4287
+ const existingWalletMap = this.walletMap;
4180
4288
  this.walletMap = wallets.reduce((acc, wallet)=>{
4181
- var _acc_accountAddress;
4182
- const accountAddress = wallet.accountAddress;
4183
- acc[wallet.accountAddress] = {
4289
+ const normalizedAddress = normalizeAddress(wallet.accountAddress);
4290
+ const existingWallet = existingWalletMap[normalizedAddress];
4291
+ acc[normalizedAddress] = {
4184
4292
  walletId: wallet.walletId,
4185
4293
  chainName: wallet.chainName,
4186
4294
  accountAddress: wallet.accountAddress,
4187
4295
  clientKeySharesBackupInfo: wallet.clientKeySharesBackupInfo,
4188
- derivationPath: ((_acc_accountAddress = acc[accountAddress]) == null ? void 0 : _acc_accountAddress.derivationPath) || undefined,
4296
+ derivationPath: existingWallet == null ? void 0 : existingWallet.derivationPath,
4189
4297
  thresholdSignatureScheme: wallet.thresholdSignatureScheme,
4190
4298
  addressType: wallet.addressType,
4191
- walletReadyState: WalletReadyState.READY
4299
+ walletReadyState: existingWallet == null ? void 0 : existingWallet.walletReadyState
4192
4300
  };
4193
4301
  return acc;
4194
4302
  }, {});
@@ -4383,4 +4491,4 @@ class DynamicWalletClient {
4383
4491
  DynamicWalletClient.rooms = {};
4384
4492
  DynamicWalletClient.roomsInitializing = {};
4385
4493
 
4386
- export { DynamicWalletClient, ERROR_ACCOUNT_ADDRESS_REQUIRED, ERROR_CREATE_WALLET_ACCOUNT, ERROR_EXPORT_PRIVATE_KEY, ERROR_IMPORT_PRIVATE_KEY, ERROR_KEYGEN_FAILED, ERROR_PUBLIC_KEY_MISMATCH, ERROR_SIGN_MESSAGE, ERROR_SIGN_TYPED_DATA, ERROR_VERIFY_MESSAGE_SIGNATURE, ERROR_VERIFY_TRANSACTION_SIGNATURE, HEAVY_QUEUE_OPERATIONS, RECOVER_QUEUE_OPERATIONS, SIGN_QUEUE_OPERATIONS, WalletBusyError, WalletNotReadyError, cancelICloudAuth, createAddCloudProviderToExistingDelegationDistribution, createBackupData, createCloudProviderDistribution, createDelegationOnlyDistribution, createDelegationWithCloudProviderDistribution, createDynamicOnlyDistribution, deleteICloudBackup, downloadStringAsFile, extractPubkey, formatEvmMessage, formatMessage, getActiveCloudProviders, getBitcoinAddressTypeFromDerivationPath, getClientKeyShareBackupInfo, getClientKeyShareExportFileName, getGoogleOAuthAccountId, getICloudBackup, getMPCSignatureScheme, getMPCSigner, hasCloudProviderBackup, hasDelegatedBackup, initializeCloudKit, isBrowser, isHeavyQueueOperation, isHexString, isICloudAuthenticated, isPublicKeyMismatchError, isRecoverQueueOperation, isSignQueueOperation, listICloudBackups, mergeUniqueKeyShares, retryPromise, timeoutPromise };
4494
+ export { DynamicWalletClient, ERROR_ACCOUNT_ADDRESS_REQUIRED, ERROR_CREATE_WALLET_ACCOUNT, ERROR_EXPORT_PRIVATE_KEY, ERROR_IMPORT_PRIVATE_KEY, ERROR_KEYGEN_FAILED, ERROR_PUBLIC_KEY_MISMATCH, ERROR_SIGN_MESSAGE, ERROR_SIGN_TYPED_DATA, ERROR_VERIFY_MESSAGE_SIGNATURE, ERROR_VERIFY_TRANSACTION_SIGNATURE, HEAVY_QUEUE_OPERATIONS, RECOVER_QUEUE_OPERATIONS, SIGN_QUEUE_OPERATIONS, WalletBusyError, WalletNotReadyError, cancelICloudAuth, createAddCloudProviderToExistingDelegationDistribution, createBackupData, createCloudProviderDistribution, createDelegationOnlyDistribution, createDelegationWithCloudProviderDistribution, createDynamicOnlyDistribution, deleteICloudBackup, downloadStringAsFile, extractPubkey, formatEvmMessage, formatMessage, getActiveCloudProviders, getBitcoinAddressTypeFromDerivationPath, getClientKeyShareBackupInfo, getClientKeyShareExportFileName, getGoogleOAuthAccountId, getICloudBackup, getMPCSignatureScheme, getMPCSigner, hasCloudProviderBackup, hasDelegatedBackup, hasEncryptedSharesCached, initializeCloudKit, isBrowser, isHeavyQueueOperation, isHexString, isICloudAuthenticated, isPublicKeyMismatchError, isRecoverQueueOperation, isSignQueueOperation, listICloudBackups, mergeUniqueKeyShares, retryPromise, timeoutPromise };