@1sat/wallet-toolbox 0.0.8 → 0.0.10

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.
Files changed (64) hide show
  1. package/dist/api/balance/index.d.ts +50 -0
  2. package/dist/api/balance/index.js +135 -0
  3. package/dist/api/broadcast/index.d.ts +24 -0
  4. package/dist/api/broadcast/index.js +73 -0
  5. package/dist/api/constants.d.ts +21 -0
  6. package/dist/api/constants.js +29 -0
  7. package/dist/api/index.d.ts +36 -0
  8. package/dist/api/index.js +59 -0
  9. package/dist/api/inscriptions/index.d.ts +25 -0
  10. package/dist/api/inscriptions/index.js +98 -0
  11. package/dist/api/locks/index.d.ts +47 -0
  12. package/dist/api/locks/index.js +291 -0
  13. package/dist/api/ordinals/index.d.ts +102 -0
  14. package/dist/api/ordinals/index.js +566 -0
  15. package/dist/api/payments/index.d.ts +48 -0
  16. package/dist/api/payments/index.js +185 -0
  17. package/dist/api/signing/index.d.ts +35 -0
  18. package/dist/api/signing/index.js +78 -0
  19. package/dist/api/skills/registry.d.ts +61 -0
  20. package/dist/api/skills/registry.js +74 -0
  21. package/dist/api/skills/types.d.ts +71 -0
  22. package/dist/api/skills/types.js +14 -0
  23. package/dist/api/tokens/index.d.ts +87 -0
  24. package/dist/api/tokens/index.js +457 -0
  25. package/dist/cwi/chrome.d.ts +11 -0
  26. package/dist/cwi/chrome.js +39 -0
  27. package/dist/cwi/event.d.ts +11 -0
  28. package/dist/cwi/event.js +38 -0
  29. package/dist/cwi/factory.d.ts +14 -0
  30. package/dist/cwi/factory.js +44 -0
  31. package/dist/cwi/index.d.ts +11 -0
  32. package/dist/cwi/index.js +11 -0
  33. package/dist/cwi/types.d.ts +39 -0
  34. package/dist/cwi/types.js +39 -0
  35. package/dist/index.d.ts +3 -1
  36. package/dist/index.js +7 -1
  37. package/dist/indexers/CosignIndexer.js +1 -0
  38. package/dist/indexers/InscriptionIndexer.js +3 -4
  39. package/dist/indexers/LockIndexer.js +1 -0
  40. package/dist/indexers/OrdLockIndexer.js +1 -0
  41. package/dist/indexers/OriginIndexer.js +1 -1
  42. package/dist/indexers/index.d.ts +1 -1
  43. package/dist/indexers/types.d.ts +18 -0
  44. package/dist/services/OneSatServices.d.ts +19 -10
  45. package/dist/services/OneSatServices.js +201 -39
  46. package/dist/services/client/ChaintracksClient.d.ts +55 -13
  47. package/dist/services/client/ChaintracksClient.js +123 -28
  48. package/dist/services/client/OrdfsClient.d.ts +2 -2
  49. package/dist/services/client/OrdfsClient.js +4 -3
  50. package/dist/services/client/TxoClient.js +9 -0
  51. package/dist/sync/AddressManager.d.ts +85 -0
  52. package/dist/sync/AddressManager.js +107 -0
  53. package/dist/sync/SyncManager.d.ts +207 -0
  54. package/dist/sync/SyncManager.js +507 -0
  55. package/dist/sync/index.d.ts +4 -0
  56. package/dist/sync/index.js +2 -0
  57. package/dist/wallet/factory.d.ts +64 -0
  58. package/dist/wallet/factory.js +129 -0
  59. package/dist/wallet/index.d.ts +1 -0
  60. package/dist/wallet/index.js +1 -0
  61. package/package.json +14 -4
  62. package/dist/OneSatWallet.d.ts +0 -316
  63. package/dist/OneSatWallet.js +0 -956
  64. package/dist/indexers/TransactionParser.d.ts +0 -53
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Factory for creating web wallets.
3
+ *
4
+ * This consolidates the common wallet setup used by both yours-wallet
5
+ * (browser extension) and 1sat-website (React app).
6
+ */
7
+ import { KeyDeriver, PrivateKey } from "@bsv/sdk";
8
+ import { Wallet, WalletStorageManager, StorageProvider, StorageIdb, StorageClient, WalletPermissionsManager, Services, Monitor, } from "@bsv/wallet-toolbox-mobile/out/src/index.client.js";
9
+ import { OneSatServices } from "../services/OneSatServices";
10
+ // Default database name for IndexedDB storage
11
+ const DEFAULT_DATABASE_NAME = "wallet";
12
+ // Default timeout for remote storage connection
13
+ const DEFAULT_REMOTE_STORAGE_TIMEOUT = 5000;
14
+ // Default fee model
15
+ const DEFAULT_FEE_MODEL = { model: "sat/kb", value: 1 };
16
+ /**
17
+ * Parse a private key from various input formats.
18
+ * Supports PrivateKey instance, WIF string, or hex string.
19
+ */
20
+ function parsePrivateKey(input) {
21
+ if (input instanceof PrivateKey) {
22
+ return input;
23
+ }
24
+ // Try WIF first (starts with 5, K, L for mainnet or c for testnet)
25
+ if (/^[5KLc][1-9A-HJ-NP-Za-km-z]{50,51}$/.test(input)) {
26
+ return PrivateKey.fromWif(input);
27
+ }
28
+ // Try hex (64 characters)
29
+ if (/^[0-9a-fA-F]{64}$/.test(input)) {
30
+ return new PrivateKey(input);
31
+ }
32
+ // Last resort - try WIF anyway
33
+ try {
34
+ return PrivateKey.fromWif(input);
35
+ }
36
+ catch {
37
+ throw new Error("Invalid private key format. Expected PrivateKey instance, WIF string, or 64-char hex string.");
38
+ }
39
+ }
40
+ /**
41
+ * Create a web wallet with storage, services, permissions, and monitor.
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * const { wallet, services, monitor, destroy } = await createWebWallet({
46
+ * privateKey: identityWif,
47
+ * chain: 'main',
48
+ * adminOriginator: 'https://wallet.example.com',
49
+ * permissionsConfig: DEFAULT_PERMISSIONS_CONFIG,
50
+ * });
51
+ *
52
+ * // Wire up monitor callbacks
53
+ * monitor.onTransactionProven = async (status) => console.log('Proven:', status.txid);
54
+ *
55
+ * // Start monitor when ready
56
+ * monitor.startTasks();
57
+ * ```
58
+ */
59
+ export async function createWebWallet(config) {
60
+ const { chain, adminOriginator, permissionsConfig } = config;
61
+ const feeModel = config.feeModel ?? DEFAULT_FEE_MODEL;
62
+ // 1. Parse private key and create KeyDeriver
63
+ const privateKey = parsePrivateKey(config.privateKey);
64
+ const identityPubKey = privateKey.toPublicKey().toString();
65
+ const keyDeriver = new KeyDeriver(privateKey);
66
+ // 2. Create fallback services and OneSatServices
67
+ const fallbackServices = new Services(chain);
68
+ const oneSatServices = new OneSatServices(chain, undefined, fallbackServices);
69
+ // 3. Create local storage
70
+ const storageOptions = StorageProvider.createStorageBaseOptions(chain);
71
+ storageOptions.feeModel = feeModel;
72
+ const localStorage = new StorageIdb(storageOptions);
73
+ await localStorage.migrate(DEFAULT_DATABASE_NAME, identityPubKey);
74
+ // 4. Create storage manager (local-only initially)
75
+ let storage = new WalletStorageManager(identityPubKey, localStorage);
76
+ await storage.makeAvailable();
77
+ // 5. Create the underlying Wallet
78
+ const underlyingWallet = new Wallet({
79
+ chain,
80
+ keyDeriver,
81
+ storage,
82
+ services: oneSatServices,
83
+ });
84
+ // 6. Attempt remote storage connection if URL provided
85
+ if (config.remoteStorageUrl) {
86
+ try {
87
+ const remoteClient = new StorageClient(underlyingWallet, config.remoteStorageUrl);
88
+ const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("Remote storage connection timeout")), DEFAULT_REMOTE_STORAGE_TIMEOUT));
89
+ await Promise.race([remoteClient.makeAvailable(), timeoutPromise]);
90
+ // Remote connected - recreate storage manager with backup
91
+ storage = new WalletStorageManager(identityPubKey, localStorage, [
92
+ remoteClient,
93
+ ]);
94
+ await storage.makeAvailable();
95
+ // Update wallet's storage reference
96
+ underlyingWallet._storage = storage;
97
+ }
98
+ catch {
99
+ // Graceful degradation - continue with local only
100
+ }
101
+ }
102
+ // 7. Wrap with permissions manager
103
+ const wallet = new WalletPermissionsManager(underlyingWallet, adminOriginator, permissionsConfig);
104
+ // 8. Create monitor (not started - consumer calls startTasks() when ready)
105
+ const monitor = new Monitor({
106
+ chain,
107
+ services: oneSatServices,
108
+ storage,
109
+ chaintracks: oneSatServices.chaintracks,
110
+ msecsWaitPerMerkleProofServiceReq: 500,
111
+ taskRunWaitMsecs: 5000,
112
+ abandonedMsecs: 300000,
113
+ unprovenAttemptsLimitTest: 10,
114
+ unprovenAttemptsLimitMain: 144,
115
+ });
116
+ monitor.addDefaultTasks();
117
+ // 9. Create cleanup function
118
+ const destroy = async () => {
119
+ monitor.stopTasks();
120
+ await monitor.destroy();
121
+ await underlyingWallet.destroy();
122
+ };
123
+ return {
124
+ wallet,
125
+ services: oneSatServices,
126
+ monitor,
127
+ destroy,
128
+ };
129
+ }
@@ -0,0 +1 @@
1
+ export * from "./factory";
@@ -0,0 +1 @@
1
+ export * from "./factory";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1sat/wallet-toolbox",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
4
4
  "description": "BSV wallet library extending @bsv/wallet-toolbox with 1Sat Ordinals protocol support",
5
5
  "author": "1Sat Team",
6
6
  "license": "MIT",
@@ -37,14 +37,24 @@
37
37
  "tester": "bun run build && bun run tester:build && bun ./tester/server.ts"
38
38
  },
39
39
  "dependencies": {
40
- "@bopen-io/templates": "^1.1.2",
41
- "@bsv/sdk": "^1.9.29",
40
+ "@bopen-io/templates": "^1.1.4",
41
+ "@bsv/sdk": "^1.9.31",
42
42
  "buffer": "^6.0.3"
43
43
  },
44
+ "peerDependencies": {
45
+ "@bsv/wallet-toolbox-mobile": "npm:@bopen-io/wallet-toolbox-mobile@^1.7.19"
46
+ },
47
+ "peerDependenciesMeta": {
48
+ "@bsv/wallet-toolbox-mobile": {
49
+ "optional": true
50
+ }
51
+ },
44
52
  "devDependencies": {
45
53
  "@biomejs/biome": "^1.9.4",
46
- "@bsv/wallet-toolbox": "^1.7.18",
54
+ "@bsv/wallet-toolbox": "npm:@bopen-io/wallet-toolbox@^1.7.19",
55
+ "@bsv/wallet-toolbox-mobile": "npm:@bopen-io/wallet-toolbox-mobile@^1.7.19",
47
56
  "@types/bun": "^1.3.4",
57
+ "@types/chrome": "^0.1.32",
48
58
  "typescript": "^5.9.3"
49
59
  }
50
60
  }
@@ -1,316 +0,0 @@
1
- import { Transaction, type WalletInterface } from "@bsv/sdk";
2
- import type { WalletStorageManager, sdk as toolboxSdk } from "@bsv/wallet-toolbox";
3
- type Chain = toolboxSdk.Chain;
4
- import { Outpoint } from "./indexers/Outpoint";
5
- import type { Indexer, ParseContext, Txo } from "./indexers/types";
6
- import { OneSatServices } from "./services/OneSatServices";
7
- import type { SyncQueueStorage } from "./sync/types";
8
- /**
9
- * Result of ingestTransaction including parse context for debugging
10
- */
11
- export interface IngestResult {
12
- parseContext: ParseContext;
13
- internalizedCount: number;
14
- }
15
- /**
16
- * Events emitted by OneSatWallet during sync operations
17
- */
18
- export interface OneSatWalletEvents {
19
- /** Sync started */
20
- "sync:start": {
21
- addresses: string[];
22
- };
23
- /** Sync progress update */
24
- "sync:progress": {
25
- pending: number;
26
- done: number;
27
- failed: number;
28
- };
29
- /** Sync complete (queue empty and stream done) */
30
- "sync:complete": Record<string, never>;
31
- /** Sync error */
32
- "sync:error": {
33
- message: string;
34
- };
35
- }
36
- type EventCallback<T> = (event: T) => void;
37
- export interface OneSatWalletArgs {
38
- /**
39
- * The underlying BRC-100 wallet to wrap.
40
- */
41
- wallet: WalletInterface;
42
- /**
43
- * The storage manager from the wallet (needed for direct storage access).
44
- */
45
- storage: WalletStorageManager;
46
- /**
47
- * Network: 'main' or 'test'
48
- */
49
- chain: Chain;
50
- /**
51
- * Addresses owned by this wallet, used for filtering indexed outputs.
52
- */
53
- owners?: Set<string>;
54
- /**
55
- * Indexers to use for parsing transactions.
56
- * If not provided, default indexers will be used.
57
- */
58
- indexers?: Indexer[];
59
- /**
60
- * Custom 1Sat API URL (default: based on chain - mainnet or testnet)
61
- */
62
- onesatUrl?: string;
63
- /**
64
- * Automatically start syncing all owner addresses on construction.
65
- */
66
- autoSync?: boolean;
67
- /**
68
- * Sync queue storage for background processing.
69
- * If provided, enables queue-based sync via sync() method.
70
- */
71
- syncQueue?: SyncQueueStorage;
72
- /**
73
- * Batch size for queue processing (default: 20).
74
- */
75
- syncBatchSize?: number;
76
- }
77
- /**
78
- * OneSatWallet wraps a BRC-100 Wallet with 1Sat-specific indexing and services.
79
- *
80
- * The consumer is responsible for constructing the underlying Wallet with
81
- * the appropriate storage and key derivation for their environment.
82
- */
83
- export declare class OneSatWallet implements WalletInterface {
84
- private readonly wallet;
85
- private readonly storage;
86
- private readonly indexers;
87
- readonly services: OneSatServices;
88
- private owners;
89
- private listeners;
90
- private syncQueue;
91
- private syncBatchSize;
92
- private syncRunning;
93
- private syncStopRequested;
94
- private activeQueueSync;
95
- private sseStreamActive;
96
- private sseUnsubscribe;
97
- private processorActive;
98
- private processorStopRequested;
99
- private streamDone;
100
- constructor(args: OneSatWalletArgs);
101
- getPublicKey: WalletInterface["getPublicKey"];
102
- revealCounterpartyKeyLinkage: WalletInterface["revealCounterpartyKeyLinkage"];
103
- revealSpecificKeyLinkage: WalletInterface["revealSpecificKeyLinkage"];
104
- encrypt: WalletInterface["encrypt"];
105
- decrypt: WalletInterface["decrypt"];
106
- createHmac: WalletInterface["createHmac"];
107
- verifyHmac: WalletInterface["verifyHmac"];
108
- createSignature: WalletInterface["createSignature"];
109
- verifySignature: WalletInterface["verifySignature"];
110
- createAction: WalletInterface["createAction"];
111
- signAction: WalletInterface["signAction"];
112
- abortAction: WalletInterface["abortAction"];
113
- listActions: WalletInterface["listActions"];
114
- internalizeAction: WalletInterface["internalizeAction"];
115
- listOutputs: WalletInterface["listOutputs"];
116
- relinquishOutput: WalletInterface["relinquishOutput"];
117
- acquireCertificate: WalletInterface["acquireCertificate"];
118
- listCertificates: WalletInterface["listCertificates"];
119
- proveCertificate: WalletInterface["proveCertificate"];
120
- relinquishCertificate: WalletInterface["relinquishCertificate"];
121
- discoverByIdentityKey: WalletInterface["discoverByIdentityKey"];
122
- discoverByAttributes: WalletInterface["discoverByAttributes"];
123
- isAuthenticated: WalletInterface["isAuthenticated"];
124
- waitForAuthentication: WalletInterface["waitForAuthentication"];
125
- getHeight: WalletInterface["getHeight"];
126
- getHeaderForHeight: WalletInterface["getHeaderForHeight"];
127
- getNetwork: WalletInterface["getNetwork"];
128
- getVersion: WalletInterface["getVersion"];
129
- /**
130
- * Subscribe to wallet events
131
- */
132
- on<K extends keyof OneSatWalletEvents>(event: K, callback: EventCallback<OneSatWalletEvents[K]>): void;
133
- /**
134
- * Unsubscribe from wallet events
135
- */
136
- off<K extends keyof OneSatWalletEvents>(event: K, callback: EventCallback<OneSatWalletEvents[K]>): void;
137
- /**
138
- * Emit a wallet event
139
- */
140
- private emit;
141
- /**
142
- * Add an address to the set of owned addresses.
143
- * Outputs to these addresses will be indexed.
144
- */
145
- addOwner(address: string): void;
146
- /**
147
- * Parse a transaction through indexers without internalizing.
148
- *
149
- * This is useful for debugging/testing to see what the indexers produce
150
- * without actually storing the transaction in the wallet.
151
- *
152
- * @param tx - Transaction or txid to parse
153
- * @param isBroadcasted - Whether this transaction has been broadcast
154
- * @returns ParseContext with all indexer data
155
- */
156
- parseTransaction(txOrTxid: Transaction | string, isBroadcasted?: boolean): Promise<ParseContext>;
157
- /**
158
- * Parse a single output without full transaction context.
159
- * Runs all indexers' parse() methods but NOT summarize().
160
- *
161
- * @param output - The TransactionOutput to parse
162
- * @param outpoint - The outpoint identifying this output
163
- * @returns Txo with all indexer data populated
164
- */
165
- parseOutput(output: Transaction["outputs"][0], outpoint: Outpoint): Promise<Txo>;
166
- /**
167
- * Load and parse a single output by outpoint.
168
- * Loads the transaction, extracts the output, and runs indexers on it.
169
- *
170
- * @param outpoint - Outpoint string (txid_vout)
171
- * @returns Txo with all indexer data populated
172
- */
173
- loadTxo(outpoint: string): Promise<Txo>;
174
- /**
175
- * Run all indexers on a single Txo and populate its data/owner/basket
176
- */
177
- runIndexersOnTxo(txo: Txo): Promise<void>;
178
- /**
179
- * Parse all inputs - run indexers on source outputs to populate ctx.spends
180
- */
181
- private parseInputs;
182
- /**
183
- * Load a transaction by txid.
184
- * Checks storage first, falls back to beef service.
185
- *
186
- * @param txid - Transaction ID to load
187
- * @returns Transaction (without source transactions hydrated)
188
- */
189
- loadTransaction(txid: string): Promise<Transaction>;
190
- /**
191
- * Load and attach source transactions for all inputs (1 level deep).
192
- * Modifies the transaction in place.
193
- */
194
- hydrateSourceTransactions(tx: Transaction): Promise<void>;
195
- /**
196
- * Build minimal parse context from transaction
197
- */
198
- buildParseContext(tx: Transaction): ParseContext;
199
- /**
200
- * Calculate the byte offset and length of each output's locking script
201
- * within the raw transaction binary. This is needed for wallet-toolbox's
202
- * listOutputs to extract locking scripts on demand.
203
- */
204
- private calculateScriptOffsets;
205
- /**
206
- * Ingest a transaction by running it through indexers and writing directly to storage.
207
- *
208
- * This is the main entry point for adding external transactions to the wallet.
209
- * The indexers extract basket, tags, and custom instructions which are then
210
- * written directly to the wallet's storage.
211
- *
212
- * Unlike internalizeAction, this method also marks any wallet outputs that are
213
- * consumed as inputs in the transaction as spent (spentBy, spendable: false).
214
- *
215
- * @param tx - Transaction to ingest
216
- * @param description - Human-readable description
217
- * @param labels - Optional labels for the transaction
218
- * @param isBroadcasted - Whether this transaction has been broadcast (affects validation)
219
- * @returns Result including parse details for all outputs
220
- */
221
- ingestTransaction(tx: Transaction, description: string, labels?: string[], isBroadcasted?: boolean): Promise<IngestResult>;
222
- /**
223
- * Broadcast a transaction and ingest it into the wallet if successful.
224
- *
225
- * @param tx - Transaction to broadcast
226
- * @param description - Human-readable description for the transaction
227
- * @param labels - Optional labels for the transaction
228
- * @returns The ingest result if successful
229
- * @throws Error if broadcast fails
230
- */
231
- broadcast(tx: Transaction, description: string, labels?: string[]): Promise<IngestResult>;
232
- /**
233
- * Start queue-based sync for all owner addresses.
234
- * Requires syncQueue to be provided in constructor args.
235
- *
236
- * This method:
237
- * 1. Opens SSE stream and enqueues outputs
238
- * 2. Processes queue in batches using Promise.all()
239
- * 3. Continues until queue is empty and stream is done
240
- */
241
- sync(): Promise<void>;
242
- /**
243
- * Handle a single output from the SSE stream.
244
- * Enqueues to the sync queue and updates lastQueuedScore with reorg protection.
245
- */
246
- private handleSyncOutput;
247
- /**
248
- * Process queue in batches until empty or stopped.
249
- */
250
- private processQueueLoop;
251
- /**
252
- * Group queue items by txid.
253
- * @deprecated - claim() now returns items already grouped
254
- */
255
- private groupItemsByTxid;
256
- /**
257
- * Process a single txid - ingest transaction and complete queue items.
258
- * Items are already marked as "processing" by claim().
259
- */
260
- private processTxid;
261
- /**
262
- * Ingest a transaction with knowledge of which outputs are already spent.
263
- */
264
- private ingestWithSpendInfo;
265
- /**
266
- * Mark outputs as spent for spend-only queue items.
267
- */
268
- private markOutputsSpent;
269
- /**
270
- * Stop the sync.
271
- */
272
- stopSync(): void;
273
- /**
274
- * Close the wallet and cleanup all sync connections.
275
- */
276
- close(): void;
277
- /**
278
- * Check if sync is currently running.
279
- */
280
- isSyncing(): boolean;
281
- /**
282
- * Get the sync queue instance (if provided).
283
- */
284
- getQueue(): SyncQueueStorage | null;
285
- /**
286
- * Start only the SSE stream, enqueueing outputs without processing.
287
- * Useful for testing to observe queue buildup.
288
- */
289
- startStream(): Promise<void>;
290
- /**
291
- * Stop the SSE stream.
292
- */
293
- stopStream(): void;
294
- /**
295
- * Check if SSE stream is active.
296
- */
297
- isStreamActive(): boolean;
298
- /**
299
- * Check if SSE stream has completed.
300
- */
301
- isStreamDone(): boolean;
302
- /**
303
- * Start only the queue processor, without starting a new SSE stream.
304
- * Useful for testing to process queued items independently.
305
- */
306
- startProcessor(): Promise<void>;
307
- /**
308
- * Stop the queue processor.
309
- */
310
- stopProcessor(): void;
311
- /**
312
- * Check if queue processor is active.
313
- */
314
- isProcessorActive(): boolean;
315
- }
316
- export {};