@1sat/wallet-toolbox 0.0.38 → 0.0.40
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 +59 -65
- package/package.json +1 -1
package/dist/wallet/factory.js
CHANGED
|
@@ -72,84 +72,79 @@ 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. Create storage manager
|
|
76
|
-
|
|
75
|
+
// 4. Create storage manager with local-only storage initially (empty backups)
|
|
76
|
+
const storage = new WalletStorageManager(identityPubKey, localStorage, []);
|
|
77
77
|
await storage.makeAvailable();
|
|
78
|
-
//
|
|
79
|
-
let remoteClient;
|
|
80
|
-
// 5. Create the underlying Wallet
|
|
78
|
+
// 5. Create the underlying Wallet FIRST (needed for StorageClient signing)
|
|
81
79
|
const underlyingWallet = new Wallet({
|
|
82
80
|
chain,
|
|
83
81
|
keyDeriver,
|
|
84
82
|
storage,
|
|
85
83
|
services: oneSatServices,
|
|
86
84
|
});
|
|
87
|
-
// 6. Attempt remote storage connection
|
|
85
|
+
// 6. Attempt remote storage connection AFTER wallet exists
|
|
86
|
+
let remoteClient;
|
|
88
87
|
if (config.remoteStorageUrl) {
|
|
89
88
|
console.log(`[createWebWallet] Attempting remote storage connection to ${config.remoteStorageUrl}`);
|
|
90
89
|
try {
|
|
90
|
+
// Create StorageClient with the REAL wallet (not a temp wallet)
|
|
91
|
+
// StorageClient captures the wallet at construction for signing requests
|
|
91
92
|
remoteClient = new StorageClient(underlyingWallet, config.remoteStorageUrl);
|
|
92
93
|
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("Remote storage connection timeout")), DEFAULT_REMOTE_STORAGE_TIMEOUT));
|
|
93
94
|
await Promise.race([remoteClient.makeAvailable(), timeoutPromise]);
|
|
94
|
-
//
|
|
95
|
-
storage
|
|
96
|
-
remoteClient,
|
|
97
|
-
]);
|
|
98
|
-
await storage.makeAvailable();
|
|
99
|
-
// Check for conflicting actives and resolve if needed
|
|
100
|
-
const storageAny = storage;
|
|
101
|
-
console.log("[createWebWallet] Storage state:", {
|
|
102
|
-
activeKey: storageAny._active?.settings?.storageIdentityKey,
|
|
103
|
-
backups: storageAny._backups?.map((b) => b.settings?.storageIdentityKey),
|
|
104
|
-
conflictingActives: storageAny._conflictingActives?.map((c) => c.settings?.storageIdentityKey),
|
|
105
|
-
});
|
|
106
|
-
// Only resolve actual conflicts, don't treat backups as conflicts
|
|
107
|
-
if (storageAny._conflictingActives &&
|
|
108
|
-
storageAny._conflictingActives.length > 0) {
|
|
109
|
-
const localKey = storageAny._active?.settings?.storageIdentityKey;
|
|
110
|
-
if (localKey && storageAny.setActive) {
|
|
111
|
-
console.log("[createWebWallet] Resolving conflicting actives...");
|
|
112
|
-
try {
|
|
113
|
-
await storageAny.setActive(localKey, (msg) => {
|
|
114
|
-
console.log("[createWebWallet] Conflict resolution:", msg);
|
|
115
|
-
return msg;
|
|
116
|
-
});
|
|
117
|
-
console.log("[createWebWallet] Conflict resolution complete");
|
|
118
|
-
}
|
|
119
|
-
catch (err) {
|
|
120
|
-
console.log("[createWebWallet] Conflict resolution failed:", err instanceof Error ? err.message : err);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
else if (storageAny._backups &&
|
|
125
|
-
storageAny._backups.length > 0 &&
|
|
126
|
-
storageAny.updateBackups) {
|
|
127
|
-
// No conflicts - push local state to remote backup (fire-and-forget)
|
|
128
|
-
console.log("[createWebWallet] Pushing local state to remote backup...");
|
|
129
|
-
storageAny
|
|
130
|
-
.updateBackups(undefined, (msg) => {
|
|
131
|
-
console.log("[createWebWallet] Backup:", msg);
|
|
132
|
-
return msg;
|
|
133
|
-
})
|
|
134
|
-
.then(() => {
|
|
135
|
-
console.log("[createWebWallet] Backup complete");
|
|
136
|
-
})
|
|
137
|
-
.catch((err) => {
|
|
138
|
-
console.log("[createWebWallet] Backup failed:", err instanceof Error ? err.message : err);
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
// Update wallet's storage reference
|
|
142
|
-
underlyingWallet._storage = storage;
|
|
95
|
+
// Add remote storage to the existing storage manager using public API
|
|
96
|
+
await storage.addWalletStorageProvider(remoteClient);
|
|
143
97
|
console.log("[createWebWallet] Remote storage connected successfully");
|
|
144
98
|
}
|
|
145
99
|
catch (err) {
|
|
146
100
|
console.log("[createWebWallet] Remote storage connection failed:", err instanceof Error ? err.message : err);
|
|
147
|
-
|
|
101
|
+
remoteClient = undefined;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Log storage state using public APIs
|
|
105
|
+
const stores = storage.getStores();
|
|
106
|
+
console.log("[createWebWallet] Storage state:", {
|
|
107
|
+
activeKey: storage.getActiveStore(),
|
|
108
|
+
backups: storage.getBackupStores(),
|
|
109
|
+
conflictingActives: storage.getConflictingStores(),
|
|
110
|
+
isActiveEnabled: storage.isActiveEnabled,
|
|
111
|
+
allStores: stores.map(s => ({ name: s.storageName, key: s.storageIdentityKey.slice(0, 16) + "..." })),
|
|
112
|
+
});
|
|
113
|
+
// 7. Handle conflicting actives or sync to backups
|
|
114
|
+
const conflictingStores = storage.getConflictingStores();
|
|
115
|
+
const backupStores = storage.getBackupStores();
|
|
116
|
+
if (conflictingStores.length > 0) {
|
|
117
|
+
const localKey = storage.getActiveStore();
|
|
118
|
+
console.log("[createWebWallet] Resolving conflicting actives...");
|
|
119
|
+
try {
|
|
120
|
+
await storage.setActive(localKey, (msg) => {
|
|
121
|
+
console.log("[createWebWallet] Conflict resolution:", msg);
|
|
122
|
+
return msg;
|
|
123
|
+
});
|
|
124
|
+
console.log("[createWebWallet] Conflict resolution complete");
|
|
148
125
|
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
console.log("[createWebWallet] Conflict resolution failed:", err instanceof Error ? err.message : err);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else if (backupStores.length > 0) {
|
|
131
|
+
// No conflicts - push local state to remote backup (fire-and-forget)
|
|
132
|
+
console.log("[createWebWallet] Pushing local state to remote backup...");
|
|
133
|
+
storage
|
|
134
|
+
.updateBackups(undefined, (msg) => {
|
|
135
|
+
console.log("[createWebWallet] Backup:", msg);
|
|
136
|
+
return msg;
|
|
137
|
+
})
|
|
138
|
+
.then(() => {
|
|
139
|
+
console.log("[createWebWallet] Backup complete");
|
|
140
|
+
})
|
|
141
|
+
.catch((err) => {
|
|
142
|
+
console.log("[createWebWallet] Backup failed:", err instanceof Error ? err.message : err);
|
|
143
|
+
});
|
|
149
144
|
}
|
|
150
|
-
//
|
|
145
|
+
// 8. Wrap with permissions manager
|
|
151
146
|
const wallet = new WalletPermissionsManager(underlyingWallet, adminOriginator, permissionsConfig);
|
|
152
|
-
//
|
|
147
|
+
// 9. Create monitor (not started - consumer calls startTasks() when ready)
|
|
153
148
|
const monitor = new Monitor({
|
|
154
149
|
chain,
|
|
155
150
|
services: oneSatServices,
|
|
@@ -162,17 +157,16 @@ export async function createWebWallet(config) {
|
|
|
162
157
|
unprovenAttemptsLimitMain: 144,
|
|
163
158
|
});
|
|
164
159
|
monitor.addDefaultTasks();
|
|
165
|
-
// Helper to sync to remote backup using updateBackups
|
|
160
|
+
// Helper to sync to remote backup using public updateBackups API
|
|
166
161
|
const syncToBackup = async (context) => {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
await storageAny.updateBackups(undefined, (msg) => {
|
|
162
|
+
if (storage.getBackupStores().length > 0) {
|
|
163
|
+
await storage.updateBackups(undefined, (msg) => {
|
|
170
164
|
console.log(`[Monitor] ${context}:`, msg);
|
|
171
165
|
return msg;
|
|
172
166
|
});
|
|
173
167
|
}
|
|
174
168
|
};
|
|
175
|
-
//
|
|
169
|
+
// 10. Wire up monitor callbacks - sync to remote first, then call user callbacks
|
|
176
170
|
monitor.onTransactionBroadcasted = async (result) => {
|
|
177
171
|
console.log("[Monitor] Transaction broadcasted:", result.txid);
|
|
178
172
|
// Sync to remote backup first (if connected)
|
|
@@ -217,13 +211,13 @@ export async function createWebWallet(config) {
|
|
|
217
211
|
}
|
|
218
212
|
}
|
|
219
213
|
};
|
|
220
|
-
//
|
|
214
|
+
// 11. Create cleanup function
|
|
221
215
|
const destroy = async () => {
|
|
222
216
|
monitor.stopTasks();
|
|
223
217
|
await monitor.destroy();
|
|
224
218
|
await underlyingWallet.destroy();
|
|
225
219
|
};
|
|
226
|
-
//
|
|
220
|
+
// 12. Create fullSync function if remote storage is connected
|
|
227
221
|
const fullSyncFn = remoteClient
|
|
228
222
|
? async (onProgress) => {
|
|
229
223
|
return fullSync({
|