@dynamic-labs-wallet/browser 0.0.323 → 0.0.324
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 +192 -72
- package/index.esm.js +192 -72
- package/package.json +3 -3
- package/src/backup/encryption/argon2.d.ts +10 -0
- package/src/backup/encryption/argon2.d.ts.map +1 -0
- package/src/backup/encryption/config.d.ts +39 -0
- package/src/backup/encryption/config.d.ts.map +1 -0
- package/src/backup/encryption/constants.d.ts +35 -0
- package/src/backup/encryption/constants.d.ts.map +1 -0
- package/src/backup/encryption/core.d.ts +31 -0
- package/src/backup/encryption/core.d.ts.map +1 -0
- package/src/backup/encryption/pbkdf2.d.ts +10 -0
- package/src/backup/encryption/pbkdf2.d.ts.map +1 -0
- package/src/backup/encryption/types.d.ts +46 -0
- package/src/backup/encryption/types.d.ts.map +1 -0
- package/src/backup/encryption/utils.d.ts +9 -0
- package/src/backup/encryption/utils.d.ts.map +1 -0
- package/src/backup/providers/googleDrive.d.ts +19 -0
- package/src/backup/providers/googleDrive.d.ts.map +1 -0
- package/src/backup/providers/iCloud.d.ts +64 -0
- package/src/backup/providers/iCloud.d.ts.map +1 -0
- package/src/backup/utils.d.ts +23 -0
- package/src/backup/utils.d.ts.map +1 -0
- package/src/client.d.ts +787 -0
- package/src/client.d.ts.map +1 -0
- package/src/constants.d.ts +9 -0
- package/src/constants.d.ts.map +1 -0
- package/src/errorConstants.d.ts +13 -0
- package/src/errorConstants.d.ts.map +1 -0
- package/src/index.d.ts +14 -0
- package/src/index.d.ts.map +1 -0
- package/src/mpc/index.d.ts +5 -0
- package/src/mpc/index.d.ts.map +1 -0
- package/src/mpc/mpc.d.ts +20 -0
- package/src/mpc/mpc.d.ts.map +1 -0
- package/src/mpc/types.d.ts +6 -0
- package/src/mpc/types.d.ts.map +1 -0
- package/src/normalizeAddress.d.ts +7 -0
- package/src/normalizeAddress.d.ts.map +1 -0
- package/src/passwordValidation.d.ts +29 -0
- package/src/passwordValidation.d.ts.map +1 -0
- package/src/queue.d.ts +96 -0
- package/src/queue.d.ts.map +1 -0
- package/src/services/encryption.d.ts +19 -0
- package/src/services/encryption.d.ts.map +1 -0
- package/src/services/localStorage.d.ts +34 -0
- package/src/services/localStorage.d.ts.map +1 -0
- package/src/services/logger.d.ts +6 -0
- package/src/services/logger.d.ts.map +1 -0
- package/src/types.d.ts +129 -0
- package/src/types.d.ts.map +1 -0
- package/src/utils.d.ts +90 -0
- package/src/utils.d.ts.map +1 -0
- package/src/walletState.d.ts +28 -0
- package/src/walletState.d.ts.map +1 -0
package/index.cjs.js
CHANGED
|
@@ -372,6 +372,22 @@ const uploadFileToGoogleDrivePersonal = async ({ accessToken, fileName, jsonData
|
|
|
372
372
|
]
|
|
373
373
|
});
|
|
374
374
|
};
|
|
375
|
+
/**
|
|
376
|
+
* Verifies that a file exists on Google Drive by fetching its metadata
|
|
377
|
+
*/ const verifyUpload = async ({ accessToken, fileId })=>{
|
|
378
|
+
const verifyResponse = await fetch(`${GOOGLE_DRIVE_UPLOAD_API}/drive/v3/files/${fileId}?fields=id,name`, {
|
|
379
|
+
headers: {
|
|
380
|
+
Authorization: `Bearer ${accessToken}`
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
if (!verifyResponse.ok) {
|
|
384
|
+
throw new Error(`Upload verification failed: file ${fileId} not accessible after upload`);
|
|
385
|
+
}
|
|
386
|
+
const verifyResult = await verifyResponse.json();
|
|
387
|
+
if (verifyResult.id !== fileId) {
|
|
388
|
+
throw new Error(`Upload verification failed: expected file ID ${fileId}, got ${verifyResult.id}`);
|
|
389
|
+
}
|
|
390
|
+
};
|
|
375
391
|
const uploadFileToGoogleDrive = async ({ accessToken, fileName, jsonData, parents })=>{
|
|
376
392
|
const metadata = {
|
|
377
393
|
name: fileName,
|
|
@@ -400,6 +416,14 @@ const uploadFileToGoogleDrive = async ({ accessToken, fileName, jsonData, parent
|
|
|
400
416
|
throw new Error('Error uploading file');
|
|
401
417
|
}
|
|
402
418
|
const result = await response.json();
|
|
419
|
+
const fileId = result.id;
|
|
420
|
+
if (!fileId) {
|
|
421
|
+
throw new Error('Upload response missing file ID');
|
|
422
|
+
}
|
|
423
|
+
await verifyUpload({
|
|
424
|
+
accessToken,
|
|
425
|
+
fileId
|
|
426
|
+
});
|
|
403
427
|
return result; // Return file metadata, including file ID
|
|
404
428
|
};
|
|
405
429
|
const listFilesFromGoogleDrive = async ({ accessToken, fileName })=>{
|
|
@@ -554,6 +578,32 @@ const getClientKeyShareBackupInfo = (params)=>{
|
|
|
554
578
|
const timeoutPromise = ({ timeInMs, activity = 'Ceremony' })=>{
|
|
555
579
|
return new Promise((_, reject)=>setTimeout(()=>reject(new Error(`${activity} did not complete in ${timeInMs}ms`)), timeInMs));
|
|
556
580
|
};
|
|
581
|
+
const buildErrorContext = (error)=>{
|
|
582
|
+
var _error_response, _error_response1;
|
|
583
|
+
return {
|
|
584
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
585
|
+
errorStack: error instanceof Error ? error.stack : undefined,
|
|
586
|
+
axiosError: error instanceof axios.AxiosError ? (_error_response = error.response) == null ? void 0 : _error_response.data : undefined,
|
|
587
|
+
axiosStatus: error instanceof axios.AxiosError ? (_error_response1 = error.response) == null ? void 0 : _error_response1.status : undefined
|
|
588
|
+
};
|
|
589
|
+
};
|
|
590
|
+
const logRetrySuccess = (operationName, attempts, logContext)=>{
|
|
591
|
+
core.Logger.info(`Successfully executed ${operationName} after ${attempts + 1} attempts`, _extends({}, logContext, {
|
|
592
|
+
attemptsTaken: attempts + 1
|
|
593
|
+
}));
|
|
594
|
+
};
|
|
595
|
+
const logRetryFailure = (operationName, attempts, maxAttempts, errorContext, logContext)=>{
|
|
596
|
+
core.Logger.warn(`Failed to execute ${operationName} on attempt ${attempts}/${maxAttempts}`, _extends({}, logContext, errorContext, {
|
|
597
|
+
attempt: attempts,
|
|
598
|
+
maxAttempts,
|
|
599
|
+
willRetry: attempts < maxAttempts
|
|
600
|
+
}));
|
|
601
|
+
};
|
|
602
|
+
const logRetryExhausted = (operationName, maxAttempts, errorContext, logContext)=>{
|
|
603
|
+
core.Logger.error(`Failed to execute ${operationName} after ${maxAttempts} attempts - stopping retry`, _extends({}, logContext, errorContext, {
|
|
604
|
+
totalAttempts: maxAttempts
|
|
605
|
+
}));
|
|
606
|
+
};
|
|
557
607
|
/**
|
|
558
608
|
* Generic helper function to retry a promise-based operations
|
|
559
609
|
*
|
|
@@ -565,24 +615,24 @@ const timeoutPromise = ({ timeInMs, activity = 'Ceremony' })=>{
|
|
|
565
615
|
let attempts = 0;
|
|
566
616
|
while(attempts < maxAttempts){
|
|
567
617
|
try {
|
|
568
|
-
|
|
618
|
+
const result = await operation();
|
|
619
|
+
if (attempts > 0) {
|
|
620
|
+
logRetrySuccess(operationName, attempts, logContext);
|
|
621
|
+
}
|
|
622
|
+
return result;
|
|
569
623
|
} catch (error) {
|
|
570
|
-
var _error_response;
|
|
571
624
|
attempts++;
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
axiosError: error instanceof axios.AxiosError ? (_error_response = error.response) == null ? void 0 : _error_response.data : undefined
|
|
575
|
-
}));
|
|
625
|
+
const errorContext = buildErrorContext(error);
|
|
626
|
+
logRetryFailure(operationName, attempts, maxAttempts, errorContext, logContext);
|
|
576
627
|
if (attempts === maxAttempts) {
|
|
577
|
-
|
|
578
|
-
core.Logger.error(`Failed to execute ${operationName} after ${maxAttempts} attempts`, _extends({}, logContext, {
|
|
579
|
-
error: error instanceof Error ? error.message : 'Unknown error',
|
|
580
|
-
axiosError: error instanceof axios.AxiosError ? (_error_response1 = error.response) == null ? void 0 : _error_response1.data : undefined
|
|
581
|
-
}));
|
|
628
|
+
logRetryExhausted(operationName, maxAttempts, errorContext, logContext);
|
|
582
629
|
throw error;
|
|
583
630
|
}
|
|
584
|
-
// Calculate exponential backoff delay
|
|
585
631
|
const exponentialDelay = retryInterval * 2 ** (attempts - 1);
|
|
632
|
+
core.Logger.debug(`Retrying ${operationName} in ${exponentialDelay}ms`, _extends({}, logContext, {
|
|
633
|
+
nextAttempt: attempts + 1,
|
|
634
|
+
delayMs: exponentialDelay
|
|
635
|
+
}));
|
|
586
636
|
await new Promise((resolve)=>setTimeout(resolve, exponentialDelay));
|
|
587
637
|
}
|
|
588
638
|
}
|
|
@@ -1062,49 +1112,81 @@ const initializeCloudKit = async (config, signInButtonId, onSignInRequired, onSi
|
|
|
1062
1112
|
await ensureICloudAuth(onSignInRequired, onSignInComplete, onAuthStatusUpdate, authOptions);
|
|
1063
1113
|
};
|
|
1064
1114
|
|
|
1115
|
+
/**
|
|
1116
|
+
* Extracts error message and stack from an unknown error value
|
|
1117
|
+
*/ const getErrorDetails = (error)=>{
|
|
1118
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1119
|
+
const stack = error instanceof Error ? error.stack : undefined;
|
|
1120
|
+
return {
|
|
1121
|
+
message,
|
|
1122
|
+
stack
|
|
1123
|
+
};
|
|
1124
|
+
};
|
|
1125
|
+
/**
|
|
1126
|
+
* Processes a single upload result and logs appropriately
|
|
1127
|
+
* @returns Error message if failed, undefined if successful
|
|
1128
|
+
*/ const processUploadResult = (result, locationName, logContext, logger)=>{
|
|
1129
|
+
if (result.status === 'fulfilled') {
|
|
1130
|
+
logger.info(`[DynamicWaasWalletClient] Successfully uploaded keyshares to ${locationName}`, logContext);
|
|
1131
|
+
return undefined;
|
|
1132
|
+
}
|
|
1133
|
+
const { message, stack } = getErrorDetails(result.reason);
|
|
1134
|
+
logger.error(`[DynamicWaasWalletClient] Failed to upload keyshares to ${locationName}`, _extends({}, logContext, {
|
|
1135
|
+
error: message,
|
|
1136
|
+
errorStack: stack
|
|
1137
|
+
}));
|
|
1138
|
+
return `Failed to backup keyshares to ${locationName}: ${message}`;
|
|
1139
|
+
};
|
|
1065
1140
|
/**
|
|
1066
1141
|
* Uploads a backup to Google Drive App
|
|
1067
1142
|
* @param accessToken - The access token for the Google Drive API
|
|
1068
1143
|
* @param fileName - The name of the file to upload
|
|
1069
1144
|
* @param backupData - The data to upload
|
|
1070
1145
|
* @param accountAddress - The account address associated with the backup
|
|
1071
|
-
|
|
1146
|
+
* @param walletId - The wallet ID for logging context
|
|
1147
|
+
* @param environmentId - The environment ID for logging context
|
|
1148
|
+
* @param chainName - The chain name for logging context
|
|
1149
|
+
* @param logger - The logger instance to use for logging
|
|
1150
|
+
*/ const uploadBackupToGoogleDrive = async ({ accessToken, fileName, backupData, accountAddress, walletId, environmentId, chainName, logger })=>{
|
|
1151
|
+
const logContext = {
|
|
1152
|
+
accountAddress,
|
|
1153
|
+
walletId,
|
|
1154
|
+
environmentId,
|
|
1155
|
+
chainName,
|
|
1156
|
+
fileName
|
|
1157
|
+
};
|
|
1158
|
+
logger.info('[DynamicWaasWalletClient] Starting Google Drive backup upload', logContext);
|
|
1072
1159
|
const uploadPromises = [
|
|
1073
1160
|
retryPromise(()=>uploadFileToGoogleDriveAppStorage({
|
|
1074
1161
|
accessToken,
|
|
1075
1162
|
fileName,
|
|
1076
1163
|
jsonData: backupData
|
|
1077
|
-
})
|
|
1164
|
+
}), {
|
|
1165
|
+
operationName: 'Google Drive App Storage upload',
|
|
1166
|
+
logContext
|
|
1167
|
+
}),
|
|
1078
1168
|
retryPromise(()=>uploadFileToGoogleDrivePersonal({
|
|
1079
1169
|
accessToken,
|
|
1080
1170
|
fileName,
|
|
1081
1171
|
jsonData: backupData
|
|
1082
|
-
})
|
|
1172
|
+
}), {
|
|
1173
|
+
operationName: 'Google Drive Personal upload',
|
|
1174
|
+
logContext
|
|
1175
|
+
})
|
|
1083
1176
|
];
|
|
1084
1177
|
const results = await Promise.allSettled(uploadPromises);
|
|
1085
|
-
const errors = [
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
core.Logger.error('[DynamicWaasWalletClient] Failed to upload keyshares to Google Drive App Storage', {
|
|
1090
|
-
accountAddress,
|
|
1091
|
-
error
|
|
1092
|
-
});
|
|
1093
|
-
errors.push(`Failed to backup keyshares to Google Drive App Storage: ${error instanceof Error ? error.message : String(error)}`);
|
|
1094
|
-
}
|
|
1095
|
-
// Check Personal Drive result
|
|
1096
|
-
if (results[1].status === 'rejected') {
|
|
1097
|
-
const error = results[1].reason;
|
|
1098
|
-
core.Logger.error('[DynamicWaasWalletClient] Failed to upload keyshares to Google Drive Personal', {
|
|
1099
|
-
accountAddress,
|
|
1100
|
-
error
|
|
1101
|
-
});
|
|
1102
|
-
errors.push(`Failed to backup keyshares to Google Drive Personal: ${error instanceof Error ? error.message : String(error)}`);
|
|
1103
|
-
}
|
|
1104
|
-
// Throw if any uploads failed
|
|
1178
|
+
const errors = [
|
|
1179
|
+
processUploadResult(results[0], 'Google Drive App Storage', logContext, logger),
|
|
1180
|
+
processUploadResult(results[1], 'Google Drive Personal', logContext, logger)
|
|
1181
|
+
].filter((error)=>error !== undefined);
|
|
1105
1182
|
if (errors.length > 0) {
|
|
1183
|
+
logger.error('[DynamicWaasWalletClient] Google Drive backup failed', _extends({}, logContext, {
|
|
1184
|
+
errorCount: errors.length,
|
|
1185
|
+
errors
|
|
1186
|
+
}));
|
|
1106
1187
|
throw new Error(`[DynamicWaasWalletClient] ${errors.join('; ')}`);
|
|
1107
1188
|
}
|
|
1189
|
+
logger.info('[DynamicWaasWalletClient] Google Drive backup completed successfully', logContext);
|
|
1108
1190
|
};
|
|
1109
1191
|
|
|
1110
1192
|
const ERROR_PASSWORD_MISMATCH = '[DynamicWaasWalletClient]: Password does not match the password used for existing wallets. All wallets must use the same password for encrypted backups.';
|
|
@@ -2476,6 +2558,17 @@ class DynamicWalletClient {
|
|
|
2476
2558
|
}, this.getTraceContext(traceContext)));
|
|
2477
2559
|
}
|
|
2478
2560
|
}
|
|
2561
|
+
// Create a rejection handler that will be wired up synchronously below.
|
|
2562
|
+
// Promise executors run synchronously, so rejectOnSSEError is guaranteed
|
|
2563
|
+
// to be assigned before serverSign is called.
|
|
2564
|
+
let rejectOnSSEError;
|
|
2565
|
+
const sseErrorPromise = new Promise((_, reject)=>{
|
|
2566
|
+
rejectOnSSEError = reject;
|
|
2567
|
+
});
|
|
2568
|
+
// Prevent unhandled rejection if SSE errors before serverSignPromise resolves
|
|
2569
|
+
// (sseErrorPromise would never reach Promise.race in that path)
|
|
2570
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
2571
|
+
sseErrorPromise.catch(()=>{});
|
|
2479
2572
|
// Perform the server sign
|
|
2480
2573
|
const serverSignPromise = this.serverSign({
|
|
2481
2574
|
walletId: wallet.walletId,
|
|
@@ -2485,7 +2578,10 @@ class DynamicWalletClient {
|
|
|
2485
2578
|
elevatedAccessToken,
|
|
2486
2579
|
roomId,
|
|
2487
2580
|
context,
|
|
2488
|
-
onError
|
|
2581
|
+
onError: (error)=>{
|
|
2582
|
+
onError == null ? void 0 : onError(error);
|
|
2583
|
+
rejectOnSSEError(error);
|
|
2584
|
+
},
|
|
2489
2585
|
dynamicRequestId,
|
|
2490
2586
|
traceContext,
|
|
2491
2587
|
bitcoinConfig
|
|
@@ -2503,7 +2599,10 @@ class DynamicWalletClient {
|
|
|
2503
2599
|
}, this.getTraceContext(traceContext)));
|
|
2504
2600
|
let signature;
|
|
2505
2601
|
try {
|
|
2506
|
-
|
|
2602
|
+
// Race clientSign against SSE errors so that server-side failures
|
|
2603
|
+
// (e.g. policy violations) immediately reject instead of hanging
|
|
2604
|
+
// until viem's task queue timeout.
|
|
2605
|
+
const clientSignPromise = this.clientSign({
|
|
2507
2606
|
chainName,
|
|
2508
2607
|
message,
|
|
2509
2608
|
roomId,
|
|
@@ -2514,6 +2613,15 @@ class DynamicWalletClient {
|
|
|
2514
2613
|
traceContext,
|
|
2515
2614
|
bitcoinConfig
|
|
2516
2615
|
});
|
|
2616
|
+
// Prevent unhandled rejection from the losing promise in the race:
|
|
2617
|
+
// if sseErrorPromise wins, clientSign keeps running and will eventually
|
|
2618
|
+
// reject (MPC timeout); if clientSign wins, sseErrorPromise may never settle.
|
|
2619
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
2620
|
+
clientSignPromise.catch(()=>{});
|
|
2621
|
+
signature = await Promise.race([
|
|
2622
|
+
clientSignPromise,
|
|
2623
|
+
sseErrorPromise
|
|
2624
|
+
]);
|
|
2517
2625
|
} catch (signError) {
|
|
2518
2626
|
// If public key mismatch and haven't tried recovery yet, recover and retry entire operation
|
|
2519
2627
|
if (!hasAttemptedKeyShareRecovery) {
|
|
@@ -3569,11 +3677,28 @@ class DynamicWalletClient {
|
|
|
3569
3677
|
}
|
|
3570
3678
|
async backupSharesWithDistribution({ accountAddress, password, signedSessionId, distribution, preserveDelegatedLocation = false, passwordUpdateBatchId }) {
|
|
3571
3679
|
const dynamicRequestId = uuid.v4();
|
|
3680
|
+
// Get wallet data early for logging context (also used in catch block)
|
|
3681
|
+
const walletData = this.getWalletFromMap(accountAddress);
|
|
3682
|
+
// Common context for all logs in this method
|
|
3683
|
+
const logContext = {
|
|
3684
|
+
accountAddress,
|
|
3685
|
+
dynamicRequestId,
|
|
3686
|
+
walletId: walletData == null ? void 0 : walletData.walletId,
|
|
3687
|
+
userId: this.userId,
|
|
3688
|
+
environmentId: this.environmentId
|
|
3689
|
+
};
|
|
3690
|
+
this.logger.info('[backupSharesWithDistribution] Starting backup', _extends({}, logContext, {
|
|
3691
|
+
hasPassword: !!password,
|
|
3692
|
+
preserveDelegatedLocation,
|
|
3693
|
+
passwordUpdateBatchId,
|
|
3694
|
+
dynamicShareCount: distribution.clientShares.length,
|
|
3695
|
+
cloudProviders: Object.keys(distribution.cloudProviderShares),
|
|
3696
|
+
hasDelegatedShare: !!distribution.delegatedShare
|
|
3697
|
+
}));
|
|
3572
3698
|
try {
|
|
3573
|
-
var _backupData_locationsWithKeyShares;
|
|
3699
|
+
var _backupData_locationsWithKeyShares, _backupData_locationsWithKeyShares1;
|
|
3574
3700
|
// Resolve signed session ID lazily once, so all downstream calls receive a string.
|
|
3575
3701
|
const resolvedSignedSessionId = await this.resolveSignedSessionId(signedSessionId);
|
|
3576
|
-
const walletData = this.getWalletFromMap(accountAddress);
|
|
3577
3702
|
if (!(walletData == null ? void 0 : walletData.walletId)) {
|
|
3578
3703
|
const error = new Error(`WalletId not found for accountAddress ${accountAddress}`);
|
|
3579
3704
|
logError({
|
|
@@ -3597,13 +3722,11 @@ class DynamicWalletClient {
|
|
|
3597
3722
|
maxAttempts: 3,
|
|
3598
3723
|
operationName: 'encrypt key share'
|
|
3599
3724
|
});
|
|
3600
|
-
this.logger.debug('[backupSharesWithDistribution] Pre-encrypting shares', {
|
|
3725
|
+
this.logger.debug('[backupSharesWithDistribution] Pre-encrypting shares', _extends({}, logContext, {
|
|
3601
3726
|
dynamicShareCount: distribution.clientShares.length,
|
|
3602
3727
|
cloudProviders: Object.keys(distribution.cloudProviderShares),
|
|
3603
|
-
hasDelegatedShare: !!distribution.delegatedShare
|
|
3604
|
-
|
|
3605
|
-
dynamicRequestId
|
|
3606
|
-
});
|
|
3728
|
+
hasDelegatedShare: !!distribution.delegatedShare
|
|
3729
|
+
}));
|
|
3607
3730
|
const preEncryptedDynamicShares = distribution.clientShares.length > 0 ? await Promise.all(distribution.clientShares.map(encryptWithRetry)) : [];
|
|
3608
3731
|
const cloudEntries = Object.entries(distribution.cloudProviderShares).filter(([, shares])=>shares && shares.length > 0);
|
|
3609
3732
|
const preEncryptedCloudShares = await Promise.all(cloudEntries.map(async ([provider, shares])=>({
|
|
@@ -3611,12 +3734,10 @@ class DynamicWalletClient {
|
|
|
3611
3734
|
shares: shares,
|
|
3612
3735
|
encrypted: await Promise.all(shares.map(encryptWithRetry))
|
|
3613
3736
|
})));
|
|
3614
|
-
this.logger.debug('[backupSharesWithDistribution] Encryption complete, starting uploads', {
|
|
3737
|
+
this.logger.debug('[backupSharesWithDistribution] Encryption complete, starting uploads', _extends({}, logContext, {
|
|
3615
3738
|
dynamicShareCount: preEncryptedDynamicShares.length,
|
|
3616
|
-
cloudProviderCount: preEncryptedCloudShares.length
|
|
3617
|
-
|
|
3618
|
-
dynamicRequestId
|
|
3619
|
-
});
|
|
3739
|
+
cloudProviderCount: preEncryptedCloudShares.length
|
|
3740
|
+
}));
|
|
3620
3741
|
// Step 1: Upload shares in parallel, each with its own retry
|
|
3621
3742
|
const uploadPromises = [];
|
|
3622
3743
|
if (distribution.clientShares.length > 0) {
|
|
@@ -3665,12 +3786,10 @@ class DynamicWalletClient {
|
|
|
3665
3786
|
}
|
|
3666
3787
|
const uploadResults = await Promise.all(uploadPromises);
|
|
3667
3788
|
const locations = uploadResults.filter((loc)=>loc !== undefined);
|
|
3668
|
-
this.logger.
|
|
3789
|
+
this.logger.info('[backupSharesWithDistribution] Uploads complete, activating shares on server', _extends({}, logContext, {
|
|
3669
3790
|
locationCount: locations.length,
|
|
3670
|
-
locations: locations.map((l)=>l.location)
|
|
3671
|
-
|
|
3672
|
-
dynamicRequestId
|
|
3673
|
-
});
|
|
3791
|
+
locations: locations.map((l)=>l.location)
|
|
3792
|
+
}));
|
|
3674
3793
|
// Preserve existing delegated location
|
|
3675
3794
|
if (preserveDelegatedLocation && !distribution.delegatedShare) {
|
|
3676
3795
|
const location = this.createPreservedDelegatedLocation({
|
|
@@ -3690,10 +3809,7 @@ class DynamicWalletClient {
|
|
|
3690
3809
|
});
|
|
3691
3810
|
// For password update pending responses, skip walletMap update — shares aren't active yet
|
|
3692
3811
|
if (backupData.passwordUpdateStatus === 'pending') {
|
|
3693
|
-
this.logger.debug('[backupSharesWithDistribution] Password update pending, skipping walletMap update',
|
|
3694
|
-
accountAddress,
|
|
3695
|
-
dynamicRequestId
|
|
3696
|
-
});
|
|
3812
|
+
this.logger.debug('[backupSharesWithDistribution] Password update pending, skipping walletMap update', logContext);
|
|
3697
3813
|
return backupData;
|
|
3698
3814
|
}
|
|
3699
3815
|
if (passwordUpdateBatchId) {
|
|
@@ -3707,11 +3823,11 @@ class DynamicWalletClient {
|
|
|
3707
3823
|
preEncryptedDynamicShares
|
|
3708
3824
|
});
|
|
3709
3825
|
}
|
|
3710
|
-
var
|
|
3826
|
+
var _backupData_locationsWithKeyShares2;
|
|
3711
3827
|
const updatedBackupInfo = getClientKeyShareBackupInfo({
|
|
3712
3828
|
walletProperties: {
|
|
3713
3829
|
derivationPath: walletData.derivationPath,
|
|
3714
|
-
keyShares: ((
|
|
3830
|
+
keyShares: ((_backupData_locationsWithKeyShares2 = backupData.locationsWithKeyShares) != null ? _backupData_locationsWithKeyShares2 : []).map((ks)=>({
|
|
3715
3831
|
id: ks.id,
|
|
3716
3832
|
keygenId: ks.keygenId,
|
|
3717
3833
|
backupLocation: ks.location,
|
|
@@ -3725,21 +3841,20 @@ class DynamicWalletClient {
|
|
|
3725
3841
|
clientKeySharesBackupInfo: updatedBackupInfo
|
|
3726
3842
|
});
|
|
3727
3843
|
await this.storage.setItem(this.storageKey, JSON.stringify(this.walletMap));
|
|
3728
|
-
var _backupData_locationsWithKeyShares_length;
|
|
3729
|
-
this.logger.
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
});
|
|
3844
|
+
var _backupData_locationsWithKeyShares_length, _backupData_locationsWithKeyShares_map;
|
|
3845
|
+
this.logger.info('[backupSharesWithDistribution] Backup complete', _extends({}, logContext, {
|
|
3846
|
+
locationCount: (_backupData_locationsWithKeyShares_length = (_backupData_locationsWithKeyShares = backupData.locationsWithKeyShares) == null ? void 0 : _backupData_locationsWithKeyShares.length) != null ? _backupData_locationsWithKeyShares_length : 0,
|
|
3847
|
+
locations: (_backupData_locationsWithKeyShares_map = (_backupData_locationsWithKeyShares1 = backupData.locationsWithKeyShares) == null ? void 0 : _backupData_locationsWithKeyShares1.map((ks)=>ks.location)) != null ? _backupData_locationsWithKeyShares_map : []
|
|
3848
|
+
}));
|
|
3734
3849
|
return backupData;
|
|
3735
3850
|
} catch (error) {
|
|
3736
3851
|
logError({
|
|
3737
3852
|
message: 'Error in backupSharesWithDistribution',
|
|
3738
3853
|
error: error,
|
|
3739
|
-
context: {
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
}
|
|
3854
|
+
context: _extends({}, logContext, {
|
|
3855
|
+
chainName: walletData == null ? void 0 : walletData.chainName,
|
|
3856
|
+
errorStack: error instanceof Error ? error.stack : undefined
|
|
3857
|
+
})
|
|
3743
3858
|
});
|
|
3744
3859
|
throw error;
|
|
3745
3860
|
}
|
|
@@ -4350,7 +4465,8 @@ class DynamicWalletClient {
|
|
|
4350
4465
|
const accessToken = await this.apiClient.getAccessToken({
|
|
4351
4466
|
oauthAccountId
|
|
4352
4467
|
});
|
|
4353
|
-
const
|
|
4468
|
+
const walletData = this.getWalletFromMap(accountAddress);
|
|
4469
|
+
const thresholdSignatureScheme = walletData.thresholdSignatureScheme;
|
|
4354
4470
|
const fileName = getClientKeyShareExportFileName({
|
|
4355
4471
|
thresholdSignatureScheme,
|
|
4356
4472
|
accountAddress,
|
|
@@ -4365,7 +4481,11 @@ class DynamicWalletClient {
|
|
|
4365
4481
|
accessToken,
|
|
4366
4482
|
fileName,
|
|
4367
4483
|
backupData,
|
|
4368
|
-
accountAddress
|
|
4484
|
+
accountAddress,
|
|
4485
|
+
walletId: walletData == null ? void 0 : walletData.walletId,
|
|
4486
|
+
environmentId: this.environmentId,
|
|
4487
|
+
chainName: walletData == null ? void 0 : walletData.chainName,
|
|
4488
|
+
logger: this.logger
|
|
4369
4489
|
});
|
|
4370
4490
|
return;
|
|
4371
4491
|
} catch (error) {
|