Module: BSV::Wallet::Client::Transaction
- Included in:
- BSV::Wallet::Client
- Defined in:
- lib/bsv/wallet/client/brc100/transaction.rb
Overview
Transaction Operations concern — the 7 BRC-100 transaction public methods and all their private helpers.
Included into BSV::Wallet::Client; methods share the instance’s scope and access all instance variables initialised in #initialize.
Constant Summary collapse
- ANCESTOR_DEPTH_CAP =
Maximum ancestor depth to traverse when wiring source transactions.
64- STALE_CHECK_INTERVAL =
Rate-limits stale pending recovery to avoid O(n) scans on every auto-fund call.
30
Instance Method Summary collapse
-
#abort_action(args, originator: nil) ⇒ Hash
Aborts a pending signable transaction.
-
#create_action(args, originator: nil) ⇒ Hash
Creates a new Bitcoin transaction.
-
#internalize_action(args, originator: nil) ⇒ Hash
Accepts an incoming transaction for wallet internalization.
-
#list_actions(args, originator: nil) ⇒ Hash
Lists stored actions matching the given labels.
-
#list_outputs(args, originator: nil) ⇒ Hash
Lists spendable outputs in a basket.
-
#relinquish_output(args, originator: nil) ⇒ Hash
Removes an output from basket tracking.
-
#sign_action(args, originator: nil) ⇒ Hash
Signs a previously created signable transaction.
Instance Method Details
#abort_action(args, originator: nil) ⇒ Hash
Aborts a pending signable transaction.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/bsv/wallet/client/brc100/transaction.rb', line 100 def abort_action(args, originator: nil) return @substrate.abort_action(args, originator: originator) if @substrate reference = args[:reference] raise WalletError, 'Transaction not found for the given reference' unless @pending.key?(reference) pending_entry = @pending.delete(reference) txid = pending_entry[:tx]&.txid_hex @pending_by_txid.delete(txid) if txid rollback_pending_action( pending_entry[:locked_outpoints], pending_entry[:change_outpoints], txid, reference ) { aborted: true } end |
#create_action(args, originator: nil) ⇒ Hash
Creates a new Bitcoin transaction.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/bsv/wallet/client/brc100/transaction.rb', line 30 def create_action(args, originator: nil) return @substrate.create_action(args, originator: originator) if @substrate validate_create_action!(args) validate_broadcast_configuration!(args) send_with_txids = Array(args.dig(:options, :send_with)) outputs = args[:outputs] || [] inputs = args[:inputs] if !send_with_txids.empty? && outputs.empty? && (inputs.nil? || inputs.empty?) raise WalletError, 'A broadcaster is required to use send_with' unless broadcast_enabled? return { send_with_results: broadcast_send_with(send_with_txids) } end if (inputs.nil? || inputs.empty?) && !outputs.empty? && (args[:auto_fund] || spendable_pool_eligible?) result = auto_fund_and_create(args, outputs) unless send_with_txids.empty? raise WalletError, 'A broadcaster is required to use send_with' unless broadcast_enabled? result[:send_with_results] = broadcast_send_with(send_with_txids) end return result end beef = parse_input_beef(args[:input_beef]) tx = build_transaction(args, beef) if needs_signing?(args[:inputs]) create_signable(tx, args, beef) else finalize_action(tx, args) end end |
#internalize_action(args, originator: nil) ⇒ Hash
Accepts an incoming transaction for wallet internalization.
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/bsv/wallet/client/brc100/transaction.rb', line 171 def internalize_action(args, originator: nil) return @substrate.internalize_action(args, originator: originator) if @substrate validate_internalize_action!(args) beef_binary = args[:tx].pack('C*') beef = BSV::Transaction::Beef.from_binary(beef_binary) raise WalletError, 'BEEF verification failed: the bundle is structurally invalid' unless beef.verify(nil) tx = extract_subject_transaction(beef) store_proofs_from_beef(beef) process_internalize_outputs(tx, args[:outputs]) has_proof = !beef.find_bump(tx.txid).nil? store_action(tx, args, status: has_proof ? 'completed' : 'unproven') { accepted: true } end |
#list_actions(args, originator: nil) ⇒ Hash
Lists stored actions matching the given labels.
123 124 125 126 127 128 129 130 131 |
# File 'lib/bsv/wallet/client/brc100/transaction.rb', line 123 def list_actions(args, originator: nil) return @substrate.list_actions(args, originator: originator) if @substrate validate_list_actions!(args) query = build_action_query(args) total = @storage.count_actions(query) actions = @storage.find_actions(query) { total_actions: total, actions: strip_action_fields(actions, args) } end |
#list_outputs(args, originator: nil) ⇒ Hash
Lists spendable outputs in a basket.
138 139 140 141 142 143 144 145 146 |
# File 'lib/bsv/wallet/client/brc100/transaction.rb', line 138 def list_outputs(args, originator: nil) return @substrate.list_outputs(args, originator: originator) if @substrate validate_list_outputs!(args) query = build_output_query(args) total = @storage.count_outputs(query) outputs = @storage.find_outputs(query) { total_outputs: total, outputs: strip_output_fields(outputs, args) } end |
#relinquish_output(args, originator: nil) ⇒ Hash
Removes an output from basket tracking.
154 155 156 157 158 159 160 161 162 |
# File 'lib/bsv/wallet/client/brc100/transaction.rb', line 154 def relinquish_output(args, originator: nil) return @substrate.relinquish_output(args, originator: originator) if @substrate Validators.validate_basket!(args[:basket]) Validators.validate_outpoint!(args[:output]) raise WalletError, 'Output not found' unless @storage.delete_output(args[:output]) { relinquished: true } end |
#sign_action(args, originator: nil) ⇒ Hash
Signs a previously created signable transaction.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/bsv/wallet/client/brc100/transaction.rb', line 73 def sign_action(args, originator: nil) return @substrate.sign_action(args, originator: originator) if @substrate reference = args[:reference] pending = @pending[reference] raise WalletError, 'Transaction not found for the given reference' unless pending tx = pending[:tx] apply_spends(tx, args[:spends]) @pending.delete(reference) merged_args = if args[:options] pending[:args].merge(options: (pending[:args][:options] || {}).merge(args[:options])) else pending[:args] end validate_broadcast_configuration!(merged_args) finalize_action(tx, merged_args) end |