Part of #455.
Summary
Fix internalize_action so the stored wallet-action status reflects whether the BEEF actually carries a merkle proof for the subject transaction. If proof present → 'completed'. If absent → 'unproven'. This mirrors the TS reference (storage/methods/internalizeAction.ts:301 — provenTx ? 'completed' : 'unproven').
Scope
gem/bsv-wallet/lib/bsv/wallet_interface/wallet_client.rb — internalize_action (line ~288-308)
Changes
- Use the existing helper
beef.find_bump(tx.txid) (see gem/bsv-sdk/lib/bsv/transaction/beef.rb:258). Returns MerklePath if a BUMP is indexed for that txid, nil otherwise.
- Replace line ~306:
store_action(tx, args, status: 'completed')
with:
has_proof = !beef.find_bump(tx.txid).nil?
store_action(tx, args, status: has_proof ? 'completed' : 'unproven')
Alternative considered but NOT preferred: tx.merkle_path.nil? ? 'unproven' : 'completed'. This depends on find_atomic_transaction wiring the merkle_path on the subject tx, which varies between atomic vs plain BEEF paths. find_bump is format-agnostic and safer.
Acceptance criteria
Edge cases
- Non-atomic BEEF with subject lacking a BUMP but ancestor txs have BUMPs — subject status must be
'unproven'. find_bump(subject.txid) must not return an ancestor's BUMP; it keys on txid specifically (verify against the helper's behaviour).
- Atomic BEEF (subject_txid set) —
find_atomic_transaction wires ancestry; find_bump(tx.txid) checks specifically for the subject's proof.
- Subject tx extracted via fallback (non-atomic, last transaction) — same logic applies.
- BEEF with a
FORMAT_TXID_ONLY entry for the subject (proof-only, no raw tx) — shouldn't happen for incoming internalize; if it does, find_bump returns the BUMP if indexed, so status is 'completed'. Edge, but correct behaviour.
Test scenarios
internalize with proven BEEF (merged BUMP for subject) → action status 'completed'
internalize with unproven BEEF (raw tx, no BUMP) → action status 'unproven'
internalize with BEEF where ancestor has BUMP but subject does not → action status 'unproven'
internalize with Atomic BEEF carrying subject proof → action status 'completed'
proofs from BEEF are still stored in proof_store in both cases (regression)
{ accepted: true } returned in both cases (regression)
Files modified
gem/bsv-wallet/lib/bsv/wallet_interface/wallet_client.rb
gem/bsv-wallet/spec/bsv/wallet_interface/wallet_client_spec.rb (Task 5 owns broader spec migration; direct test additions for internalize_action land here)
Sequencing
Independent of Tasks 1-3. Can be developed in parallel. Lands alongside them.
Part of #455.
Summary
Fix
internalize_actionso the stored wallet-action status reflects whether the BEEF actually carries a merkle proof for the subject transaction. If proof present →'completed'. If absent →'unproven'. This mirrors the TS reference (storage/methods/internalizeAction.ts:301—provenTx ? 'completed' : 'unproven').Scope
gem/bsv-wallet/lib/bsv/wallet_interface/wallet_client.rb—internalize_action(line ~288-308)Changes
beef.find_bump(tx.txid)(seegem/bsv-sdk/lib/bsv/transaction/beef.rb:258). ReturnsMerklePathif a BUMP is indexed for that txid,nilotherwise.Alternative considered but NOT preferred:
tx.merkle_path.nil? ? 'unproven' : 'completed'. This depends onfind_atomic_transactionwiring themerkle_pathon the subject tx, which varies between atomic vs plain BEEF paths.find_bumpis format-agnostic and safer.Acceptance criteria
'completed'.'unproven'.{ accepted: true }return value unchanged.store_proofs_from_beefstill called — any proofs present in the BEEF are persisted regardless of the subject-tx proof status (regression).'completed'(the atomic format setssubject_txid;find_bump(subject_txid)returns the BUMP).Edge cases
'unproven'.find_bump(subject.txid)must not return an ancestor's BUMP; it keys on txid specifically (verify against the helper's behaviour).find_atomic_transactionwires ancestry;find_bump(tx.txid)checks specifically for the subject's proof.FORMAT_TXID_ONLYentry for the subject (proof-only, no raw tx) — shouldn't happen for incoming internalize; if it does,find_bumpreturns the BUMP if indexed, so status is'completed'. Edge, but correct behaviour.Test scenarios
internalize with proven BEEF (merged BUMP for subject) → action status 'completed'internalize with unproven BEEF (raw tx, no BUMP) → action status 'unproven'internalize with BEEF where ancestor has BUMP but subject does not → action status 'unproven'internalize with Atomic BEEF carrying subject proof → action status 'completed'proofs from BEEF are still stored in proof_store in both cases(regression){ accepted: true } returned in both cases(regression)Files modified
gem/bsv-wallet/lib/bsv/wallet_interface/wallet_client.rbgem/bsv-wallet/spec/bsv/wallet_interface/wallet_client_spec.rb(Task 5 owns broader spec migration; direct test additions forinternalize_actionland here)Sequencing
Independent of Tasks 1-3. Can be developed in parallel. Lands alongside them.