@1sat/wallet-toolbox 0.0.1

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/README.md ADDED
@@ -0,0 +1,301 @@
1
+ # @1sat/wallet-toolbox
2
+
3
+ A BSV wallet library extending [@bsv/wallet-toolbox](https://github.com/bitcoin-sv/ts-sdk) with 1Sat Ordinals protocol support. Implements BRC-100 wallet interface with indexed transaction ingestion and address synchronization.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @1sat/wallet-toolbox
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { OneSatWallet, StorageIdb, WalletStorageManager } from "@1sat/wallet-toolbox";
15
+ import { PrivateKey } from "@bsv/sdk";
16
+
17
+ // Create wallet with signing capability
18
+ const wallet = new OneSatWallet({
19
+ rootKey: PrivateKey.fromWif("..."),
20
+ storage: await WalletStorageManager.createWalletStorageManager(new StorageIdb("wallet")),
21
+ chain: "main",
22
+ owners: new Set(["1Address...", "1Another..."]),
23
+ });
24
+
25
+ // Sync wallet from the 1Sat indexer
26
+ await wallet.syncAll();
27
+
28
+ // Query outputs
29
+ const outputs = await wallet.listOutputs({ basket: "1sat" });
30
+ ```
31
+
32
+ ## Public Interface
33
+
34
+ ### OneSatWallet
35
+
36
+ Main wallet class extending `Wallet` from `@bsv/wallet-toolbox`.
37
+
38
+ ```typescript
39
+ import { OneSatWallet, StorageIdb, WalletStorageManager } from "@1sat/wallet-toolbox";
40
+ import { PrivateKey } from "@bsv/sdk";
41
+
42
+ // Full signing mode
43
+ const wallet = new OneSatWallet({
44
+ rootKey: PrivateKey.fromWif("..."),
45
+ storage: await WalletStorageManager.createWalletStorageManager(new StorageIdb("wallet")),
46
+ chain: "main",
47
+ owners: new Set(["1Address...", "1Another..."]),
48
+ });
49
+
50
+ // Read-only mode (public key only)
51
+ const readOnlyWallet = new OneSatWallet({
52
+ rootKey: "02abc123...", // public key hex
53
+ storage: storageManager,
54
+ chain: "main",
55
+ });
56
+ ```
57
+
58
+ #### Constructor Args
59
+
60
+ | Property | Type | Description |
61
+ |----------|------|-------------|
62
+ | `rootKey` | `string \| PrivateKey` | Public key hex (read-only) or PrivateKey (full signing) |
63
+ | `storage` | `WalletStorageManager` | Storage backend for wallet data |
64
+ | `chain` | `"main" \| "test"` | Network |
65
+ | `owners` | `Set<string>` | Optional. Addresses to filter indexed outputs |
66
+ | `ordfsUrl` | `string` | Optional. OrdFS server URL (default: `https://ordfs.network`) |
67
+ | `onesatUrl` | `string` | Optional. 1Sat indexer URL (default: based on chain) |
68
+
69
+ #### Properties
70
+
71
+ | Property | Type | Description |
72
+ |----------|------|-------------|
73
+ | `readOnly` | `boolean` | True if instantiated with public key only |
74
+
75
+ #### Methods
76
+
77
+ ##### `addOwner(address: string): void`
78
+ Add an address to the set of owned addresses for output filtering.
79
+
80
+ ##### `ingestTransaction(tx, description, labels?, isBroadcasted?): Promise<InternalizeActionResult>`
81
+ Ingest a transaction by running it through indexers, then internalizing via BRC-100.
82
+
83
+ | Parameter | Type | Description |
84
+ |-----------|------|-------------|
85
+ | `tx` | `Transaction` | Transaction to ingest |
86
+ | `description` | `string` | Human-readable description |
87
+ | `labels` | `string[]` | Optional labels |
88
+ | `isBroadcasted` | `boolean` | Default `true`. Affects validation |
89
+
90
+ ##### `broadcast(tx, description, labels?): Promise<InternalizeActionResult>`
91
+ Broadcast a transaction and ingest it into the wallet if successful.
92
+
93
+ | Parameter | Type | Description |
94
+ |-----------|------|-------------|
95
+ | `tx` | `Transaction` | Transaction to broadcast |
96
+ | `description` | `string` | Human-readable description |
97
+ | `labels` | `string[]` | Optional labels |
98
+
99
+ ##### `syncAddress(address: string, limit?: number): Promise<void>`
100
+ Sync a single address from the 1Sat indexer. Fetches new outputs and spends, ingesting transactions as needed. Progress is persisted to localStorage.
101
+
102
+ ##### `syncAll(): Promise<void>`
103
+ Sync all owner addresses in parallel.
104
+
105
+ ##### `on(event, callback): void`
106
+ Subscribe to wallet events. See [Events](#events) section.
107
+
108
+ ##### `off(event, callback): void`
109
+ Unsubscribe from wallet events.
110
+
111
+ ##### BRC-100 Methods (inherited from Wallet)
112
+ - `createAction()` - Create and sign transactions
113
+ - `internalizeAction()` - Import external transactions
114
+ - `listOutputs()` - Query wallet outputs
115
+ - `listActions()` - Query transaction history
116
+ - See [@bsv/wallet-toolbox](https://github.com/bitcoin-sv/ts-sdk) for full interface
117
+
118
+ #### Events
119
+
120
+ Subscribe to sync events using the `on` method:
121
+
122
+ ```typescript
123
+ wallet.on("sync:start", (event) => {
124
+ console.log(`Starting sync for ${event.address} from score ${event.fromScore}`);
125
+ });
126
+
127
+ wallet.on("sync:progress", (event) => {
128
+ console.log(`${event.address}: ${event.processed} processed, ${event.remaining} remaining`);
129
+ });
130
+
131
+ wallet.on("sync:tx", (event) => {
132
+ console.log(`${event.address}: ${event.type} tx ${event.txid}`);
133
+ });
134
+
135
+ wallet.on("sync:error", (event) => {
136
+ console.error(`${event.address}: ${event.error.message}`);
137
+ });
138
+
139
+ wallet.on("sync:complete", (event) => {
140
+ console.log(`${event.address}: completed, ${event.processed} transactions`);
141
+ });
142
+ ```
143
+
144
+ | Event | Payload | Description |
145
+ |-------|---------|-------------|
146
+ | `sync:start` | `{ address, fromScore }` | Sync started for an address |
147
+ | `sync:progress` | `{ address, processed, remaining, currentScore, done }` | Progress update |
148
+ | `sync:tx` | `{ address, txid, type }` | Transaction ingested (`type`: "output" or "spend") |
149
+ | `sync:error` | `{ address, error }` | Error during sync |
150
+ | `sync:complete` | `{ address, processed, finalScore }` | Sync completed |
151
+
152
+ ---
153
+
154
+ ### OneSatServices
155
+
156
+ WalletServices implementation for 1Sat ecosystem. Uses ordfs-server for blockchain data and OneSat API for broadcasting.
157
+
158
+ ```typescript
159
+ import { OneSatServices } from "@1sat/wallet-toolbox";
160
+
161
+ const services = new OneSatServices("main", "https://ordfs.network");
162
+ ```
163
+
164
+ #### Constructor Args
165
+
166
+ | Parameter | Type | Description |
167
+ |-----------|------|-------------|
168
+ | `chain` | `"main" \| "test"` | Network |
169
+ | `ordfsUrl` | `string` | Optional. OrdFS server URL (default: `https://ordfs.network`) |
170
+ | `onesatUrl` | `string` | Optional. 1Sat API URL (default: based on chain) |
171
+ | `storage` | `WalletStorageManager` | Optional. Storage for caching |
172
+
173
+ #### Methods
174
+
175
+ | Method | Description |
176
+ |--------|-------------|
177
+ | `getRawTx(txid)` | Fetch raw transaction bytes |
178
+ | `getMerklePath(txid)` | Fetch merkle proof |
179
+ | `postBeef(beef, txids)` | Broadcast transaction(s) |
180
+ | `getHeight()` | Get current chain height |
181
+ | `getHeaderForHeight(height)` | Get block header |
182
+ | `getChainTracker()` | Get ChainTracker for SPV validation |
183
+ | `getBeefBytes(txid)` | Get BEEF bytes for transaction |
184
+ | `getBeefForTxid(txid)` | Get BEEF object for transaction |
185
+ | `getOrdfsMetadata(outpoint)` | Get inscription metadata |
186
+ | `getBsv21TokenByTxid(tokenId, txid)` | Get BSV21 token data |
187
+ | `getBsv21TokenDetails(tokenId)` | Get BSV21 token metadata (cached) |
188
+
189
+ ---
190
+
191
+ ### ReadOnlySigner
192
+
193
+ KeyDeriver implementation for read-only wallet mode. Throws on any signing operation.
194
+
195
+ ```typescript
196
+ import { ReadOnlySigner } from "@1sat/wallet-toolbox";
197
+
198
+ const signer = new ReadOnlySigner("02abc123..."); // public key hex
199
+ ```
200
+
201
+ ---
202
+
203
+ ### Indexers
204
+
205
+ Transaction indexers that extract protocol-specific data for wallet storage. Each indexer identifies outputs by a **tag** (data identifier), optionally assigns a **basket** for output organization, and may add searchable **tags** for querying.
206
+
207
+ | Indexer | Tag | Basket | Tags | Description |
208
+ |---------|-----|--------|------|-------------|
209
+ | `FundIndexer` | `fund` | `fund` | - | Standard P2PKH outputs (>1 sat) |
210
+ | `LockIndexer` | `lock` | `lock` | - | Time-locked outputs |
211
+ | `InscriptionIndexer` | `insc` | - | - | 1Sat Ordinal inscriptions (preliminary data) |
212
+ | `OriginIndexer` | `origin` | `1sat` | `origin:{outpoint}`, `type:{category}`, `type:{base}`, `type:{full}` | Origin tracking via OrdFS |
213
+ | `Bsv21Indexer` | `bsv21` | `bsv21` | `id:{tokenId}`, `id:{tokenId}:{status}` | BSV21 token protocol |
214
+ | `OrdLockIndexer` | `list` | - | `ordlock` | OrdLock marketplace listings |
215
+ | `OpNSIndexer` | `opns` | `opns` | `name:{name}` | OPNS namespace protocol |
216
+ | `SigmaIndexer` | `sigma` | - | - | Sigma signatures |
217
+ | `MapIndexer` | `map` | - | - | MAP protocol data |
218
+ | `CosignIndexer` | `cosign` | - | - | Cosigner script data |
219
+
220
+ #### Baskets
221
+
222
+ Outputs are organized into baskets for querying via `listOutputs({ basket })`:
223
+
224
+ - **`fund`** - Standard funding UTXOs
225
+ - **`lock`** - Time-locked outputs
226
+ - **`1sat`** - 1Sat Ordinal outputs (non-token inscriptions)
227
+ - **`bsv21`** - BSV21 token outputs
228
+ - **`opns`** - OPNS namespace outputs
229
+
230
+ #### Tags
231
+
232
+ Tags enable filtered queries via `listOutputs({ tags })`. Tags are only added for owned outputs.
233
+
234
+ - **`origin:{outpoint}`** - Filter by origin outpoint
235
+ - **`type:{category}`** - Filter by content category (e.g., `type:image`, `type:text`)
236
+ - **`type:{base}`** - Filter by base MIME type without encoding (e.g., `type:image/png`)
237
+ - **`type:{full}`** - Filter by full MIME type including encoding (e.g., `type:image/png; charset=utf-8`)
238
+ - **`id:{tokenId}`** - Filter BSV21 by token ID
239
+ - **`id:{tokenId}:{status}`** - Filter BSV21 by token ID and status (`valid`, `invalid`, `pending`)
240
+ - **`ordlock`** - Filter for OrdLock listings
241
+ - **`name:{name}`** - Filter OPNS by name
242
+
243
+ ---
244
+
245
+ ### TransactionParser
246
+
247
+ Runs indexers over transactions to extract basket/tags for wallet-toolbox storage.
248
+
249
+ ```typescript
250
+ import { TransactionParser, FundIndexer, OriginIndexer } from "@1sat/wallet-toolbox";
251
+
252
+ const parser = new TransactionParser(
253
+ [new FundIndexer(owners, "mainnet"), new OriginIndexer(owners, "mainnet", services)],
254
+ owners,
255
+ services
256
+ );
257
+
258
+ const result = await parser.parse(transaction, true);
259
+ // result.outputs: ParsedOutput[] with vout, basket, tags, customInstructions
260
+ ```
261
+
262
+ ---
263
+
264
+ ## Project Status
265
+
266
+ ### Completed
267
+
268
+ - [x] OneSatWallet extending wallet-toolbox Wallet
269
+ - [x] Read-only mode via public key
270
+ - [x] OneSatServices (WalletServices implementation)
271
+ - [x] All indexers migrated from yours-wallet
272
+ - [x] TransactionParser for indexed ingestion
273
+ - [x] `ingestTransaction()` method
274
+ - [x] `syncAddress()` / `syncAll()` synchronization
275
+ - [x] Event system for sync progress
276
+ - [x] `broadcast()` method
277
+ - [x] `getChainTracker()` implementation
278
+
279
+ ### TODO
280
+
281
+ - [ ] Implement remaining OneSatServices methods:
282
+ - [ ] `getBsvExchangeRate()`
283
+ - [ ] `getFiatExchangeRate()`
284
+ - [ ] `getStatusForTxids()`
285
+ - [ ] `isUtxo()`
286
+ - [ ] `getUtxoStatus()`
287
+ - [ ] `getScriptHashHistory()`
288
+ - [ ] `hashToHeader()`
289
+ - [ ] `nLockTimeIsFinal()`
290
+ - [ ] Improve basket/tag extraction in TransactionParser
291
+ - [ ] Tests
292
+ - [ ] Integration with yours-wallet
293
+
294
+ ## Development
295
+
296
+ ```bash
297
+ bun install
298
+ bun run build
299
+ bun run lint
300
+ bun test
301
+ ```
@@ -0,0 +1,132 @@
1
+ import { Wallet, WalletStorageManager } from "@bsv/wallet-toolbox/mobile";
2
+ import type { Chain } from "@bsv/wallet-toolbox/mobile/out/src/sdk/types";
3
+ import { PrivateKey, Transaction, type InternalizeActionResult } from "@bsv/sdk";
4
+ export interface SyncStartEvent {
5
+ address: string;
6
+ fromScore: number;
7
+ }
8
+ export interface SyncProgressEvent {
9
+ address: string;
10
+ processed: number;
11
+ remaining: number;
12
+ currentScore: number;
13
+ done: boolean;
14
+ }
15
+ export interface SyncTxEvent {
16
+ address: string;
17
+ txid: string;
18
+ type: "output" | "spend";
19
+ }
20
+ export interface SyncErrorEvent {
21
+ address: string;
22
+ error: Error;
23
+ }
24
+ export interface SyncCompleteEvent {
25
+ address: string;
26
+ processed: number;
27
+ finalScore: number;
28
+ }
29
+ export interface OneSatWalletEvents {
30
+ "sync:start": SyncStartEvent;
31
+ "sync:progress": SyncProgressEvent;
32
+ "sync:tx": SyncTxEvent;
33
+ "sync:error": SyncErrorEvent;
34
+ "sync:complete": SyncCompleteEvent;
35
+ }
36
+ type EventCallback<T> = (event: T) => void;
37
+ export interface OneSatWalletArgs {
38
+ /**
39
+ * Either a public key hex string (read-only mode) or a PrivateKey (full signing).
40
+ */
41
+ rootKey: string | PrivateKey;
42
+ /**
43
+ * The storage manager for the wallet.
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
+ * Custom OrdFS server URL (default: https://ordfs.network)
56
+ */
57
+ ordfsUrl?: string;
58
+ /**
59
+ * Custom 1Sat indexer URL (default: based on chain - mainnet or testnet)
60
+ */
61
+ onesatUrl?: string;
62
+ }
63
+ /**
64
+ * OneSatWallet extends the BRC-100 Wallet with 1Sat-specific indexing and services.
65
+ *
66
+ * Can be instantiated with either:
67
+ * - A public key (read-only mode for queries)
68
+ * - A private key (full signing capability)
69
+ */
70
+ export declare class OneSatWallet extends Wallet {
71
+ private readonly isReadOnly;
72
+ private readonly parser;
73
+ private readonly oneSatServices;
74
+ private owners;
75
+ private listeners;
76
+ constructor(args: OneSatWalletArgs);
77
+ /**
78
+ * Returns true if this wallet was created with only a public key.
79
+ * Read-only wallets can query but not sign transactions.
80
+ */
81
+ get readOnly(): boolean;
82
+ /**
83
+ * Add an address to the set of owned addresses.
84
+ * Outputs to these addresses will be indexed.
85
+ */
86
+ addOwner(address: string): void;
87
+ /**
88
+ * Subscribe to wallet events.
89
+ */
90
+ on<K extends keyof OneSatWalletEvents>(event: K, callback: EventCallback<OneSatWalletEvents[K]>): void;
91
+ /**
92
+ * Unsubscribe from wallet events.
93
+ */
94
+ off<K extends keyof OneSatWalletEvents>(event: K, callback: EventCallback<OneSatWalletEvents[K]>): void;
95
+ private emit;
96
+ /**
97
+ * Ingest a transaction by running it through indexers and then internalizing.
98
+ *
99
+ * This is the main entry point for adding external transactions to the wallet.
100
+ * The indexers extract basket, tags, and custom instructions which are then
101
+ * passed to the underlying wallet's internalizeAction.
102
+ *
103
+ * @param tx - Transaction or BEEF to ingest
104
+ * @param description - Human-readable description
105
+ * @param labels - Optional labels for the transaction
106
+ * @param isBroadcasted - Whether this transaction has been broadcast (affects validation)
107
+ */
108
+ ingestTransaction(tx: Transaction, description: string, labels?: string[], isBroadcasted?: boolean): Promise<InternalizeActionResult>;
109
+ /**
110
+ * Broadcast a transaction and ingest it into the wallet if successful.
111
+ *
112
+ * @param tx - Transaction to broadcast
113
+ * @param description - Human-readable description for the transaction
114
+ * @param labels - Optional labels for the transaction
115
+ * @returns The internalize result if successful
116
+ * @throws Error if broadcast fails
117
+ */
118
+ broadcast(tx: Transaction, description: string, labels?: string[]): Promise<InternalizeActionResult>;
119
+ /**
120
+ * Sync a single address from the 1Sat indexer.
121
+ * Fetches new outputs and spends, ingesting transactions as needed.
122
+ *
123
+ * @param address - The address to sync
124
+ * @param limit - Max outputs per page (default 100)
125
+ */
126
+ syncAddress(address: string, limit?: number): Promise<void>;
127
+ /**
128
+ * Sync all owner addresses in parallel.
129
+ */
130
+ syncAll(): Promise<void>;
131
+ }
132
+ export {};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * HTTP error with status code for granular error handling
3
+ */
4
+ export declare class HttpError extends Error {
5
+ status: number;
6
+ constructor(status: number, message: string);
7
+ }
@@ -0,0 +1,7 @@
1
+ export { OneSatWallet, type OneSatWalletArgs, type OneSatWalletEvents, type SyncStartEvent, type SyncProgressEvent, type SyncTxEvent, type SyncErrorEvent, type SyncCompleteEvent, } from "./OneSatWallet";
2
+ export { OneSatServices, type OrdfsMetadata } from "./services/OneSatServices";
3
+ export { ReadOnlySigner } from "./signers/ReadOnlySigner";
4
+ export * from "./indexers";
5
+ export { WalletStorageManager } from "@bsv/wallet-toolbox/mobile";
6
+ export { StorageIdb } from "@bsv/wallet-toolbox/mobile/out/src/storage/StorageIdb";
7
+ export type { Chain } from "@bsv/wallet-toolbox/mobile/out/src/sdk/types";