bsv-wallet 0.8.0 → 0.9.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.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7959ebc47fc5d89d3d0db18f4136c925e228f6ea483553decffd4b9e7de9defc
|
|
4
|
+
data.tar.gz: 2365a17193357b64d50c15a61aa12422b966b8f0155a6ab989b3bacb700a0929
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 895d3c7a661e00b7d70dd833d12e4dd0e17ca2a8d0d8ba6a2c0ef622dfbac6bc0d6fb534a3fe06c14c0b1747981f1e0c9b8b61e9f164e3cc8fea222e5f9e70c1
|
|
7
|
+
data.tar.gz: 3086ff6e236c57d903c947ac7c230148104993837b3d2f46ddef3a09a9b43da42bab1a5ea6f1c7b375b105cc7e8feffe2c8defbd83a325ec7ca0775dbd1f2ea1
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,47 @@ All notable changes to the `bsv-wallet` gem are documented here.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
6
6
|
and this gem adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## 0.9.0 — 2026-04-16
|
|
9
|
+
|
|
10
|
+
### Changed — **Breaking**
|
|
11
|
+
|
|
12
|
+
#### Action status taxonomy aligned with BRC-100 reference SDK (HLR #455)
|
|
13
|
+
|
|
14
|
+
This release realigns the action status values with the wallet-toolbox reference
|
|
15
|
+
implementation. The meaning of `'completed'` has changed — **consumers must
|
|
16
|
+
update any code that checks for `'completed'` as the post-broadcast success
|
|
17
|
+
state**.
|
|
18
|
+
|
|
19
|
+
| Status | Old meaning | New meaning |
|
|
20
|
+
|--------|-------------|-------------|
|
|
21
|
+
| `'nosend'` | No change | Transaction built but not broadcast (`no_send: true`) |
|
|
22
|
+
| `'sending'` | No change | Async queue accepted; worker has not yet attempted broadcast |
|
|
23
|
+
| `'unproven'` | *(new)* | Broadcast succeeded; awaiting merkle proof |
|
|
24
|
+
| `'completed'` | Broadcast succeeded | **Merkle proof received and stored** |
|
|
25
|
+
| `'failed'` | No change | Broadcast rejected or transaction invalid |
|
|
26
|
+
|
|
27
|
+
**Migration:**
|
|
28
|
+
|
|
29
|
+
- Code querying `list_actions(status: 'completed')` will return fewer results
|
|
30
|
+
until a proof-watcher is implemented (out of scope for this release). To find
|
|
31
|
+
successfully-broadcast actions that have not yet received a proof, query
|
|
32
|
+
`status: 'unproven'` instead.
|
|
33
|
+
- `create_action` and `sign_action` now raise `BSV::Wallet::WalletError` when
|
|
34
|
+
no broadcaster is configured and `options: { no_send: true }` is not set.
|
|
35
|
+
Previously these calls succeeded silently. To resolve: pass
|
|
36
|
+
`broadcaster: BSV::Network::ARC.default` to `WalletClient.new`, or pass
|
|
37
|
+
`options: { no_send: true }` to `create_action` to build without
|
|
38
|
+
broadcasting.
|
|
39
|
+
- `internalize_action` now sets status to `'completed'` only when the supplied
|
|
40
|
+
BEEF contains a merkle proof for the subject transaction. Plain BEEF (raw
|
|
41
|
+
transaction, no BUMP) results in status `'unproven'`.
|
|
42
|
+
- Wallets configured with a `SolidQueueAdapter` satisfy the broadcaster
|
|
43
|
+
requirement if the adapter carries an embedded `broadcaster:` — the
|
|
44
|
+
`WalletClient` itself does not need one.
|
|
45
|
+
|
|
46
|
+
**Related upstream incidents:** x402-rack #148, x402-rack #158, x402-doom #196.
|
|
47
|
+
**Tracking issue:** #455.
|
|
48
|
+
|
|
8
49
|
## 0.8.0 — 2026-04-15
|
|
9
50
|
|
|
10
51
|
### Added
|
|
@@ -68,6 +68,21 @@ module BSV
|
|
|
68
68
|
false
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
+
# Returns +false+ by default — adapters without a broadcaster cannot
|
|
72
|
+
# broadcast on-chain.
|
|
73
|
+
#
|
|
74
|
+
# Override in adapters that hold a broadcaster reference so that
|
|
75
|
+
# +WalletClient+ can determine broadcast availability from the queue
|
|
76
|
+
# alone. This is the correct delegation point because users may pass a
|
|
77
|
+
# broadcaster-equipped queue (e.g.
|
|
78
|
+
# +SolidQueueAdapter.new(broadcaster: arc)+) without also passing
|
|
79
|
+
# +broadcaster:+ directly to +WalletClient+.
|
|
80
|
+
#
|
|
81
|
+
# @return [Boolean]
|
|
82
|
+
def broadcast_enabled?
|
|
83
|
+
false
|
|
84
|
+
end
|
|
85
|
+
|
|
71
86
|
# Returns the broadcast status for a previously enqueued transaction.
|
|
72
87
|
#
|
|
73
88
|
# @param _txid [String] hex transaction identifier
|
|
@@ -30,6 +30,17 @@ module BSV
|
|
|
30
30
|
false
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
# Returns +true+ when a broadcaster has been configured.
|
|
34
|
+
#
|
|
35
|
+
# +WalletClient+ delegates its own +broadcast_enabled?+ to this method
|
|
36
|
+
# so the check works correctly when the broadcaster is embedded in the
|
|
37
|
+
# queue rather than passed directly to the wallet.
|
|
38
|
+
#
|
|
39
|
+
# @return [Boolean]
|
|
40
|
+
def broadcast_enabled?
|
|
41
|
+
!@broadcaster.nil?
|
|
42
|
+
end
|
|
43
|
+
|
|
33
44
|
# Returns the broadcast status for a previously enqueued transaction.
|
|
34
45
|
#
|
|
35
46
|
# Delegates to storage and returns the action status field, or +nil+ if
|
|
@@ -96,8 +107,10 @@ module BSV
|
|
|
96
107
|
}
|
|
97
108
|
end
|
|
98
109
|
|
|
99
|
-
# Broadcast succeeded — promote all pending state to
|
|
100
|
-
|
|
110
|
+
# Broadcast succeeded — promote all pending state; set status to
|
|
111
|
+
# 'unproven' (transaction is on-chain but lacks a merkle proof).
|
|
112
|
+
# 'completed' is reserved for transactions confirmed by a proof-watcher.
|
|
113
|
+
promote(input_outpoints, change_outpoints, txid, status: 'unproven')
|
|
101
114
|
|
|
102
115
|
result = {
|
|
103
116
|
txid: txid,
|
|
@@ -109,14 +122,24 @@ module BSV
|
|
|
109
122
|
result
|
|
110
123
|
end
|
|
111
124
|
|
|
112
|
-
# Promotes UTXO state without broadcasting
|
|
113
|
-
# used when no broadcaster is configured.
|
|
125
|
+
# Promotes UTXO state without broadcasting.
|
|
114
126
|
#
|
|
115
|
-
#
|
|
116
|
-
#
|
|
127
|
+
# This path is reached when no broadcaster is configured. It is only
|
|
128
|
+
# valid when +accept_delayed_broadcast+ is set on the create_action
|
|
129
|
+
# call — the caller explicitly accepts that the transaction will be
|
|
130
|
+
# broadcast out-of-band. Action status is set to +unproven+.
|
|
131
|
+
#
|
|
132
|
+
# +completed+ is reserved for transactions that have received a merkle
|
|
133
|
+
# proof (set by +internalize_action+ or a future proof-watcher).
|
|
134
|
+
#
|
|
135
|
+
# Defensive guard: raises +WalletError+ if reached without
|
|
136
|
+
# +accept_delayed_broadcast+. The normal entry point for this guard is
|
|
137
|
+
# the +create_action+ validation added in Task 1 (#456), but this guard
|
|
138
|
+
# protects against other code paths that bypass it.
|
|
117
139
|
#
|
|
118
140
|
# @param payload [Hash] broadcast payload
|
|
119
141
|
# @return [Hash] result hash containing +:txid+ and +:tx+
|
|
142
|
+
# @raise [BSV::Wallet::WalletError] if +accept_delayed_broadcast+ is not set
|
|
120
143
|
def promote_without_broadcast(payload)
|
|
121
144
|
txid = payload[:txid]
|
|
122
145
|
beef_binary = payload[:beef_binary]
|
|
@@ -124,8 +147,14 @@ module BSV
|
|
|
124
147
|
change_outpoints = payload[:change_outpoints]
|
|
125
148
|
delayed = payload[:accept_delayed_broadcast]
|
|
126
149
|
|
|
127
|
-
|
|
128
|
-
|
|
150
|
+
unless delayed
|
|
151
|
+
raise BSV::Wallet::WalletError,
|
|
152
|
+
'InlineQueue cannot promote without a broadcaster unless ' \
|
|
153
|
+
'accept_delayed_broadcast is set. This indicates a bypass of ' \
|
|
154
|
+
'the create_action guard — report as a bug.'
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
promote(input_outpoints, change_outpoints, txid, status: 'unproven')
|
|
129
158
|
|
|
130
159
|
{ txid: txid, tx: beef_binary.unpack('C*') }
|
|
131
160
|
end
|
|
@@ -94,9 +94,13 @@ module BSV
|
|
|
94
94
|
)
|
|
95
95
|
end
|
|
96
96
|
|
|
97
|
-
# Returns true when
|
|
97
|
+
# Returns +true+ when broadcast is available.
|
|
98
|
+
#
|
|
99
|
+
# Delegates to the broadcast queue so that queue-embedded broadcasters
|
|
100
|
+
# (e.g. +SolidQueueAdapter.new(broadcaster: arc)+) are recognised even
|
|
101
|
+
# when no +broadcaster:+ was passed directly to +WalletClient+.
|
|
98
102
|
def broadcast_enabled?
|
|
99
|
-
|
|
103
|
+
@broadcast_queue.broadcast_enabled?
|
|
100
104
|
end
|
|
101
105
|
|
|
102
106
|
# --- Transaction Operations ---
|
|
@@ -123,6 +127,7 @@ module BSV
|
|
|
123
127
|
return @substrate.create_action(args, originator: originator) if @substrate
|
|
124
128
|
|
|
125
129
|
validate_create_action!(args)
|
|
130
|
+
validate_broadcast_configuration!(args)
|
|
126
131
|
|
|
127
132
|
send_with_txids = Array(args.dig(:options, :send_with))
|
|
128
133
|
|
|
@@ -185,6 +190,11 @@ module BSV
|
|
|
185
190
|
else
|
|
186
191
|
pending[:args]
|
|
187
192
|
end
|
|
193
|
+
|
|
194
|
+
# Re-validate broadcast configuration on merged args — options may have
|
|
195
|
+
# been flipped between create_action and sign_action (e.g. no_send toggled).
|
|
196
|
+
validate_broadcast_configuration!(merged_args)
|
|
197
|
+
|
|
188
198
|
finalize_action(tx, merged_args)
|
|
189
199
|
end
|
|
190
200
|
|
|
@@ -303,7 +313,8 @@ module BSV
|
|
|
303
313
|
store_proofs_from_beef(beef)
|
|
304
314
|
@storage.store_transaction(tx.txid_hex, tx.to_hex)
|
|
305
315
|
process_internalize_outputs(tx, args[:outputs])
|
|
306
|
-
|
|
316
|
+
has_proof = !beef.find_bump(tx.txid).nil?
|
|
317
|
+
store_action(tx, args, status: has_proof ? 'completed' : 'unproven')
|
|
307
318
|
{ accepted: true }
|
|
308
319
|
end
|
|
309
320
|
|
|
@@ -1068,6 +1079,25 @@ module BSV
|
|
|
1068
1079
|
|
|
1069
1080
|
# --- Validation ---
|
|
1070
1081
|
|
|
1082
|
+
# Raises +WalletError+ when a broadcast is required but unavailable.
|
|
1083
|
+
#
|
|
1084
|
+
# Broadcast is required whenever +no_send+ is absent or false. Callers
|
|
1085
|
+
# that do not intend to broadcast on-chain must pass
|
|
1086
|
+
# +options: { no_send: true }+ to opt out.
|
|
1087
|
+
#
|
|
1088
|
+
# @param args [Hash] action arguments (merged, as seen at call site)
|
|
1089
|
+
# @raise [WalletError] if broadcast is needed but +broadcast_enabled?+ is false
|
|
1090
|
+
def validate_broadcast_configuration!(args)
|
|
1091
|
+
no_send = args.dig(:options, :no_send)
|
|
1092
|
+
return if no_send
|
|
1093
|
+
return if broadcast_enabled?
|
|
1094
|
+
|
|
1095
|
+
raise WalletError,
|
|
1096
|
+
'create_action requires a broadcaster for on-chain broadcast. ' \
|
|
1097
|
+
'Pass broadcaster: BSV::Network::ARC.default to WalletClient.new, ' \
|
|
1098
|
+
'or options: { no_send: true } to build a transaction without broadcasting.'
|
|
1099
|
+
end
|
|
1100
|
+
|
|
1071
1101
|
def validate_create_action!(args)
|
|
1072
1102
|
Validators.validate_description!(args[:description])
|
|
1073
1103
|
inputs_present = args[:inputs] && !args[:inputs].empty?
|