Skip to content

Commit c0a427b

Browse files
authored
Merge pull request #375 from sgbett/feat/368-broadcast-rollback
feat(wallet): broadcast/rollback semantics for create_action (F8.13)
2 parents cad64c6 + 363652e commit c0a427b

File tree

11 files changed

+1065
-23
lines changed

11 files changed

+1065
-23
lines changed

.rubocop.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Naming/PredicateMethod:
6161
- is_authenticated
6262
- delete_output
6363
- delete_certificate
64+
- delete_action
6465

6566
# is_authenticated uses the BRC-100 wire-protocol naming convention (is_ prefix).
6667
Naming/PredicatePrefix:

gem/bsv-sdk/lib/bsv/network/arc.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,8 @@ def handle_broadcast_response(response)
195195
raise BroadcastError.new(
196196
body['detail'] || body['title'] || body['txStatus'],
197197
status_code: code,
198-
txid: body['txid']
198+
txid: body['txid'],
199+
arc_status: body['txStatus'].to_s.upcase
199200
)
200201
end
201202

@@ -277,7 +278,8 @@ def build_response_or_error(body)
277278
BroadcastError.new(
278279
body['detail'] || body['title'] || body['txStatus'],
279280
status_code: 200,
280-
txid: body['txid']
281+
txid: body['txid'],
282+
arc_status: body['txStatus'].to_s.upcase
281283
)
282284
elsif !body['txid']
283285
BroadcastError.new(

gem/bsv-sdk/lib/bsv/network/broadcast_error.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
module BSV
44
module Network
55
class BroadcastError < StandardError
6-
attr_reader :status_code, :txid
6+
attr_reader :status_code, :txid, :arc_status
77

8-
def initialize(message, status_code: nil, txid: nil)
8+
def initialize(message, status_code: nil, txid: nil, arc_status: nil)
99
@status_code = status_code
1010
@txid = txid
11+
@arc_status = arc_status
1112
super(message)
1213
end
1314
end

gem/bsv-wallet-postgres/lib/bsv/wallet_postgres/postgres_store.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,23 @@ def count_actions(query)
102102
filter_actions(@db[:wallet_actions], query).count
103103
end
104104

105+
def update_action_status(txid, new_status)
106+
ds = @db[:wallet_actions].where(txid: txid)
107+
raise WalletError, "Action not found: #{txid}" if ds.empty?
108+
109+
ds.update(
110+
data: Sequel.lit(
111+
"data || jsonb_build_object('status', ?)",
112+
new_status
113+
)
114+
)
115+
symbolise_keys(ds.first[:data])
116+
end
117+
118+
def delete_action(txid)
119+
@db[:wallet_actions].where(txid: txid).delete.positive?
120+
end
121+
105122
# --- Outputs ---
106123

107124
def store_output(output_data)

gem/bsv-wallet/lib/bsv/wallet_interface/file_store.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ def store_action(action_data)
4848
result
4949
end
5050

51+
def update_action_status(txid, new_status)
52+
result = super
53+
save_actions
54+
result
55+
end
56+
57+
def delete_action(txid)
58+
result = super
59+
save_actions if result
60+
result
61+
end
62+
5163
def store_output(output_data)
5264
result = super
5365
save_outputs

gem/bsv-wallet/lib/bsv/wallet_interface/memory_store.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,22 @@ def store_action(action_data)
3030
action_data
3131
end
3232

33+
def update_action_status(txid, new_status)
34+
action = @actions.find { |a| a[:txid] == txid }
35+
raise WalletError, "Action not found: #{txid}" unless action
36+
37+
action[:status] = new_status
38+
action
39+
end
40+
41+
def delete_action(txid)
42+
idx = @actions.index { |a| a[:txid] == txid }
43+
return false unless idx
44+
45+
@actions.delete_at(idx)
46+
true
47+
end
48+
3349
def find_actions(query)
3450
apply_pagination(filter_actions(query), query)
3551
end

gem/bsv-wallet/lib/bsv/wallet_interface/storage_adapter.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,26 @@ def find_transaction(_txid)
6767
raise NotImplementedError, "#{self.class}#find_transaction not implemented"
6868
end
6969

70+
# Updates the status field of a stored action identified by txid.
71+
#
72+
# @param _txid [String] the transaction identifier of the action to update
73+
# @param _new_status [String] the new status value (e.g. 'failed', 'completed')
74+
# @return [Hash] the updated action hash
75+
# @raise [BSV::Wallet::WalletError] if no action with the given txid is found
76+
# @raise [NotImplementedError]
77+
def update_action_status(_txid, _new_status)
78+
raise NotImplementedError, "#{self.class}#update_action_status not implemented"
79+
end
80+
81+
# Removes a stored action by txid.
82+
#
83+
# @param _txid [String] the transaction identifier of the action to remove
84+
# @return [Boolean] true if the action was deleted, false if not found
85+
# @raise [NotImplementedError]
86+
def delete_action(_txid)
87+
raise NotImplementedError, "#{self.class}#delete_action not implemented"
88+
end
89+
7090
# Transitions the state of an existing output.
7191
#
7292
# When +new_state+ is +:pending+, pass a +pending_reference:+ string to

0 commit comments

Comments
 (0)