@1sat/wallet-toolbox 0.0.39 → 0.0.41
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/dist/wallet/factory.js +17 -26
- package/dist/wallet/fullSync.js +27 -6
- package/package.json +1 -1
package/dist/wallet/factory.js
CHANGED
|
@@ -72,37 +72,35 @@ export async function createWebWallet(config) {
|
|
|
72
72
|
storageOptions.feeModel = feeModel;
|
|
73
73
|
const localStorage = new StorageIdb(storageOptions);
|
|
74
74
|
await localStorage.migrate(DEFAULT_DATABASE_NAME, identityPubKey);
|
|
75
|
-
// 4.
|
|
75
|
+
// 4. Create storage manager with local-only storage initially (empty backups)
|
|
76
|
+
const storage = new WalletStorageManager(identityPubKey, localStorage, []);
|
|
77
|
+
await storage.makeAvailable();
|
|
78
|
+
// 5. Create the underlying Wallet FIRST (needed for StorageClient signing)
|
|
79
|
+
const underlyingWallet = new Wallet({
|
|
80
|
+
chain,
|
|
81
|
+
keyDeriver,
|
|
82
|
+
storage,
|
|
83
|
+
services: oneSatServices,
|
|
84
|
+
});
|
|
85
|
+
// 6. Attempt remote storage connection AFTER wallet exists
|
|
76
86
|
let remoteClient;
|
|
77
87
|
if (config.remoteStorageUrl) {
|
|
78
88
|
console.log(`[createWebWallet] Attempting remote storage connection to ${config.remoteStorageUrl}`);
|
|
79
89
|
try {
|
|
80
|
-
// Create
|
|
81
|
-
// StorageClient
|
|
82
|
-
|
|
83
|
-
await tempStorage.makeAvailable();
|
|
84
|
-
const tempWallet = new Wallet({
|
|
85
|
-
chain,
|
|
86
|
-
keyDeriver,
|
|
87
|
-
storage: tempStorage,
|
|
88
|
-
services: oneSatServices,
|
|
89
|
-
});
|
|
90
|
-
remoteClient = new StorageClient(tempWallet, config.remoteStorageUrl);
|
|
90
|
+
// Create StorageClient with the REAL wallet (not a temp wallet)
|
|
91
|
+
// StorageClient captures the wallet at construction for signing requests
|
|
92
|
+
remoteClient = new StorageClient(underlyingWallet, config.remoteStorageUrl);
|
|
91
93
|
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("Remote storage connection timeout")), DEFAULT_REMOTE_STORAGE_TIMEOUT));
|
|
92
94
|
await Promise.race([remoteClient.makeAvailable(), timeoutPromise]);
|
|
95
|
+
// Add remote storage to the existing storage manager using public API
|
|
96
|
+
await storage.addWalletStorageProvider(remoteClient);
|
|
93
97
|
console.log("[createWebWallet] Remote storage connected successfully");
|
|
94
|
-
// Clean up temp wallet (don't destroy storage - we'll reuse localStorage)
|
|
95
|
-
await tempWallet.destroy();
|
|
96
98
|
}
|
|
97
99
|
catch (err) {
|
|
98
100
|
console.log("[createWebWallet] Remote storage connection failed:", err instanceof Error ? err.message : err);
|
|
99
101
|
remoteClient = undefined;
|
|
100
102
|
}
|
|
101
103
|
}
|
|
102
|
-
// 5. Create storage manager with final configuration (local + remote if connected)
|
|
103
|
-
const backups = remoteClient ? [remoteClient] : [];
|
|
104
|
-
const storage = new WalletStorageManager(identityPubKey, localStorage, backups);
|
|
105
|
-
await storage.makeAvailable();
|
|
106
104
|
// Log storage state using public APIs
|
|
107
105
|
const stores = storage.getStores();
|
|
108
106
|
console.log("[createWebWallet] Storage state:", {
|
|
@@ -112,7 +110,7 @@ export async function createWebWallet(config) {
|
|
|
112
110
|
isActiveEnabled: storage.isActiveEnabled,
|
|
113
111
|
allStores: stores.map(s => ({ name: s.storageName, key: s.storageIdentityKey.slice(0, 16) + "..." })),
|
|
114
112
|
});
|
|
115
|
-
//
|
|
113
|
+
// 7. Handle conflicting actives or sync to backups
|
|
116
114
|
const conflictingStores = storage.getConflictingStores();
|
|
117
115
|
const backupStores = storage.getBackupStores();
|
|
118
116
|
if (conflictingStores.length > 0) {
|
|
@@ -144,13 +142,6 @@ export async function createWebWallet(config) {
|
|
|
144
142
|
console.log("[createWebWallet] Backup failed:", err instanceof Error ? err.message : err);
|
|
145
143
|
});
|
|
146
144
|
}
|
|
147
|
-
// 7. Create the underlying Wallet with the FINAL storage configuration
|
|
148
|
-
const underlyingWallet = new Wallet({
|
|
149
|
-
chain,
|
|
150
|
-
keyDeriver,
|
|
151
|
-
storage,
|
|
152
|
-
services: oneSatServices,
|
|
153
|
-
});
|
|
154
145
|
// 8. Wrap with permissions manager
|
|
155
146
|
const wallet = new WalletPermissionsManager(underlyingWallet, adminOriginator, permissionsConfig);
|
|
156
147
|
// 9. Create monitor (not started - consumer calls startTasks() when ready)
|
package/dist/wallet/fullSync.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* This is a deliberate user action (not automatic) for recovering from sync issues.
|
|
6
6
|
*/
|
|
7
7
|
import { createSyncMap } from "@bsv/wallet-toolbox-mobile/out/src/storage/schema/entities/EntityBase.js";
|
|
8
|
+
import { EntitySyncState } from "@bsv/wallet-toolbox-mobile/out/src/storage/schema/entities/EntitySyncState.js";
|
|
8
9
|
/**
|
|
9
10
|
* Perform a full sync with the remote backup server.
|
|
10
11
|
*
|
|
@@ -28,14 +29,34 @@ import { createSyncMap } from "@bsv/wallet-toolbox-mobile/out/src/storage/schema
|
|
|
28
29
|
*/
|
|
29
30
|
export async function fullSync(options) {
|
|
30
31
|
const { storage, remoteStorage, identityKey, onProgress } = options;
|
|
31
|
-
// Step 1: Push local data to remote
|
|
32
|
+
// Step 1: Push ALL local data to remote (bypassing timestamp filter)
|
|
32
33
|
onProgress?.("pushing", "Pushing local data to remote...");
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
|
|
34
|
+
const localSettings = storage.getSettings();
|
|
35
|
+
const remoteSettings = await remoteStorage.makeAvailable();
|
|
36
|
+
let pushInserts = 0;
|
|
37
|
+
let pushUpdates = 0;
|
|
38
|
+
let chunkCount = 0;
|
|
39
|
+
for (;;) {
|
|
40
|
+
// Get sync state from remote for proper offsets
|
|
41
|
+
const ss = await EntitySyncState.fromStorage(remoteStorage, identityKey, localSettings);
|
|
42
|
+
const args = ss.makeRequestSyncChunkArgs(identityKey, remoteSettings.storageIdentityKey);
|
|
43
|
+
// KEY: Override since to undefined - includes ALL data regardless of timestamp
|
|
44
|
+
args.since = undefined;
|
|
45
|
+
// Get chunk from local storage
|
|
46
|
+
const chunk = await storage.runAsSync(async (sync) => sync.getSyncChunk(args));
|
|
47
|
+
// Send chunk to remote
|
|
48
|
+
const result = await remoteStorage.processSyncChunk(args, chunk);
|
|
49
|
+
pushInserts += result.inserts;
|
|
50
|
+
pushUpdates += result.updates;
|
|
51
|
+
chunkCount++;
|
|
52
|
+
onProgress?.("pushing", `Chunk ${chunkCount}: ${result.inserts} inserts, ${result.updates} updates`);
|
|
53
|
+
if (result.done)
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
onProgress?.("pushing", `Pushed ${pushInserts} inserts, ${pushUpdates} updates`);
|
|
36
57
|
// Step 2: Reset sync state to force full pull
|
|
37
58
|
onProgress?.("resetting", "Resetting sync state...");
|
|
38
|
-
const
|
|
59
|
+
const auth = await storage.getAuth();
|
|
39
60
|
await storage.runAsStorageProvider(async (active) => {
|
|
40
61
|
const syncStates = await active.findSyncStates({
|
|
41
62
|
partial: {
|
|
@@ -63,7 +84,7 @@ export async function fullSync(options) {
|
|
|
63
84
|
// Step 4: Complete
|
|
64
85
|
onProgress?.("complete", "Full sync complete");
|
|
65
86
|
return {
|
|
66
|
-
pushed: { inserts:
|
|
87
|
+
pushed: { inserts: pushInserts, updates: pushUpdates },
|
|
67
88
|
pulled: { inserts: pullResult.inserts, updates: pullResult.updates },
|
|
68
89
|
};
|
|
69
90
|
}
|