@dynamic-labs-wallet/browser 0.0.240 → 0.0.241
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 +217 -148
- package/index.esm.js +213 -145
- package/package.json +2 -2
- package/src/client.d.ts +39 -12
- package/src/client.d.ts.map +1 -1
- package/src/types.d.ts +36 -15
- package/src/types.d.ts.map +1 -1
package/index.cjs.js
CHANGED
|
@@ -715,10 +715,7 @@ const configureCloudKit = (config, signInButtonId)=>{
|
|
|
715
715
|
apiTokenAuth: {
|
|
716
716
|
apiToken: config.apiToken,
|
|
717
717
|
persist: true,
|
|
718
|
-
signInButton:
|
|
719
|
-
id: signInButtonId,
|
|
720
|
-
theme: 'black'
|
|
721
|
-
} : undefined
|
|
718
|
+
signInButton: undefined
|
|
722
719
|
}
|
|
723
720
|
};
|
|
724
721
|
CloudKit.configure({
|
|
@@ -727,10 +724,6 @@ const configureCloudKit = (config, signInButtonId)=>{
|
|
|
727
724
|
]
|
|
728
725
|
});
|
|
729
726
|
cloudKitConfigured = true;
|
|
730
|
-
currentSignInButtonId = signInButtonId || null;
|
|
731
|
-
};
|
|
732
|
-
const resetCloudKitConfig = ()=>{
|
|
733
|
-
cloudKitConfigured = false;
|
|
734
727
|
currentSignInButtonId = null;
|
|
735
728
|
};
|
|
736
729
|
/**
|
|
@@ -961,9 +954,6 @@ const ensureICloudAuth = async (onSignInRequired, onSignInComplete, onAuthStatus
|
|
|
961
954
|
};
|
|
962
955
|
const initializeCloudKit = async (config, signInButtonId, onSignInRequired, onSignInComplete, onAuthStatusUpdate, authOptions)=>{
|
|
963
956
|
await loadCloudKit();
|
|
964
|
-
if (signInButtonId) {
|
|
965
|
-
resetCloudKitConfig();
|
|
966
|
-
}
|
|
967
957
|
configureCloudKit(config, signInButtonId);
|
|
968
958
|
await ensureICloudAuth(onSignInRequired, onSignInComplete, onAuthStatusUpdate);
|
|
969
959
|
};
|
|
@@ -1168,42 +1158,82 @@ class WalletBusyError extends Error {
|
|
|
1168
1158
|
this.accountAddress = accountAddress;
|
|
1169
1159
|
}
|
|
1170
1160
|
}
|
|
1171
|
-
|
|
1161
|
+
/**
|
|
1162
|
+
* Creates distribution where shares go to specified cloud providers
|
|
1163
|
+
* Last share goes to cloud providers, rest to Dynamic backend
|
|
1164
|
+
* @param providers - Array of cloud providers to backup to
|
|
1165
|
+
* @param allShares - All key shares to distribute
|
|
1166
|
+
*/ const createCloudProviderDistribution = ({ providers, allShares })=>{
|
|
1167
|
+
const cloudProviderShares = {};
|
|
1168
|
+
// Last share goes to cloud providers, rest to Dynamic
|
|
1169
|
+
const sharesForCloud = allShares.slice(-1);
|
|
1170
|
+
providers.forEach((provider)=>{
|
|
1171
|
+
cloudProviderShares[provider] = sharesForCloud;
|
|
1172
|
+
});
|
|
1173
|
+
return {
|
|
1174
|
+
clientShares: allShares.slice(0, -1),
|
|
1175
|
+
cloudProviderShares
|
|
1176
|
+
};
|
|
1177
|
+
};
|
|
1178
|
+
/**
|
|
1179
|
+
* Creates distribution with delegation + cloud backup
|
|
1180
|
+
* Client shares backed up to Dynamic AND cloud providers
|
|
1181
|
+
* Delegated share goes to webhook
|
|
1182
|
+
*/ const createDelegationWithCloudProviderDistribution = ({ providers, existingShares, delegatedShare })=>{
|
|
1183
|
+
const cloudProviderShares = {};
|
|
1184
|
+
providers.forEach((provider)=>{
|
|
1185
|
+
cloudProviderShares[provider] = existingShares;
|
|
1186
|
+
});
|
|
1187
|
+
return {
|
|
1172
1188
|
clientShares: existingShares,
|
|
1173
|
-
|
|
1189
|
+
cloudProviderShares,
|
|
1174
1190
|
delegatedShare
|
|
1191
|
+
};
|
|
1192
|
+
};
|
|
1193
|
+
/**
|
|
1194
|
+
* Creates distribution for adding cloud backup to existing delegation
|
|
1195
|
+
* Client shares go to both Dynamic AND cloud providers
|
|
1196
|
+
* delegatedShare is undefined - we don't re-publish, but preserve the location
|
|
1197
|
+
*/ const createAddCloudProviderToExistingDelegationDistribution = ({ providers, clientShares })=>{
|
|
1198
|
+
const cloudProviderShares = {};
|
|
1199
|
+
providers.forEach((provider)=>{
|
|
1200
|
+
cloudProviderShares[provider] = clientShares;
|
|
1201
|
+
});
|
|
1202
|
+
return {
|
|
1203
|
+
clientShares,
|
|
1204
|
+
cloudProviderShares
|
|
1205
|
+
};
|
|
1206
|
+
};
|
|
1207
|
+
/**
|
|
1208
|
+
* Checks if wallet has backup on any of the specified providers
|
|
1209
|
+
*/ const hasCloudProviderBackup = (backupInfo, providers)=>{
|
|
1210
|
+
if (!(backupInfo == null ? void 0 : backupInfo.backups)) return false;
|
|
1211
|
+
return providers.some((provider)=>{
|
|
1212
|
+
var _backupInfo_backups_provider;
|
|
1213
|
+
var _backupInfo_backups_provider_length;
|
|
1214
|
+
return ((_backupInfo_backups_provider_length = (_backupInfo_backups_provider = backupInfo.backups[provider]) == null ? void 0 : _backupInfo_backups_provider.length) != null ? _backupInfo_backups_provider_length : 0) > 0;
|
|
1175
1215
|
});
|
|
1216
|
+
};
|
|
1217
|
+
/**
|
|
1218
|
+
* Gets all cloud providers that have backups for this wallet
|
|
1219
|
+
*/ const getActiveCloudProviders = (backupInfo)=>{
|
|
1220
|
+
if (!(backupInfo == null ? void 0 : backupInfo.backups)) return [];
|
|
1221
|
+
return Object.entries(backupInfo.backups).filter(([location, backups])=>location !== core.BackupLocation.DYNAMIC && location !== core.BackupLocation.DELEGATED && backups.length > 0).map(([location])=>location);
|
|
1222
|
+
};
|
|
1176
1223
|
const createDelegationOnlyDistribution = ({ existingShares, delegatedShare })=>({
|
|
1177
1224
|
clientShares: existingShares,
|
|
1178
|
-
|
|
1225
|
+
cloudProviderShares: {},
|
|
1179
1226
|
delegatedShare
|
|
1180
1227
|
});
|
|
1181
|
-
const createGoogleDriveOnlyDistribution = ({ allShares })=>({
|
|
1182
|
-
clientShares: allShares.slice(0, -1),
|
|
1183
|
-
googleDriveShares: allShares.slice(-1)
|
|
1184
|
-
});
|
|
1185
1228
|
const createDynamicOnlyDistribution = ({ allShares })=>({
|
|
1186
1229
|
clientShares: allShares,
|
|
1187
|
-
|
|
1230
|
+
cloudProviderShares: {}
|
|
1188
1231
|
});
|
|
1189
|
-
const hasGoogleDriveBackup = (backupInfo)=>{
|
|
1190
|
-
var _backupInfo_backups_BackupLocation_GOOGLE_DRIVE, _backupInfo_backups;
|
|
1191
|
-
var _backupInfo_backups_BackupLocation_GOOGLE_DRIVE_length;
|
|
1192
|
-
return ((_backupInfo_backups_BackupLocation_GOOGLE_DRIVE_length = backupInfo == null ? void 0 : (_backupInfo_backups = backupInfo.backups) == null ? void 0 : (_backupInfo_backups_BackupLocation_GOOGLE_DRIVE = _backupInfo_backups[core.BackupLocation.GOOGLE_DRIVE]) == null ? void 0 : _backupInfo_backups_BackupLocation_GOOGLE_DRIVE.length) != null ? _backupInfo_backups_BackupLocation_GOOGLE_DRIVE_length : 0) > 0;
|
|
1193
|
-
};
|
|
1194
1232
|
const hasDelegatedBackup = (backupInfo)=>{
|
|
1195
1233
|
var _backupInfo_backups_BackupLocation_DELEGATED, _backupInfo_backups;
|
|
1196
1234
|
var _backupInfo_backups_BackupLocation_DELEGATED_length;
|
|
1197
1235
|
return ((_backupInfo_backups_BackupLocation_DELEGATED_length = backupInfo == null ? void 0 : (_backupInfo_backups = backupInfo.backups) == null ? void 0 : (_backupInfo_backups_BackupLocation_DELEGATED = _backupInfo_backups[core.BackupLocation.DELEGATED]) == null ? void 0 : _backupInfo_backups_BackupLocation_DELEGATED.length) != null ? _backupInfo_backups_BackupLocation_DELEGATED_length : 0) > 0;
|
|
1198
1236
|
};
|
|
1199
|
-
/**
|
|
1200
|
-
* Distribution for adding Google Drive backup to an existing delegation.
|
|
1201
|
-
* Client's shares go to both Dynamic and Google Drive.
|
|
1202
|
-
* delegatedShare is undefined - we don't re-publish, but preserve the location.
|
|
1203
|
-
*/ const createAddGoogleDriveToExistingDelegationDistribution = ({ clientShares })=>({
|
|
1204
|
-
clientShares: clientShares,
|
|
1205
|
-
googleDriveShares: clientShares
|
|
1206
|
-
});
|
|
1207
1237
|
|
|
1208
1238
|
// eslint-disable-next-line @nx/enforce-module-boundaries
|
|
1209
1239
|
class DynamicWalletClient {
|
|
@@ -1972,7 +2002,7 @@ class DynamicWalletClient {
|
|
|
1972
2002
|
existingClientKeyShares
|
|
1973
2003
|
};
|
|
1974
2004
|
}
|
|
1975
|
-
async reshare({ chainName, accountAddress, oldThresholdSignatureScheme, newThresholdSignatureScheme, password = undefined, signedSessionId,
|
|
2005
|
+
async reshare({ chainName, accountAddress, oldThresholdSignatureScheme, newThresholdSignatureScheme, password = undefined, signedSessionId, cloudProviders = [], delegateToProjectEnvironment = false, mfaToken, revokeDelegation = false }) {
|
|
1976
2006
|
return this.withWalletBusyLock({
|
|
1977
2007
|
accountAddress,
|
|
1978
2008
|
operation: core.WalletOperation.RESHARE,
|
|
@@ -1983,14 +2013,14 @@ class DynamicWalletClient {
|
|
|
1983
2013
|
newThresholdSignatureScheme,
|
|
1984
2014
|
password,
|
|
1985
2015
|
signedSessionId,
|
|
1986
|
-
|
|
2016
|
+
cloudProviders,
|
|
1987
2017
|
delegateToProjectEnvironment,
|
|
1988
2018
|
mfaToken,
|
|
1989
2019
|
revokeDelegation
|
|
1990
2020
|
})
|
|
1991
2021
|
});
|
|
1992
2022
|
}
|
|
1993
|
-
async internalReshare({ chainName, accountAddress, oldThresholdSignatureScheme, newThresholdSignatureScheme, password = undefined, signedSessionId,
|
|
2023
|
+
async internalReshare({ chainName, accountAddress, oldThresholdSignatureScheme, newThresholdSignatureScheme, password = undefined, signedSessionId, cloudProviders = [], delegateToProjectEnvironment = false, mfaToken, revokeDelegation = false }) {
|
|
1994
2024
|
const dynamicRequestId = uuid.v4();
|
|
1995
2025
|
try {
|
|
1996
2026
|
await this.verifyPassword({
|
|
@@ -2057,28 +2087,31 @@ class DynamicWalletClient {
|
|
|
2057
2087
|
...newReshareResults
|
|
2058
2088
|
];
|
|
2059
2089
|
let distribution;
|
|
2060
|
-
|
|
2061
|
-
|
|
2090
|
+
// Generic distribution logic - works with any cloud providers
|
|
2091
|
+
if (delegateToProjectEnvironment && cloudProviders.length > 0) {
|
|
2092
|
+
// Delegation + Cloud Providers: Client's existing share backs up to both Dynamic and cloud providers.
|
|
2062
2093
|
// The new share goes to the webhook for delegation.
|
|
2063
|
-
distribution =
|
|
2094
|
+
distribution = createDelegationWithCloudProviderDistribution({
|
|
2095
|
+
providers: cloudProviders,
|
|
2064
2096
|
existingShares: existingReshareResults,
|
|
2065
2097
|
delegatedShare: newReshareResults[0]
|
|
2066
2098
|
});
|
|
2067
2099
|
} else if (delegateToProjectEnvironment) {
|
|
2068
2100
|
// Delegation only: Client's existing share backs up to Dynamic.
|
|
2069
|
-
// The new share goes to the webhook for delegation. No
|
|
2101
|
+
// The new share goes to the webhook for delegation. No cloud provider backup.
|
|
2070
2102
|
distribution = createDelegationOnlyDistribution({
|
|
2071
2103
|
existingShares: existingReshareResults,
|
|
2072
2104
|
delegatedShare: newReshareResults[0]
|
|
2073
2105
|
});
|
|
2074
|
-
} else if (
|
|
2075
|
-
//
|
|
2076
|
-
// The last share (new share) goes to
|
|
2077
|
-
distribution =
|
|
2106
|
+
} else if (cloudProviders.length > 0) {
|
|
2107
|
+
// Cloud Providers only: Split shares between Dynamic (N-1) and cloud providers (1).
|
|
2108
|
+
// The last share (new share) goes to cloud providers.
|
|
2109
|
+
distribution = createCloudProviderDistribution({
|
|
2110
|
+
providers: cloudProviders,
|
|
2078
2111
|
allShares: allClientShares
|
|
2079
2112
|
});
|
|
2080
2113
|
} else {
|
|
2081
|
-
// No delegation, no
|
|
2114
|
+
// No delegation, no cloud providers: All shares go to Dynamic backend only.
|
|
2082
2115
|
distribution = createDynamicOnlyDistribution({
|
|
2083
2116
|
allShares: allClientShares
|
|
2084
2117
|
});
|
|
@@ -2106,7 +2139,7 @@ class DynamicWalletClient {
|
|
|
2106
2139
|
chainName,
|
|
2107
2140
|
oldThresholdSignatureScheme,
|
|
2108
2141
|
newThresholdSignatureScheme,
|
|
2109
|
-
|
|
2142
|
+
cloudProviders,
|
|
2110
2143
|
dynamicRequestId
|
|
2111
2144
|
}
|
|
2112
2145
|
});
|
|
@@ -2139,6 +2172,8 @@ class DynamicWalletClient {
|
|
|
2139
2172
|
throw new Error('Delegation is not allowed for SUI');
|
|
2140
2173
|
}
|
|
2141
2174
|
const currentThresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
|
|
2175
|
+
// Get active cloud providers to maintain existing backups
|
|
2176
|
+
const activeProviders = getActiveCloudProviders((_this_walletMap_accountAddress = this.walletMap[accountAddress]) == null ? void 0 : _this_walletMap_accountAddress.clientKeySharesBackupInfo);
|
|
2142
2177
|
await this.reshare({
|
|
2143
2178
|
chainName: this.walletMap[accountAddress].chainName,
|
|
2144
2179
|
accountAddress,
|
|
@@ -2146,7 +2181,7 @@ class DynamicWalletClient {
|
|
|
2146
2181
|
newThresholdSignatureScheme,
|
|
2147
2182
|
password,
|
|
2148
2183
|
signedSessionId,
|
|
2149
|
-
|
|
2184
|
+
cloudProviders: activeProviders,
|
|
2150
2185
|
delegateToProjectEnvironment: true,
|
|
2151
2186
|
mfaToken,
|
|
2152
2187
|
revokeDelegation
|
|
@@ -2445,17 +2480,21 @@ class DynamicWalletClient {
|
|
|
2445
2480
|
externalKeyShareId: data.keyShareIds[0]
|
|
2446
2481
|
});
|
|
2447
2482
|
}
|
|
2448
|
-
|
|
2449
|
-
|
|
2483
|
+
// Handle all cloud provider backups generically
|
|
2484
|
+
for (const [provider, shares] of Object.entries(distribution.cloudProviderShares)){
|
|
2485
|
+
if (!shares || shares.length === 0) continue;
|
|
2486
|
+
const backupLocation = provider;
|
|
2487
|
+
const encryptedCloudShares = await Promise.all(shares.map((keyShare)=>this.encryptKeyShare({
|
|
2450
2488
|
keyShare,
|
|
2451
2489
|
password
|
|
2452
2490
|
})));
|
|
2453
|
-
await this.
|
|
2491
|
+
await this.uploadToCloudProvider({
|
|
2492
|
+
provider: backupLocation,
|
|
2454
2493
|
accountAddress,
|
|
2455
|
-
encryptedKeyShares:
|
|
2494
|
+
encryptedKeyShares: encryptedCloudShares
|
|
2456
2495
|
});
|
|
2457
2496
|
locations.push({
|
|
2458
|
-
location:
|
|
2497
|
+
location: backupLocation
|
|
2459
2498
|
});
|
|
2460
2499
|
}
|
|
2461
2500
|
if (distribution.delegatedShare) {
|
|
@@ -2552,44 +2591,52 @@ class DynamicWalletClient {
|
|
|
2552
2591
|
* @param params.signedSessionId - Optional signed session ID for authentication
|
|
2553
2592
|
* @param params.backupToGoogleDrive - Whether to backup to Google Drive (defaults to false)
|
|
2554
2593
|
* @returns Promise with backup metadata including share locations and IDs
|
|
2555
|
-
*/ async storeEncryptedBackupByWallet({ accountAddress, clientKeyShares = undefined, password = undefined, signedSessionId,
|
|
2594
|
+
*/ async storeEncryptedBackupByWallet({ accountAddress, clientKeyShares = undefined, password = undefined, signedSessionId, cloudProviders = [], delegatedKeyshare = undefined }) {
|
|
2556
2595
|
var _this_walletMap_accountAddress, _this_walletMap_accountAddress1;
|
|
2557
2596
|
const keySharesToBackup = clientKeyShares != null ? clientKeyShares : await this.getClientKeySharesFromLocalStorage({
|
|
2558
2597
|
accountAddress
|
|
2559
2598
|
});
|
|
2560
|
-
|
|
2599
|
+
// Check if we should backup to cloud providers (either requested or already exists)
|
|
2600
|
+
const activeCloudProviders = getActiveCloudProviders((_this_walletMap_accountAddress = this.walletMap[accountAddress]) == null ? void 0 : _this_walletMap_accountAddress.clientKeySharesBackupInfo);
|
|
2601
|
+
const shouldBackupToCloudProviders = cloudProviders.length > 0 || activeCloudProviders.length > 0;
|
|
2602
|
+
// Use requested providers, or fall back to existing active providers
|
|
2603
|
+
const providersToBackup = cloudProviders.length > 0 ? cloudProviders : activeCloudProviders;
|
|
2561
2604
|
const hasExistingDelegation = hasDelegatedBackup((_this_walletMap_accountAddress1 = this.walletMap[accountAddress]) == null ? void 0 : _this_walletMap_accountAddress1.clientKeySharesBackupInfo);
|
|
2562
2605
|
let distribution;
|
|
2563
2606
|
let preserveDelegatedLocation = false;
|
|
2564
|
-
|
|
2565
|
-
|
|
2607
|
+
// Generic distribution logic - works with any cloud providers
|
|
2608
|
+
if (delegatedKeyshare && shouldBackupToCloudProviders) {
|
|
2609
|
+
// NEW delegation + Cloud Providers: Client's shares back up to both Dynamic and cloud providers.
|
|
2566
2610
|
// The delegated share goes to the webhook.
|
|
2567
|
-
distribution =
|
|
2611
|
+
distribution = createDelegationWithCloudProviderDistribution({
|
|
2612
|
+
providers: providersToBackup,
|
|
2568
2613
|
existingShares: keySharesToBackup,
|
|
2569
2614
|
delegatedShare: delegatedKeyshare
|
|
2570
2615
|
});
|
|
2571
2616
|
} else if (delegatedKeyshare) {
|
|
2572
2617
|
// NEW delegation only: Client's shares back up to Dynamic.
|
|
2573
|
-
// The delegated share goes to the webhook. No
|
|
2618
|
+
// The delegated share goes to the webhook. No cloud provider backup.
|
|
2574
2619
|
distribution = createDelegationOnlyDistribution({
|
|
2575
2620
|
existingShares: keySharesToBackup,
|
|
2576
2621
|
delegatedShare: delegatedKeyshare
|
|
2577
2622
|
});
|
|
2578
|
-
} else if (hasExistingDelegation &&
|
|
2579
|
-
// ADD
|
|
2623
|
+
} else if (hasExistingDelegation && shouldBackupToCloudProviders) {
|
|
2624
|
+
// ADD Cloud Providers to EXISTING delegation: Client's share backs up to both Dynamic and cloud providers.
|
|
2580
2625
|
// Don't re-publish delegated share, just preserve the location.
|
|
2581
|
-
distribution =
|
|
2626
|
+
distribution = createAddCloudProviderToExistingDelegationDistribution({
|
|
2627
|
+
providers: providersToBackup,
|
|
2582
2628
|
clientShares: keySharesToBackup
|
|
2583
2629
|
});
|
|
2584
2630
|
preserveDelegatedLocation = true;
|
|
2585
|
-
} else if (
|
|
2586
|
-
//
|
|
2587
|
-
// The last share (new share) goes to
|
|
2588
|
-
distribution =
|
|
2631
|
+
} else if (shouldBackupToCloudProviders && keySharesToBackup.length >= 2) {
|
|
2632
|
+
// Cloud Providers only (no delegation): Split shares between Dynamic (N-1) and cloud providers (1).
|
|
2633
|
+
// The last share (new share) goes to cloud providers.
|
|
2634
|
+
distribution = createCloudProviderDistribution({
|
|
2635
|
+
providers: providersToBackup,
|
|
2589
2636
|
allShares: keySharesToBackup
|
|
2590
2637
|
});
|
|
2591
2638
|
} else {
|
|
2592
|
-
// No delegation, no
|
|
2639
|
+
// No delegation, no cloud providers: All shares go to Dynamic backend only.
|
|
2593
2640
|
distribution = createDynamicOnlyDistribution({
|
|
2594
2641
|
allShares: keySharesToBackup
|
|
2595
2642
|
});
|
|
@@ -2758,16 +2805,10 @@ class DynamicWalletClient {
|
|
|
2758
2805
|
this.walletMap = JSON.parse(wallets);
|
|
2759
2806
|
}
|
|
2760
2807
|
/**
|
|
2761
|
-
*
|
|
2762
|
-
* - For 2-of-2 wallets: Automatically reshares to 2-of-3 threshold, then distributes shares (1 to backend, 1 to
|
|
2763
|
-
* - For 2-of-3 wallets: Call storeEncryptedBackupByWallet to backup for backend and
|
|
2764
|
-
|
|
2765
|
-
* @param params - The backup parameters
|
|
2766
|
-
* @param params.accountAddress - The wallet account address to backup
|
|
2767
|
-
* @param params.password - Optional password for encryption (uses environment ID if not provided)
|
|
2768
|
-
* @param params.signedSessionId - Optional signed session ID for authentication
|
|
2769
|
-
* @returns Promise<string[]> - Array of Google Drive key share IDs that were backed up
|
|
2770
|
-
*/ async backupKeySharesToGoogleDrive({ accountAddress, password, signedSessionId }) {
|
|
2808
|
+
* Internal helper method that handles the complete flow for ensuring wallet key shares are backed up to a cloud provider.
|
|
2809
|
+
* - For 2-of-2 wallets: Automatically reshares to 2-of-3 threshold, then distributes shares (1 to backend, 1 to cloud)
|
|
2810
|
+
* - For 2-of-3 wallets: Call storeEncryptedBackupByWallet to backup for backend and cloud
|
|
2811
|
+
*/ async backupKeySharesToCloudProvider({ accountAddress, password, signedSessionId, backupLocation }) {
|
|
2771
2812
|
try {
|
|
2772
2813
|
await this.getWallet({
|
|
2773
2814
|
accountAddress,
|
|
@@ -2785,93 +2826,86 @@ class DynamicWalletClient {
|
|
|
2785
2826
|
newThresholdSignatureScheme: core.ThresholdSignatureScheme.TWO_OF_THREE,
|
|
2786
2827
|
password,
|
|
2787
2828
|
signedSessionId,
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
const googleDriveShares = backupInfo.backups[core.BackupLocation.GOOGLE_DRIVE] || [];
|
|
2792
|
-
return googleDriveShares.map((ks)=>{
|
|
2793
|
-
var _ks_externalKeyShareId;
|
|
2794
|
-
return (_ks_externalKeyShareId = ks.externalKeyShareId) != null ? _ks_externalKeyShareId : '';
|
|
2829
|
+
cloudProviders: [
|
|
2830
|
+
backupLocation
|
|
2831
|
+
]
|
|
2795
2832
|
});
|
|
2796
2833
|
} else {
|
|
2797
2834
|
await this.storeEncryptedBackupByWallet({
|
|
2798
2835
|
accountAddress,
|
|
2799
2836
|
password,
|
|
2800
2837
|
signedSessionId,
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
const googleDriveShares = backupInfo.backups[core.BackupLocation.GOOGLE_DRIVE] || [];
|
|
2805
|
-
return googleDriveShares.map((ks)=>{
|
|
2806
|
-
var _ks_externalKeyShareId;
|
|
2807
|
-
return (_ks_externalKeyShareId = ks.externalKeyShareId) != null ? _ks_externalKeyShareId : '';
|
|
2838
|
+
cloudProviders: [
|
|
2839
|
+
backupLocation
|
|
2840
|
+
]
|
|
2808
2841
|
});
|
|
2809
2842
|
}
|
|
2810
2843
|
} catch (error) {
|
|
2811
2844
|
logError({
|
|
2812
|
-
message:
|
|
2845
|
+
message: `Error in backupKeySharesToCloudProvider (${backupLocation})`,
|
|
2813
2846
|
error: error,
|
|
2814
2847
|
context: {
|
|
2815
|
-
accountAddress
|
|
2848
|
+
accountAddress,
|
|
2849
|
+
backupLocation
|
|
2816
2850
|
}
|
|
2817
2851
|
});
|
|
2818
2852
|
throw error;
|
|
2819
2853
|
}
|
|
2820
2854
|
}
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2855
|
+
/**
|
|
2856
|
+
* This method handles the complete flow for ensuring wallet key shares are backed up to Google Drive:
|
|
2857
|
+
* - For 2-of-2 wallets: Automatically reshares to 2-of-3 threshold, then distributes shares (1 to backend, 1 to Google Drive)
|
|
2858
|
+
* - For 2-of-3 wallets: Call storeEncryptedBackupByWallet to backup for backend and Google Drive
|
|
2859
|
+
*
|
|
2860
|
+
* @param params - The backup parameters
|
|
2861
|
+
* @param params.accountAddress - The wallet account address to backup
|
|
2862
|
+
* @param params.password - Optional password for encryption (uses environment ID if not provided)
|
|
2863
|
+
* @param params.signedSessionId - Optional signed session ID for authentication
|
|
2864
|
+
*/ async backupKeySharesToGoogleDrive({ accountAddress, password, signedSessionId }) {
|
|
2865
|
+
return this.backupKeySharesToCloudProvider({
|
|
2866
|
+
accountAddress,
|
|
2867
|
+
password,
|
|
2868
|
+
signedSessionId,
|
|
2869
|
+
backupLocation: core.BackupLocation.GOOGLE_DRIVE
|
|
2870
|
+
});
|
|
2871
|
+
}
|
|
2872
|
+
/**
|
|
2873
|
+
* This method handles the complete flow for ensuring wallet key shares are backed up to iCloud:
|
|
2874
|
+
* - For 2-of-2 wallets: Automatically reshares to 2-of-3 threshold, then distributes shares (1 to backend, 1 to iCloud)
|
|
2875
|
+
* - For 2-of-3 wallets: Call storeEncryptedBackupByWallet to backup for backend and iCloud
|
|
2876
|
+
*
|
|
2877
|
+
* @param params - The backup parameters
|
|
2878
|
+
* @param params.accountAddress - The wallet account address to backup
|
|
2879
|
+
* @param params.password - Optional password for encryption (uses environment ID if not provided)
|
|
2880
|
+
* @param params.signedSessionId - Optional signed session ID for authentication
|
|
2881
|
+
*/ async backupKeySharesToICloud({ accountAddress, password, signedSessionId }) {
|
|
2882
|
+
return this.backupKeySharesToCloudProvider({
|
|
2883
|
+
accountAddress,
|
|
2884
|
+
password,
|
|
2885
|
+
signedSessionId,
|
|
2886
|
+
backupLocation: core.BackupLocation.ICLOUD
|
|
2887
|
+
});
|
|
2888
|
+
}
|
|
2889
|
+
/**
|
|
2890
|
+
* Generic router method that uploads encrypted key shares to the specified cloud provider
|
|
2891
|
+
* @param provider - The cloud backup provider (GOOGLE_DRIVE, ICLOUD, etc.)
|
|
2892
|
+
* @param accountAddress - Wallet account address
|
|
2893
|
+
* @param encryptedKeyShares - Already encrypted key shares to upload
|
|
2894
|
+
* @returns Promise<void>
|
|
2895
|
+
*/ async uploadToCloudProvider({ provider, accountAddress, encryptedKeyShares }) {
|
|
2896
|
+
switch(provider){
|
|
2897
|
+
case core.BackupLocation.GOOGLE_DRIVE:
|
|
2898
|
+
return this.uploadKeySharesToGoogleDrive({
|
|
2899
|
+
accountAddress,
|
|
2900
|
+
encryptedKeyShares
|
|
2848
2901
|
});
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
});
|
|
2857
|
-
if (onProgress) {
|
|
2858
|
-
onProgress(0, 1);
|
|
2859
|
-
}
|
|
2860
|
-
const savedRecord = await saveBackupToICloud(backupData);
|
|
2861
|
-
savedRecords.push(savedRecord);
|
|
2862
|
-
if (onProgress) {
|
|
2863
|
-
onProgress(1, 1);
|
|
2864
|
-
}
|
|
2865
|
-
return savedRecords;
|
|
2866
|
-
} catch (error) {
|
|
2867
|
-
logError({
|
|
2868
|
-
message: 'Error in backupKeySharesToICloud',
|
|
2869
|
-
error: error,
|
|
2870
|
-
context: {
|
|
2871
|
-
accountAddress
|
|
2872
|
-
}
|
|
2873
|
-
});
|
|
2874
|
-
throw error;
|
|
2902
|
+
case core.BackupLocation.ICLOUD:
|
|
2903
|
+
return this.uploadKeySharesToICloud({
|
|
2904
|
+
accountAddress,
|
|
2905
|
+
encryptedKeyShares
|
|
2906
|
+
});
|
|
2907
|
+
default:
|
|
2908
|
+
throw new Error(`Unsupported cloud provider: ${provider}`);
|
|
2875
2909
|
}
|
|
2876
2910
|
}
|
|
2877
2911
|
/**
|
|
@@ -2923,6 +2957,40 @@ class DynamicWalletClient {
|
|
|
2923
2957
|
throw error;
|
|
2924
2958
|
}
|
|
2925
2959
|
}
|
|
2960
|
+
/**
|
|
2961
|
+
* Private method that handles only the iCloud upload mechanics without any reshare logic.
|
|
2962
|
+
* It takes already encrypted key shares and uploads them to iCloud.
|
|
2963
|
+
* @param accountAddress - The wallet account address
|
|
2964
|
+
* @param encryptedKeyShares - Already encrypted key shares to upload
|
|
2965
|
+
* @returns Promise<void>
|
|
2966
|
+
*/ async uploadKeySharesToICloud({ accountAddress, encryptedKeyShares }) {
|
|
2967
|
+
try {
|
|
2968
|
+
var _environmentSettings_sdk_waas, _environmentSettings_sdk;
|
|
2969
|
+
if (encryptedKeyShares.length === 0) {
|
|
2970
|
+
throw new Error('No key shares found');
|
|
2971
|
+
}
|
|
2972
|
+
const environmentSettings = await this.apiClient.getEnvironmentSettings();
|
|
2973
|
+
const iCloudConfig = environmentSettings == null ? void 0 : (_environmentSettings_sdk = environmentSettings.sdk) == null ? void 0 : (_environmentSettings_sdk_waas = _environmentSettings_sdk.waas) == null ? void 0 : _environmentSettings_sdk_waas.iCloud;
|
|
2974
|
+
await initializeCloudKit(iCloudConfig);
|
|
2975
|
+
const thresholdSignatureScheme = this.walletMap[accountAddress].thresholdSignatureScheme;
|
|
2976
|
+
const backupData = createBackupData({
|
|
2977
|
+
encryptedKeyShares,
|
|
2978
|
+
accountAddress,
|
|
2979
|
+
thresholdSignatureScheme
|
|
2980
|
+
});
|
|
2981
|
+
await saveBackupToICloud(backupData);
|
|
2982
|
+
return;
|
|
2983
|
+
} catch (error) {
|
|
2984
|
+
logError({
|
|
2985
|
+
message: 'Error in uploadKeySharesToICloud',
|
|
2986
|
+
error: error,
|
|
2987
|
+
context: {
|
|
2988
|
+
accountAddress
|
|
2989
|
+
}
|
|
2990
|
+
});
|
|
2991
|
+
throw error;
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2926
2994
|
async exportClientKeysharesFromGoogleDrive({ accountAddress, password, signedSessionId }) {
|
|
2927
2995
|
try {
|
|
2928
2996
|
await this.getWallet({
|
|
@@ -3575,25 +3643,26 @@ exports.ERROR_VERIFY_MESSAGE_SIGNATURE = ERROR_VERIFY_MESSAGE_SIGNATURE;
|
|
|
3575
3643
|
exports.ERROR_VERIFY_TRANSACTION_SIGNATURE = ERROR_VERIFY_TRANSACTION_SIGNATURE;
|
|
3576
3644
|
exports.WalletBusyError = WalletBusyError;
|
|
3577
3645
|
exports.cancelICloudAuth = cancelICloudAuth;
|
|
3578
|
-
exports.
|
|
3646
|
+
exports.createAddCloudProviderToExistingDelegationDistribution = createAddCloudProviderToExistingDelegationDistribution;
|
|
3579
3647
|
exports.createBackupData = createBackupData;
|
|
3648
|
+
exports.createCloudProviderDistribution = createCloudProviderDistribution;
|
|
3580
3649
|
exports.createDelegationOnlyDistribution = createDelegationOnlyDistribution;
|
|
3581
|
-
exports.
|
|
3650
|
+
exports.createDelegationWithCloudProviderDistribution = createDelegationWithCloudProviderDistribution;
|
|
3582
3651
|
exports.createDynamicOnlyDistribution = createDynamicOnlyDistribution;
|
|
3583
|
-
exports.createGoogleDriveOnlyDistribution = createGoogleDriveOnlyDistribution;
|
|
3584
3652
|
exports.deleteICloudBackup = deleteICloudBackup;
|
|
3585
3653
|
exports.downloadStringAsFile = downloadStringAsFile;
|
|
3586
3654
|
exports.extractPubkey = extractPubkey;
|
|
3587
3655
|
exports.formatEvmMessage = formatEvmMessage;
|
|
3588
3656
|
exports.formatMessage = formatMessage;
|
|
3657
|
+
exports.getActiveCloudProviders = getActiveCloudProviders;
|
|
3589
3658
|
exports.getClientKeyShareBackupInfo = getClientKeyShareBackupInfo;
|
|
3590
3659
|
exports.getClientKeyShareExportFileName = getClientKeyShareExportFileName;
|
|
3591
3660
|
exports.getGoogleOAuthAccountId = getGoogleOAuthAccountId;
|
|
3592
3661
|
exports.getICloudBackup = getICloudBackup;
|
|
3593
3662
|
exports.getMPCSignatureScheme = getMPCSignatureScheme;
|
|
3594
3663
|
exports.getMPCSigner = getMPCSigner;
|
|
3664
|
+
exports.hasCloudProviderBackup = hasCloudProviderBackup;
|
|
3595
3665
|
exports.hasDelegatedBackup = hasDelegatedBackup;
|
|
3596
|
-
exports.hasGoogleDriveBackup = hasGoogleDriveBackup;
|
|
3597
3666
|
exports.isBrowser = isBrowser;
|
|
3598
3667
|
exports.isHexString = isHexString;
|
|
3599
3668
|
exports.listICloudBackups = listICloudBackups;
|