bsv-wallet 0.11.0 → 0.100.0

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -523
  3. data/LICENSE +23 -80
  4. data/lib/bsv/network/chain_tracker.rb +80 -0
  5. data/lib/bsv/network/services.rb +311 -0
  6. data/lib/bsv/wallet/cli.rb +174 -0
  7. data/lib/bsv/wallet/daemon.rb +94 -0
  8. data/lib/bsv/wallet/engine.rb +1663 -0
  9. data/lib/bsv/wallet/errors.rb +44 -0
  10. data/lib/bsv/wallet/fetchable.rb +47 -0
  11. data/lib/bsv/wallet/interface/broadcast_queue.rb +55 -21
  12. data/lib/bsv/wallet/interface/proof_store.rb +35 -7
  13. data/lib/bsv/wallet/interface/store.rb +201 -66
  14. data/lib/bsv/wallet/interface/utxo_pool.rb +66 -12
  15. data/lib/bsv/wallet/interface.rb +4 -5
  16. data/lib/bsv/wallet/key_deriver.rb +492 -0
  17. data/lib/bsv/wallet/pushable.rb +45 -0
  18. data/lib/bsv/wallet/version.rb +1 -1
  19. data/lib/bsv/wallet.rb +32 -34
  20. metadata +16 -67
  21. data/lib/bsv/wallet/broadcast_queue/inline.rb +0 -202
  22. data/lib/bsv/wallet/broadcast_queue.rb +0 -28
  23. data/lib/bsv/wallet/client/brc100/authentication.rb +0 -28
  24. data/lib/bsv/wallet/client/brc100/crypto.rb +0 -314
  25. data/lib/bsv/wallet/client/brc100/identity.rb +0 -239
  26. data/lib/bsv/wallet/client/brc100/network.rb +0 -72
  27. data/lib/bsv/wallet/client/brc100/transaction.rb +0 -980
  28. data/lib/bsv/wallet/client/certificate_signature.rb +0 -212
  29. data/lib/bsv/wallet/client/change_generator.rb +0 -192
  30. data/lib/bsv/wallet/client/coin_selector.rb +0 -132
  31. data/lib/bsv/wallet/client/fee_estimator.rb +0 -140
  32. data/lib/bsv/wallet/client/fee_model.rb +0 -13
  33. data/lib/bsv/wallet/client/key_deriver.rb +0 -146
  34. data/lib/bsv/wallet/client/validators.rb +0 -206
  35. data/lib/bsv/wallet/client.rb +0 -255
  36. data/lib/bsv/wallet/errors/insufficient_funds_error.rb +0 -15
  37. data/lib/bsv/wallet/errors/invalid_hmac_error.rb +0 -11
  38. data/lib/bsv/wallet/errors/invalid_parameter_error.rb +0 -14
  39. data/lib/bsv/wallet/errors/invalid_signature_error.rb +0 -11
  40. data/lib/bsv/wallet/errors/pool_depleted_error.rb +0 -12
  41. data/lib/bsv/wallet/errors/unsupported_action_error.rb +0 -11
  42. data/lib/bsv/wallet/errors/wallet_error.rb +0 -14
  43. data/lib/bsv/wallet/interface/brc100.rb +0 -153
  44. data/lib/bsv/wallet/proof_store/local_proof_store.rb +0 -42
  45. data/lib/bsv/wallet/store/file.rb +0 -279
  46. data/lib/bsv/wallet/store/memory.rb +0 -382
  47. data/lib/bsv/wallet/store.rb +0 -19
  48. data/lib/bsv/wallet/substrates/http_wallet_json.rb +0 -268
  49. data/lib/bsv/wallet/substrates/http_wallet_wire.rb +0 -85
  50. data/lib/bsv/wallet/substrates/wallet_wire_transceiver.rb +0 -168
  51. data/lib/bsv/wallet/substrates.rb +0 -16
  52. data/lib/bsv/wallet/testing/shared_examples_for_storage_adapter.rb +0 -778
  53. data/lib/bsv/wallet/testing/shared_examples_for_wallet_operations.rb +0 -3701
  54. data/lib/bsv/wallet/testing/store_conformance.rb +0 -15
  55. data/lib/bsv/wallet/utxo_pool/local_pool.rb +0 -172
  56. data/lib/bsv/wallet/utxo_pool/replenishment_worker.rb +0 -183
  57. data/lib/bsv/wallet/wire/reader.rb +0 -238
  58. data/lib/bsv/wallet/wire/serializer.rb +0 -1993
  59. data/lib/bsv/wallet/wire/writer.rb +0 -214
  60. data/lib/bsv/wallet/wire.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 43a1c78810a0351eb11cf29575e9d2a9e8ffca2d5e844f8122bc28dc5dfffb02
4
- data.tar.gz: 358f2f7514b5d44f1896ec3ca6898cfb2e195142639711e787f545d27eda6f03
3
+ metadata.gz: 72c932682aed184499474a9973fe1127e43ca0e8cdda64546af2bea1976b6b6c
4
+ data.tar.gz: e7165b0bd2df8c93649020a815bd0f154cb4bedcc19828aa8fd0b2449b082eab
5
5
  SHA512:
6
- metadata.gz: c82bcf291d49346fd574d8bf442b690575f4b42d3c66e94a8262a32ceab596831d7c9b8c69a3617e5540f29e93417014f16979aa0e345eff0b48577de6ddf10e
7
- data.tar.gz: 8a5adfbe6bb90ea76d8478d181f3a453d5a9c4a15ad3a1f7eb833ef9d1b2862b5305d2dcaab016f4b10d83f5f091338f1e66c9ba3fdf0858f25597304d345308
6
+ metadata.gz: 52d5a757e7bf565d0c1189c9d2bf328e2773b8f27f45f1bcdce285e9051014a5948aa6625db80170b1542a924b75eb0cf0be4db983dc5364054fe1a4a85c5038
7
+ data.tar.gz: 72b403928501959aa29e843a3d2d500eab980b56b156bd44453c767458d915631c52e6d81802133cc2894349979dafefc9c3756b533cec05777f4b400bad9e78
data/CHANGELOG.md CHANGED
@@ -1,531 +1,26 @@
1
- # Changelog — bsv-wallet
1
+ # Changelog
2
2
 
3
- All notable changes to the `bsv-wallet` gem are documented here.
3
+ ## [0.100.0] - 2026-05-13
4
4
 
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
6
- and this gem adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ## 0.11.0 — 2026-04-22
9
-
10
- ### Added
11
- - `chain_data_source:` constructor param on `Client` — injectable chain
12
- data provider for local blockchain queries without a remote substrate
13
- - `sync_utxos` restored — discovers on-chain UTXOs via the chain data
14
- source and imports them into storage as `:spendable` with
15
- `derivation_type: :identity`. Deduplicates transaction fetches and
16
- validates UTXO API values against transaction outputs (#599)
17
- - `get_height` restored with local chain data fallback — returns
18
- `{ height: Integer }` without requiring a substrate (#597)
19
- - `get_header_for_height` restored with local chain data fallback —
20
- returns WoC block header JSON (#598)
21
- - BEEF SPV merkle root verification restored in `internalize_action`
22
- when a chain data source with `valid_root_for_height?` is available;
23
- error messages now distinguish SPV rejection from structural
24
- invalidity (#600)
25
- - Store conformance shared examples extracted to
26
- `lib/bsv/wallet/testing/` — downstream adapter gems can now
27
- `require 'bsv/wallet/testing/store_conformance'` for interface and
28
- wallet-level test coverage (#591)
29
-
30
- ### Changed
31
- - `MemoryStore` guarded in `Client.new` — raises `ArgumentError` unless
32
- `allow_memory_store: true` is passed, preventing accidental data loss
33
- in production
34
- - Wallet-level dual-store specs refactored to use shared examples via
35
- `it_behaves_like`; no test coverage lost (1281 examples preserved)
36
-
37
- ### Fixed
38
- - `sync_utxos` deduplicates UTXO response entries before processing
39
- and caches fetched transactions by txid to minimise WoC API calls
40
- - `internalize_action` chain tracker guard uses explicit nil check for
41
- clarity
42
- - Consistent error message wording across `get_height` and
43
- `get_header_for_height`
44
-
45
- ## 0.10.0 — 2026-04-21
46
-
47
- ### Added
48
- - BRC-100 abstract contract modules and `Client` with composition architecture
49
- - UTXO pool system: `UTXOPool` interface, `LocalPool` implementation, `ReplenishmentWorker`, and `utxo_pool` factory on Client
50
- - BRC-122 two-zone basket validation
51
- - `update_output_basket` on Store interface
52
-
53
- ### Changed
54
- - `ProtoWallet` and `WalletClient` deleted, replaced with `Client` using concern modules (`Transaction`, `Crypto`, `Identity`, `Network`, `Authentication`)
55
- - File paths renamed from `wallet_interface` to `wallet`
56
- - `Store` and `BroadcastQueue` collaborators namespaced under `Client`
57
- - Contracts moved under `Interface` namespace
58
- - Legacy `ChainProvider` classes removed
59
-
60
- ### Fixed
61
- - `internalize_payment` and `internalize_basket` now set `state: :spendable` explicitly on stored outputs
62
- - Derivation metadata now persisted in `store_tracked_outputs`
63
- - Cold start normalisation and eager validation fixes
64
- - SimpleCov coverage gate now requires `COVERAGE=true` explicitly
65
-
66
- ## 0.9.1 — 2026-04-16
67
-
68
- ### Changed
69
-
70
- - Raised `bsv-sdk` dependency floor to `>= 0.12.1` to pick up BEEF ancestry correctness fixes ([bsv-sdk#467](https://github.com/sgbett/bsv-ruby-sdk/issues/467), [bsv-sdk#468](https://github.com/sgbett/bsv-ruby-sdk/issues/468), HLR #466). Consumer impact: recently-received UTXOs that previously could not be re-broadcast now can — the wallet's `create_action` flow relies on `Transaction.from_beef` producing fully-wired ancestry, which the old SDK didn't do.
71
-
72
- ### Fixed
73
-
74
- - Removed redundant `store_transaction` call in `internalize_action` — `store_proofs_from_beef` already persists every transaction in the BEEF bundle, so the subject tx was being written twice. No behaviour change; minor cleanup. (#469)
75
-
76
- **Related:** [wallet-toolbox#149](https://github.com/bsv-blockchain/wallet-toolbox/issues/149) — same architectural gap reported upstream.
77
-
78
- ## 0.9.0 — 2026-04-16
79
-
80
- ### Changed — **Breaking**
81
-
82
- #### Action status taxonomy aligned with BRC-100 reference SDK (HLR #455)
83
-
84
- This release realigns the action status values with the wallet-toolbox reference
85
- implementation. The meaning of `'completed'` has changed — **consumers must
86
- update any code that checks for `'completed'` as the post-broadcast success
87
- state**.
88
-
89
- | Status | Old meaning | New meaning |
90
- |--------|-------------|-------------|
91
- | `'nosend'` | No change | Transaction built but not broadcast (`no_send: true`) |
92
- | `'sending'` | No change | Async queue accepted; worker has not yet attempted broadcast |
93
- | `'unproven'` | *(new)* | Broadcast succeeded; awaiting merkle proof |
94
- | `'completed'` | Broadcast succeeded | **Merkle proof received and stored** |
95
- | `'failed'` | No change | Broadcast rejected or transaction invalid |
96
-
97
- **Migration:**
98
-
99
- - Code querying `list_actions(status: 'completed')` will return fewer results
100
- until a proof-watcher is implemented (out of scope for this release). To find
101
- successfully-broadcast actions that have not yet received a proof, query
102
- `status: 'unproven'` instead.
103
- - `create_action` and `sign_action` now raise `BSV::Wallet::WalletError` when
104
- no broadcaster is configured and `options: { no_send: true }` is not set.
105
- Previously these calls succeeded silently. To resolve: pass
106
- `broadcaster: BSV::Network::ARC.default` to `WalletClient.new`, or pass
107
- `options: { no_send: true }` to `create_action` to build without
108
- broadcasting.
109
- - `internalize_action` now sets status to `'completed'` only when the supplied
110
- BEEF contains a merkle proof for the subject transaction. Plain BEEF (raw
111
- transaction, no BUMP) results in status `'unproven'`.
112
- - Wallets configured with a `SolidQueueAdapter` satisfy the broadcaster
113
- requirement if the adapter carries an embedded `broadcaster:` — the
114
- `WalletClient` itself does not need one.
115
-
116
- **Related upstream incidents:** x402-rack #148, x402-rack #158, x402-doom #196.
117
- **Tracking issue:** #455.
118
-
119
- ## 0.8.0 — 2026-04-15
120
-
121
- ### Added
122
- - BRC-100 substrates: `HTTPWalletJSON` for JSON-over-HTTP, `HTTPWalletWire`
123
- for binary transport, and `WalletWireTransceiver` Interface adapter (#449–#451)
124
- - `WalletClient` accepts `substrate:` constructor param for remote wallet
125
- delegation — all Interface methods delegate to the substrate when set (#452)
126
- - `list_actions` and `list_outputs` honour `include_labels`, `include_inputs`,
127
- and `include_outputs` flags (#448)
128
- - `acquire_certificate` uses `AuthFetch` for BRC-104 authenticated certificate
129
- issuance (#453)
130
-
131
- ### Fixed
132
- - `prove_certificate` now uses correct protocol ID (`'certificate field encryption'`)
133
- and key ID format (`"#{serial_number} #{field_name}"`) matching TS/Go SDKs —
134
- previously incompatible cross-SDK (#424)
135
- - Code review findings addressed for substrates and include flags
136
-
137
- ### Changed
138
- - `BSV::WalletInterface` module removed — `VERSION` now lives in `BSV::Wallet::VERSION`
139
- where all other wallet constants already reside
140
-
141
- ## 0.7.0 — 2026-04-12
142
-
143
- ### Added
144
- - Pluggable `BroadcastQueue` interface module — duck-typed, follows the `StorageAdapter` pattern
145
- - `InlineQueue` synchronous default adapter — consolidates broadcast and no-broadcaster paths
146
- - `WalletClient` accepts `broadcast_queue:` constructor parameter (auto-creates `InlineQueue` when not provided)
147
- - `BroadcastQueue.status_for_error` shared helper for consistent broadcast error mapping
148
- - Integration specs for broadcast/rollback flows (20 specs)
149
- - MemoryStore production warning — logs to stderr when `RACK_ENV`/`RAILS_ENV` is `production` or `staging`
150
-
151
- ### Fixed
152
- - TOCTOU window on change outputs — stored as `:pending` directly, eliminating race with concurrent `auto_fund`
153
- - Broadcast promotion failure no longer deletes confirmed on-chain outputs — only broadcast failure triggers rollback
154
-
155
- ### Changed
156
- - `accept_delayed_broadcast: true` no longer logs "not yet implemented" warning — handled by the queue adapter
157
- - MemoryStore demoted to test/development only (production use triggers a suppressible warning)
158
-
159
- ## 0.6.0 — 2026-04-12
160
-
161
- ### Added
162
- - Broadcast-before-promote semantics for `create_action` — transactions are
163
- broadcast via a configurable `broadcaster:` before promoting state, with
164
- automatic rollback on failure to prevent phantom UTXOs (#369, #371)
165
- - `send_with` for batched broadcast of previously `no_send` transactions,
166
- with per-transaction rollback on failure (#373)
167
- - `accept_delayed_broadcast` option accepted as a stub (defaults to `false`;
168
- background broadcasting deferred to a follow-up) (#374)
169
- - `delete_action` and `update_action_status` on `StorageAdapter`, implemented
170
- in MemoryStore, FileStore, and PostgresStore (#370)
171
- - Broadcast results mapped to `ReviewActionResultStatus` (`success`,
172
- `doubleSpend`, `invalidTx`, `serviceError`) and returned in the result
173
- hash (#372)
174
-
175
- ### Fixed
176
- - EF version marker overhead corrected from 2 to 6 bytes in fee estimation
177
- - Fee estimation now includes EF overhead for ARC compatibility
178
- - `FeeEstimator` default raised from 1 sat/kB to 100 sat/kB
179
- - `internalize_payment` now stores outputs in the default basket
180
- - `derivation_type` comparison uses string comparison for JSON round-trip
181
- safety (#367)
182
-
183
- ### Changed
184
- - Extracted `DEFAULT_SATS_PER_KB` constant for fee estimation
185
- - Specs reorganised into per-gem directories (#363)
186
-
187
- ## 0.5.1 — 2026-04-11
188
-
189
- ### Fixed
190
-
191
- - **Auto-fund coin selection and change use default basket** (#344):
192
- coin selection and change generation now correctly target the `default`
193
- basket, matching TS SDK behaviour. Previously, auto-funded transactions
194
- could select UTXOs from or generate change into the wrong basket.
195
- - **Normalise protocol name in KeyDeriver** (#262, #263): `compute_invoice_number`
196
- now applies `.downcase.strip` to the protocol name before building the
197
- invoice string, matching TS and Go SDK behaviour. Mixed-case or
198
- whitespace-padded protocol names previously derived different keys.
199
-
200
- ### Changed
201
-
202
- - **SDK dependency floor raised** to `bsv-sdk >= 0.10.0` (from 0.9.0)
203
- to pick up the KeyDeriver normalisation fix in the SDK layer.
204
-
205
- ---
206
-
207
- ## 0.5.0 — 2026-04-11
208
-
209
- Native UTXO management, coin selection, and automatic change handling.
210
- The wallet can now fund transactions end-to-end without an external
211
- wallet server — `create_action` with outputs but no inputs triggers
212
- automatic UTXO selection, fee estimation, and change generation.
213
-
214
- ### Added
215
-
216
- - **UTXO management pipeline** (#264, #265–#272): complete transaction-
217
- funding pipeline with `CoinSelector` (exact-match, smallest-sufficient,
218
- largest-first strategies), `ChangeGenerator` (BRC-29 multi-output change
219
- with dust consolidation, randomised splits, pool-health-aware output
220
- caps), and `FeeEstimator` (size-based sats/kB with ceil rounding).
221
- - **`WhatsOnChainProvider`**: chain UTXO discovery via the WhatsOnChain API,
222
- implementing `sync_utxos` for on-chain balance loading.
223
- - **StorageAdapter extensions**: 6 new interface methods —
224
- `update_output_state`, `lock_utxos`, `find_spendable_outputs`,
225
- `release_stale_pending!`, `store_setting`, `find_setting`. All default
226
- to `NotImplementedError`; `MemoryStore` and `FileStore` implement them.
227
- - **Atomic UTXO locking**: `lock_utxos` checks and marks outputs as
228
- `:pending` within a single mutex hold, closing the TOCTOU race where two
229
- threads could select the same UTXO.
230
- - **Pending state management**: outputs transition through `:spendable` →
231
- `:pending` → `:spent`, with timestamps and caller references for stale
232
- lock recovery.
233
- - **Auto-funding in `create_action`**: when given outputs without inputs,
234
- the wallet selects UTXOs, estimates fees, generates change outputs, and
235
- locks inputs automatically.
236
- - **`set_wallet_change_params`**: configures target UTXO count and value
237
- for the change pool.
238
-
239
- ### Fixed
240
-
241
- - **Identity UTXO filter alignment**: `sync_utxos` stores
242
- `derivation_type: :identity` but auto-fund filtered on a field that was
243
- never set. Fixed the filter and added a signing branch that uses
244
- `root_key` directly for identity UTXOs.
245
- - **`tx_pos` bounds validation in `sync_utxos`**: untrusted WhatsOnChain
246
- API responses with negative or out-of-bounds `tx_pos` could exploit
247
- Ruby's negative array indexing or raise `NoMethodError` on nil. Now
248
- validates before use.
249
- - **Stale pending recovery rate-limited**: `release_stale_pending!` now
250
- skips if invoked within 30 seconds, preventing O(n) output scans on
251
- every `create_action` call.
252
- - **`no_send` change outputs stored as `:pending`**, matching the TS SDK
253
- where `noSend` outputs have `spendable: false`. Prevents them from
254
- being auto-selected by concurrent `create_action` calls.
255
- - **`abort_action` cleans up change outputs** created by the aborted
256
- transaction, matching TS SDK behaviour.
257
- - **Nil state guard**: `effective_state` handles `state: nil` (from NULL
258
- DB column) without raising `NoMethodError`.
259
- - **`change_params` wiring**: stored change params and pool size are now
260
- wired into `converge_change` so `set_wallet_change_params` actually
261
- affects auto-fund output count.
262
-
263
- ### Changed
264
-
265
- - **`FeeModel` consolidated into `FeeEstimator`**: `FeeModel` is now a
266
- backward-compatible alias for `FeeEstimator`, which is the canonical
267
- implementation with dust floor, varint handling, and extra-bytes
268
- support.
269
- - **`BRC29_PROTOCOL_ID` constant** replaces hardcoded protocol ID in
270
- `internalize_payment`.
271
-
272
- ## 0.4.0 — 2026-04-10
273
-
274
- ### Added
275
-
276
- - **Protocol-ID normalisation** (F8.7): `Validators.validate_protocol_id!` now
277
- strips and downcases the name before applying rules, so `' MyProtocol '` and
278
- `'myprotocol'` are treated identically and cannot silently fork to different
279
- key-derivation paths.
280
- - **Permission-rule constants** (F8.8): Reserved prefix/suffix strings are now
281
- named constants on `BSV::Wallet::Validators` (`RESERVED_PROTOCOL_PREFIXES`,
282
- `RESERVED_PROTOCOL_SUFFIX`, `RESERVED_BASKET_PREFIXES`, `RESERVED_BASKET_SUFFIX`,
283
- `RESERVED_BASKET_NAME`), making them discoverable and documentable.
284
- - **BEEF verification in `internalize_action`** (F8.14): The BEEF bundle is now
285
- verified via `Beef#verify` before any outputs are stored. If the bundle is
286
- structurally invalid, a `WalletError` is raised rather than storing unverified
287
- data. When the chain provider supports `valid_root_for_height?`, full SPV
288
- verification is performed.
289
- - **Depth cap and cycle detection in `wire_source_tx_ancestors`** (F8.18):
290
- Recursion is now bounded by `WalletClient::ANCESTOR_DEPTH_CAP` (64 levels)
291
- and a visited-txid `Set`, preventing stack overflow on deep or cyclic
292
- transaction ancestry chains.
293
-
294
- ### Changed
295
-
296
- - **`ProtoWallet#create_signature` default counterparty** (P305.1): The default
297
- value for `counterparty` has changed from `'self'` to `'anyone'`, matching the
298
- behaviour of `ts-sdk`'s `ProtoWallet.createSignature`. Callers that rely on
299
- the `'self'` derivation path when omitting `counterparty:` must now pass
300
- `counterparty: 'self'` explicitly.
301
-
302
- ### Migration notes
303
-
304
- **P305.1 — `create_signature` counterparty default change (breaking)**
305
-
306
- Previously, calling `wallet.create_signature({ protocol_id: ..., key_id: ...,
307
- data: ... })` without a `counterparty:` key would derive using `'self'`. It now
308
- derives using `'anyone'`. This changes the resulting private key and therefore
309
- the signature. If your application omits `counterparty:`, add
310
- `counterparty: 'self'` to preserve the old behaviour.
311
-
312
- **F8.14 — BEEF verification now mandatory in `internalize_action`**
313
-
314
- Calls to `internalize_action` that previously succeeded with a malformed or
315
- unverifiable BEEF will now raise `BSV::Wallet::WalletError`. In practice this
316
- only affects callers passing synthetic or hand-crafted BEEF bytes; legitimate
317
- BEEF produced by `create_action` or broadcast round-trips will continue to work.
5
+ First release of the Ruby BRC-100 wallet — ground-up implementation.
318
6
 
319
7
  ### Added
8
+ - **BRC-100 Engine** — full transaction lifecycle: createAction, signAction, internalizeAction, abortAction, listActions, listOutputs, relinquishOutput
9
+ - **Key derivation** — BRC-42 ECDH key derivation, BRC-43 symmetric encryption, HMAC, ECDSA sign/verify
10
+ - **Certificates** — BRC-52 identity certificates with field-level encryption and selective revelation
11
+ - **Auto-funded transactions** — UTXO selection, fee estimation, change outputs with split-eagerness
12
+ - **SPV verification** — incoming BEEF validated via SDK `Transaction#verify` with chain tracker
13
+ - **BSV::Network::ChainTracker** — write-through block header cache (DB + network services)
14
+ - **BSV::Network::Services** — porcelain routing layer with fallback, rate limiting, response normalization
15
+ - **Pushable/Fetchable modules** — entity-driven network interaction for broadcast and proof lifecycle
16
+ - **Daemon** — background polling loop driving push!/fetch! on unresolved entities
17
+ - **UTXOPool** — sizing strategy with limp mode safety threshold
18
+ - **Porcelain CLI** — bin/create, bin/receive, bin/import, bin/send_payment
19
+ - **wtxid/dtxid convention** — binary wire-order internally, display hex at boundaries
320
20
 
321
- - **Shared conformance suite** for `StorageAdapter`
322
- implementations at `spec/support/shared_examples_for_storage_adapter.rb`.
323
- `MemoryStore` and `FileStore` now both drive their behavioural
324
- tests through `it_behaves_like 'a storage adapter'`, and the
325
- extraction backfilled previously-missing coverage (certificate
326
- `:attributes` filter, `count_certificates`, proof and transaction
327
- round-trip, pagination ordering).
328
-
329
- ## 0.3.4 — 2026-04-08
330
-
331
- Paired security patch release. Three P0 findings from the
332
- [2026-04-08 cross-SDK compliance review](.architecture/reviews/20260408-cross-sdk-compliance-review.md)
333
- plus follow-up hardening from the PR review pass. Must be installed
334
- together — the `bsv-wallet` gemspec now pins its `bsv-sdk` dependency
335
- to `>= 0.8.2, < 1.0` to enforce the paired upgrade and prevent a stale
336
- pair where one gem has its fixes and the other doesn't.
337
-
338
- Two GitHub Security Advisories accompany this release (draft until
339
- CVE IDs return from MITRE):
340
-
341
-
342
- ### Security
343
-
344
- - **`acquire_certificate` now verifies certifier signatures** before
345
- persisting (BRC-52). Both the `'direct'` and `'issuance'` acquisition
346
- paths previously wrote user-supplied `signature:` values to storage
347
- without any verification — a caller could forge a certificate that
348
- `list_certificates` / `prove_certificate` would later treat as
349
- authentic. This was a credential forgery primitive masquerading as
350
- an API finding. The new `BSV::Wallet::CertificateSignature` module
351
- builds the canonical BRC-52 preimage (matching the TS reference
352
- `Certificate#toBinary(false)` byte-for-byte) and delegates to
353
- `ProtoWallet#verify_signature`. Invalid certificates raise
354
- `BSV::Wallet::CertificateSignature::InvalidError` and are not
355
- persisted. Closes F8.15 (and the verification aspect of F8.16).
356
-
357
-
358
-
359
- ### Changed
360
-
361
- - **`bsv-wallet.gemspec` bsv-sdk dependency pinned** to
362
- `>= 0.8.2, < 1.0`. The previous `~> 0.4` constraint was stale (wallet
363
- hasn't been tested against bsv-sdk 0.4.x in months) and would have
364
- let a user install `bsv-wallet 0.3.4` against an old `bsv-sdk` that
365
- was missing F1.3 and F5.13. Technically breaking — any consumer
366
- pinned to `bsv-sdk < 0.8.2` must upgrade — but un-breaking in
367
- practice: it forces users to the known-good pair rather than a
368
- silently-broken combination.
369
-
370
- ### Internal
371
-
372
- - `lib/bsv/wallet_interface/**/*` added to the
373
- `Metrics/ModuleLength` exclusion list (was previously only excluded
374
- from `Metrics/ClassLength`). The new `CertificateSignature` module
375
- triggered the discrepancy.
376
- - Review-feedback hardening bundled into the same PR to
377
- keep the security-patch window small: case-insensitive ARC failure
378
- matching, `Base64.strict_decode64` on BRC-52 preimage fields,
379
- `EncodingError` rescue in `CertificateSignature.verify!`, rejection
380
- of mixed string / symbol duplicate field names, malformed 2xx
381
- rejection in ARC, and even-length guard on hex signatures.
382
-
383
- ### Migration notes
384
-
385
- - **Existing `bsv-wallet` users** pinned to `bsv-sdk ~> 0.4` will need
386
- to relax their constraint or upgrade. Anything installed before
387
- `bsv-wallet 0.3.4` is vulnerable to the F8.15 certificate forgery
388
- primitive.
389
- - **Callers passing negative integers to `VarInt.encode`** (unlikely —
390
- the docstring already disallowed it) will now get an `ArgumentError`
391
- instead of silent corruption. Fix: pass non-negative values.
392
- - **Callers relying on ARC broadcaster silently succeeding for INVALID
393
- / MALFORMED / MINED_IN_STALE_BLOCK / ORPHAN responses** will now see
394
- `BroadcastError` raised. Fix: handle the error — the previous
395
- behaviour was objectively wrong and any downstream logic that
396
- tolerated it was silently corrupt.
397
- - **Callers of `acquire_certificate` with a fake or untrusted
398
- `signature:` field** will now see
399
- `BSV::Wallet::CertificateSignature::InvalidError`. Fix: ensure the
400
- certificate has been properly signed by the declared certifier.
401
-
402
- ### Test suite
403
-
404
- - 3112 examples, 0 failures (up from 3080 on 0.8.1)
405
- - 16 new regression tests for F1.3, F5.13, and F8.15
406
- - 16 further regression tests for the review-feedback hardening
407
- - Ruby 2.7 — 3.4 matrix green
408
- - CodeQL clean; RuboCop clean across 266 files
409
-
410
- ## 0.3.3 — 2026-04-06
411
-
412
- ### Fixed
413
-
414
- - `finalize_action` now stores the spending transaction so subsequent
415
- `internalize_action` / proof resolution flows can find it. Previously the
416
- wallet remembered the inputs and outputs but not the finalised tx itself.
417
-
418
- ## 0.3.2 — 2026-04-06
419
-
420
- ### Fixed
421
-
422
- - `internalize_action` now stores **all** transactions from the
423
- incoming BEEF, not just the proven ones. Unproven ancestors are needed for
424
- later BEEF reconstruction in `create_action` → `to_beef`.
425
-
426
- ## 0.3.1 — 2026-04-06
427
-
428
- ### Fixed
429
-
430
- - `internalize_action` now stores the subject transaction hex (not
431
- just its proof and outputs), so the wallet can rebuild BEEF for spends of
432
- the inbound outputs without re-fetching the tx.
433
-
434
- ## 0.3.0 — 2026-04-06
21
+ ## [0.1.0] - 2026-04-24
435
22
 
436
23
  ### Added
437
24
 
438
- - **Pluggable proof store** for merkle proof persistence. The wallet
439
- is now a lightweight SPV node: `internalize_action` extracts and stores
440
- merkle proofs from incoming BEEF; `create_action` reattaches them to
441
- produce valid BEEF with BUMPs for ARC broadcast.
442
- - `ProofStore` interface with `store_proof` / `resolve_proof`.
443
- - `LocalProofStore` default implementation using `StorageAdapter`.
444
- - `WalletClient` accepts injectable `proof_store:` parameter.
445
- - Transaction caching (`store_transaction` / `find_transaction`) for
446
- ancestry reconstruction.
447
- - `StorageAdapter` gains `store_proof`, `find_proof`,
448
- `store_transaction`, `find_transaction` methods, implemented in both
449
- `MemoryStore` and `FileStore`.
450
-
451
- ### Fixed
452
-
453
- - `wire_source_from_storage` resolves merkle proofs via proof store
454
- so `to_beef` produces valid BEEF that ARC accepts. Previously, BEEF
455
- contained source transactions without proofs, causing ARC 463/468
456
- rejections.
457
-
458
- ## 0.2.2 — 2026-04-06
459
-
460
- ### Fixed
461
-
462
- - `to_beef` now includes source transactions in the BEEF output, not
463
- just the subject transaction. Without ancestors, ARC could not validate the
464
- spend graph.
465
-
466
- ## 0.2.1 — 2026-04-06
467
-
468
- ### Added
469
-
470
- - `WalletClient#create_action` now accepts `UnlockingScriptTemplate`
471
- objects (e.g. `P2PKH`) as input unlocking scripts, enabling template-based
472
- signing without BEEF.
473
- - `wire_source_from_storage` fallback populates `source_satoshis`
474
- and `source_locking_script` from wallet storage when BEEF is absent or
475
- incomplete, enabling BIP-143 sighash computation for wallet-tracked
476
- outputs.
477
- - `finalize_action` resolves template inputs via `sign_all` before
478
- serialisation.
479
- - `MemoryStore#filter_outputs` supports outpoint filtering for
480
- efficient single-output lookups.
481
-
482
- The sdk gem was re-released alongside this wallet change with no
483
- behavioural changes of its own.
484
-
485
- ## 0.2.0 — 2026-04-01
486
-
487
- ### Added
488
-
489
- #### Primitives
490
-
491
-
492
- #### Transaction
493
-
494
-
495
- #### Wallet
496
-
497
- - **FileStore** — JSON file-backed persistent storage, now the
498
- default for `WalletClient`. Data survives process restarts. `MemoryStore`
499
- becomes explicit opt-in for tests.
500
- - **File permissions** — directory created with 0700, files with
501
- 0600. Warns via Logger on startup if permissions are too open.
502
-
503
- ## 0.1.2 — 2026-03-30
504
-
505
- ### Added
506
-
507
- #### Script
508
-
509
-
510
- #### Transaction
511
-
512
-
513
- #### Wallet
514
-
515
- - **BRC-31 Auth/Peer** — mutual authentication with nonce-based
516
- challenges, ECDSA signatures, and session management.
517
- - **BRC-100 wire protocol** — binary ABI serialisation for all 28
518
- BRC-100 methods (call codes 1-28, VarInt encoding).
519
- - **Certificate issuance** — `acquire_certificate` with
520
- `'issuance'` protocol (POST to certifier URL).
521
-
522
- ### Fixed
523
-
524
- - Subject and certifier pinned in certificate issuance response
525
- (not overridable by remote certifier).
526
- - Wire reader negative `privileged_reason` length crash.
527
-
528
- This was the first formal `bsv-wallet` gem release tag. Wallet code that
529
- landed in master before this date (notably the BRC-100 identity certificate
530
- methods and the BRC-100 blockchain-data / authentication methods committed
531
- during the sdk-0.3.1 window) is part of this gem's initial released state.
25
+ - BRC-100 wallet interface module (`BSV::Wallet`)
26
+ - Gem scaffolding
data/LICENSE CHANGED
@@ -1,86 +1,29 @@
1
- Open BSV License Version 5 – granted by BSV Association, Grafenauweg 6, 6300
2
- Zug, Switzerland (CHE-427.008.338) ("Licensor"), to you as a user (henceforth
3
- "You", "User" or "Licensee").
1
+ Open BSV License
4
2
 
5
- For the purposes of this license, the definitions below have the following
6
- meanings:
3
+ Copyright (c) 2026 Simon Bettison
7
4
 
8
- "Bitcoin Protocol" means the protocol implementation, cryptographic rules,
9
- network protocols, and consensus mechanisms in the Bitcoin White Paper as
10
- described here https://protocol.bsvblockchain.org.
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
11
 
12
- "Bitcoin White Paper" means the paper entitled 'Bitcoin: A Peer-to-Peer
13
- Electronic Cash System' published by 'Satoshi Nakamoto' in October 2008.
12
+ 1. The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
14
 
15
- "BSV Blockchains" means:
16
- (a) the Bitcoin blockchain containing block height #556767 with the hash
17
- "000000000000000001d956714215d96ffc00e0afda4cd0a96c96f8d802b1662b" and
18
- that contains the longest honest persistent chain of blocks which has been
19
- produced in a manner which is consistent with the rules set forth in the
20
- Network Access Rules; and
21
- (b) the test blockchains that contain the longest honest persistent chains of
22
- blocks which has been produced in a manner which is consistent with the
23
- rules set forth in the Network Access Rules.
24
-
25
- "Network Access Rules" or "Rules" means the set of rules regulating the
26
- relationship between BSV Association and the nodes on BSV based on the Bitcoin
27
- Protocol rules and those set out in the Bitcoin White Paper, and available here
28
- https://bsvblockchain.org/network-access-rules.
29
-
30
- "Software" means the software the subject of this licence, including any/all
31
- intellectual property rights therein and associated documentation files.
32
-
33
- BSV Association grants permission, free of charge and on a non-exclusive and
34
- revocable basis, to any person obtaining a copy of the Software to deal in the
35
- Software without restriction, including without limitation the rights to use,
36
- copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
37
- Software, and to permit persons to whom the Software is furnished to do so,
38
- subject to and conditioned upon the following conditions:
39
-
40
- 1 - The text "© BSV Association," and this license shall be included in all
41
- copies or substantial portions of the Software.
42
- 2 - The Software, and any software that is derived from the Software or parts
43
- thereof, must only be used on the BSV Blockchains.
44
-
45
- For the avoidance of doubt, this license is granted subject to and conditioned
46
- upon your compliance with these terms only. In the event of non-compliance, the
47
- license shall extinguish and you can be enjoined from violating BSV's
48
- intellectual property rights (incl. damages and similar related claims).
49
-
50
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES REGARDING ENTITLEMENT,
52
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
53
- EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS THEREOF BE LIABLE FOR ANY CLAIM,
54
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
55
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
56
- DEALINGS IN THE SOFTWARE.
57
-
58
-
59
- Version 0.1.1 of the Bitcoin SV software, and prior versions of software upon
60
- which it was based, were licensed under the MIT License, which is included below.
61
-
62
- The MIT License (MIT)
63
-
64
- Copyright (c) 2009-2010 Satoshi Nakamoto
65
- Copyright (c) 2009-2015 Bitcoin Developers
66
- Copyright (c) 2009-2017 The Bitcoin Core developers
67
- Copyright (c) 2017 The Bitcoin ABC developers
68
- Copyright (c) 2018 Bitcoin Association for BSV
69
- Copyright (c) 2023 BSV Association
70
-
71
- Permission is hereby granted, free of charge, to any person obtaining a copy of
72
- this software and associated documentation files (the "Software"), to deal in
73
- the Software without restriction, including without limitation the rights to
74
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
75
- the Software, and to permit persons to whom the Software is furnished to do so,
76
- subject to the following conditions:
77
-
78
- The above copyright notice and this permission notice shall be included in all
79
- copies or substantial portions of the Software.
15
+ 2. The Software, and any software that is derived from the Software or parts
16
+ thereof, can only be used on the Bitcoin SV blockchains. The Bitcoin SV
17
+ blockchains are defined, for purposes of this license, as the Bitcoin
18
+ blockchain containing block combinator
19
+ 000000000000000001d956714215d96ffc00e0afda4cd0a96c96f8d802b1662b and the
20
+ test combinator
21
+ 00000000a6e140e27e4eb65e3cb4e4e07b1a0e3964b396c97a4b36e4ac06eb54.
80
22
 
81
23
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
82
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
83
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
84
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
85
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
86
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29
+ THE SOFTWARE.