@1sat/wallet-toolbox 0.0.37 → 0.0.39
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 +83 -72
- package/package.json +3 -3
package/dist/wallet/factory.js
CHANGED
|
@@ -72,84 +72,88 @@ 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.
|
|
76
|
-
let storage = new WalletStorageManager(identityPubKey, localStorage);
|
|
77
|
-
await storage.makeAvailable();
|
|
78
|
-
// Track remote client for fullSync
|
|
75
|
+
// 4. Attempt remote storage connection BEFORE creating Wallet (if URL provided)
|
|
79
76
|
let remoteClient;
|
|
80
|
-
// 5. Create the underlying Wallet
|
|
81
|
-
const underlyingWallet = new Wallet({
|
|
82
|
-
chain,
|
|
83
|
-
keyDeriver,
|
|
84
|
-
storage,
|
|
85
|
-
services: oneSatServices,
|
|
86
|
-
});
|
|
87
|
-
// 6. Attempt remote storage connection if URL provided
|
|
88
77
|
if (config.remoteStorageUrl) {
|
|
89
78
|
console.log(`[createWebWallet] Attempting remote storage connection to ${config.remoteStorageUrl}`);
|
|
90
79
|
try {
|
|
91
|
-
|
|
80
|
+
// Create a temporary wallet just for StorageClient auth
|
|
81
|
+
// StorageClient needs a wallet to sign requests
|
|
82
|
+
const tempStorage = new WalletStorageManager(identityPubKey, localStorage);
|
|
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);
|
|
92
91
|
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("Remote storage connection timeout")), DEFAULT_REMOTE_STORAGE_TIMEOUT));
|
|
93
92
|
await Promise.race([remoteClient.makeAvailable(), timeoutPromise]);
|
|
94
|
-
// Remote connected - recreate storage manager with backup
|
|
95
|
-
storage = new WalletStorageManager(identityPubKey, localStorage, [
|
|
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;
|
|
143
93
|
console.log("[createWebWallet] Remote storage connected successfully");
|
|
94
|
+
// Clean up temp wallet (don't destroy storage - we'll reuse localStorage)
|
|
95
|
+
await tempWallet.destroy();
|
|
144
96
|
}
|
|
145
97
|
catch (err) {
|
|
146
98
|
console.log("[createWebWallet] Remote storage connection failed:", err instanceof Error ? err.message : err);
|
|
147
|
-
|
|
99
|
+
remoteClient = undefined;
|
|
148
100
|
}
|
|
149
101
|
}
|
|
150
|
-
//
|
|
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
|
+
// Log storage state using public APIs
|
|
107
|
+
const stores = storage.getStores();
|
|
108
|
+
console.log("[createWebWallet] Storage state:", {
|
|
109
|
+
activeKey: storage.getActiveStore(),
|
|
110
|
+
backups: storage.getBackupStores(),
|
|
111
|
+
conflictingActives: storage.getConflictingStores(),
|
|
112
|
+
isActiveEnabled: storage.isActiveEnabled,
|
|
113
|
+
allStores: stores.map(s => ({ name: s.storageName, key: s.storageIdentityKey.slice(0, 16) + "..." })),
|
|
114
|
+
});
|
|
115
|
+
// 6. Handle conflicting actives or push to backups
|
|
116
|
+
const conflictingStores = storage.getConflictingStores();
|
|
117
|
+
const backupStores = storage.getBackupStores();
|
|
118
|
+
if (conflictingStores.length > 0) {
|
|
119
|
+
const localKey = storage.getActiveStore();
|
|
120
|
+
console.log("[createWebWallet] Resolving conflicting actives...");
|
|
121
|
+
try {
|
|
122
|
+
await storage.setActive(localKey, (msg) => {
|
|
123
|
+
console.log("[createWebWallet] Conflict resolution:", msg);
|
|
124
|
+
return msg;
|
|
125
|
+
});
|
|
126
|
+
console.log("[createWebWallet] Conflict resolution complete");
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
console.log("[createWebWallet] Conflict resolution failed:", err instanceof Error ? err.message : err);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else if (backupStores.length > 0) {
|
|
133
|
+
// No conflicts - push local state to remote backup (fire-and-forget)
|
|
134
|
+
console.log("[createWebWallet] Pushing local state to remote backup...");
|
|
135
|
+
storage
|
|
136
|
+
.updateBackups(undefined, (msg) => {
|
|
137
|
+
console.log("[createWebWallet] Backup:", msg);
|
|
138
|
+
return msg;
|
|
139
|
+
})
|
|
140
|
+
.then(() => {
|
|
141
|
+
console.log("[createWebWallet] Backup complete");
|
|
142
|
+
})
|
|
143
|
+
.catch((err) => {
|
|
144
|
+
console.log("[createWebWallet] Backup failed:", err instanceof Error ? err.message : err);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
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
|
+
// 8. Wrap with permissions manager
|
|
151
155
|
const wallet = new WalletPermissionsManager(underlyingWallet, adminOriginator, permissionsConfig);
|
|
152
|
-
//
|
|
156
|
+
// 9. Create monitor (not started - consumer calls startTasks() when ready)
|
|
153
157
|
const monitor = new Monitor({
|
|
154
158
|
chain,
|
|
155
159
|
services: oneSatServices,
|
|
@@ -162,14 +166,22 @@ export async function createWebWallet(config) {
|
|
|
162
166
|
unprovenAttemptsLimitMain: 144,
|
|
163
167
|
});
|
|
164
168
|
monitor.addDefaultTasks();
|
|
165
|
-
//
|
|
169
|
+
// Helper to sync to remote backup using public updateBackups API
|
|
170
|
+
const syncToBackup = async (context) => {
|
|
171
|
+
if (storage.getBackupStores().length > 0) {
|
|
172
|
+
await storage.updateBackups(undefined, (msg) => {
|
|
173
|
+
console.log(`[Monitor] ${context}:`, msg);
|
|
174
|
+
return msg;
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
// 10. Wire up monitor callbacks - sync to remote first, then call user callbacks
|
|
166
179
|
monitor.onTransactionBroadcasted = async (result) => {
|
|
167
180
|
console.log("[Monitor] Transaction broadcasted:", result.txid);
|
|
168
181
|
// Sync to remote backup first (if connected)
|
|
169
182
|
if (remoteClient) {
|
|
170
183
|
try {
|
|
171
|
-
|
|
172
|
-
await storage.syncToWriter(auth, remoteClient);
|
|
184
|
+
await syncToBackup("Backup after broadcast");
|
|
173
185
|
console.log("[Monitor] Synced to backup after broadcast");
|
|
174
186
|
}
|
|
175
187
|
catch (err) {
|
|
@@ -191,8 +203,7 @@ export async function createWebWallet(config) {
|
|
|
191
203
|
// Sync to remote backup first (if connected)
|
|
192
204
|
if (remoteClient) {
|
|
193
205
|
try {
|
|
194
|
-
|
|
195
|
-
await storage.syncToWriter(auth, remoteClient);
|
|
206
|
+
await syncToBackup("Backup after confirmation");
|
|
196
207
|
console.log("[Monitor] Synced to backup after confirmation");
|
|
197
208
|
}
|
|
198
209
|
catch (err) {
|
|
@@ -209,13 +220,13 @@ export async function createWebWallet(config) {
|
|
|
209
220
|
}
|
|
210
221
|
}
|
|
211
222
|
};
|
|
212
|
-
//
|
|
223
|
+
// 11. Create cleanup function
|
|
213
224
|
const destroy = async () => {
|
|
214
225
|
monitor.stopTasks();
|
|
215
226
|
await monitor.destroy();
|
|
216
227
|
await underlyingWallet.destroy();
|
|
217
228
|
};
|
|
218
|
-
//
|
|
229
|
+
// 12. Create fullSync function if remote storage is connected
|
|
219
230
|
const fullSyncFn = remoteClient
|
|
220
231
|
? async (onProgress) => {
|
|
221
232
|
return fullSync({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1sat/wallet-toolbox",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.39",
|
|
4
4
|
"description": "BSV wallet library extending @bsv/wallet-toolbox with 1Sat Ordinals protocol support",
|
|
5
5
|
"author": "1Sat Team",
|
|
6
6
|
"license": "MIT",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"fflate": "^0.8.2"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
|
-
"@bsv/wallet-toolbox-mobile": "npm:@bopen-io/wallet-toolbox-mobile@^1.7.20-idb-fix.
|
|
47
|
+
"@bsv/wallet-toolbox-mobile": "npm:@bopen-io/wallet-toolbox-mobile@^1.7.20-idb-fix.19"
|
|
48
48
|
},
|
|
49
49
|
"peerDependenciesMeta": {
|
|
50
50
|
"@bsv/wallet-toolbox-mobile": {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@biomejs/biome": "^1.9.4",
|
|
56
56
|
"@bsv/wallet-toolbox": "npm:@bopen-io/wallet-toolbox@^1.7.20-idb-fix.17",
|
|
57
|
-
"@bsv/wallet-toolbox-mobile": "npm:@bopen-io/wallet-toolbox-mobile@^1.7.20-idb-fix.
|
|
57
|
+
"@bsv/wallet-toolbox-mobile": "npm:@bopen-io/wallet-toolbox-mobile@^1.7.20-idb-fix.19",
|
|
58
58
|
"@types/bun": "^1.3.4",
|
|
59
59
|
"@types/chrome": "^0.1.32",
|
|
60
60
|
"typescript": "^5.9.3"
|