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