Module: BSV::Wallet::Interface::Store

Defined in:
lib/bsv/wallet/interface/store.rb

Overview

Persistence interface for wallet state.

Methods mirror the schema’s phase model — the action lifecycle is create (lock inputs) → sign (attach wtxid) → promote (write outputs). Status is derived from structural state, never stored directly.

All methods receive and return plain hashes/arrays — no ORM objects leak through the interface boundary.

Instance Method Summary collapse

Instance Method Details

#abort_action(action_id:) ⇒ Object

Abort an action. CASCADE deletes inputs, releasing locked UTXOs. Only valid for unsigned actions (wtxid IS NULL).

Parameters:

  • action_id (Integer)

Raises:

  • (NotImplementedError)


75
76
77
# File 'lib/bsv/wallet/interface/store.rb', line 75

def abort_action(action_id:)
  raise NotImplementedError
end

#create_action(action:, inputs: []) ⇒ Hash

Phase 1: Create an action and lock inputs atomically.

Inserts an action row and input rows in one transaction. Input locking uses INSERT ON CONFLICT — concurrent callers competing for the same outputs are resolved by the database.

Parameters:

  • action (Hash)

    :description, :broadcast (:delayed/:inline/:none), :nlocktime, :version, :input_beef, :outgoing

  • inputs (Array<Hash>) (defaults to: [])

    each: :output_id, :vin, :nsequence, :description

Returns:

  • (Hash)

    the created action with :id, :reference

Raises:



28
29
30
# File 'lib/bsv/wallet/interface/store.rb', line 28

def create_action(action:, inputs: [])
  raise NotImplementedError
end

#delete_certificate(type:, serial_number:, certifier:) ⇒ Object

Soft-delete a certificate.

Raises:

  • (NotImplementedError)


157
158
159
# File 'lib/bsv/wallet/interface/store.rb', line 157

def delete_certificate(type:, serial_number:, certifier:)
  raise NotImplementedError
end

#find_action(id: nil, wtxid: nil, reference: nil) ⇒ Hash?

Find an action by id, wtxid, or reference.

Returns:

  • (Hash, nil)

Raises:

  • (NotImplementedError)


84
85
86
# File 'lib/bsv/wallet/interface/store.rb', line 84

def find_action(id: nil, wtxid: nil, reference: nil)
  raise NotImplementedError
end

#find_or_create_basket(name:) ⇒ Object

Find or create a basket by name. Returns the basket ID.

Raises:

  • (NotImplementedError)


133
134
135
# File 'lib/bsv/wallet/interface/store.rb', line 133

def find_or_create_basket(name:)
  raise NotImplementedError
end

#find_or_create_labels(names:) ⇒ Object

Find or create labels by name. Returns an array of label IDs.

Raises:

  • (NotImplementedError)


123
124
125
# File 'lib/bsv/wallet/interface/store.rb', line 123

def find_or_create_labels(names:)
  raise NotImplementedError
end

#find_or_create_tags(names:) ⇒ Object

Find or create tags by name. Returns an array of tag IDs.

Raises:

  • (NotImplementedError)


128
129
130
# File 'lib/bsv/wallet/interface/store.rb', line 128

def find_or_create_tags(names:)
  raise NotImplementedError
end

#find_spendable(satoshis:, basket: nil, exclude: []) ⇒ Array<Hash>

Find spendable outputs totalling at least the required satoshis. This is the database-level query — the UTXOPool wraps this with a selection strategy for higher tiers.

Parameters:

  • satoshis (Integer)

    minimum total value needed

  • basket (String, nil) (defaults to: nil)

    optional basket filter

  • exclude (Array<Integer>) (defaults to: [])

    output IDs to skip (e.g. from a failed lock attempt)

Returns:

  • (Array<Hash>)

    candidates: :id, :satoshis, :vout, :locking_script, :action_id

Raises:

  • (NotImplementedError)


227
228
229
# File 'lib/bsv/wallet/interface/store.rb', line 227

def find_spendable(satoshis:, basket: nil, exclude: [])
  raise NotImplementedError
end

#get_setting(key:) ⇒ String?

Retrieve a setting value by key.

Returns:

  • (String, nil)

Raises:

  • (NotImplementedError)


166
167
168
# File 'lib/bsv/wallet/interface/store.rb', line 166

def get_setting(key:)
  raise NotImplementedError
end

#label_action(action_id:, label_ids:) ⇒ Object

Attach labels to an action.

Raises:

  • (NotImplementedError)


138
139
140
# File 'lib/bsv/wallet/interface/store.rb', line 138

def label_action(action_id:, label_ids:)
  raise NotImplementedError
end

Link a merkle proof to an action (marks it as completed).

Parameters:

  • action_id (Integer)
  • tx_proof_id (Integer)

Raises:

  • (NotImplementedError)


67
68
69
# File 'lib/bsv/wallet/interface/store.rb', line 67

def link_proof(action_id:, tx_proof_id:)
  raise NotImplementedError
end

#promote_action(action_id:, outputs:) ⇒ Array<Integer>

Phase 4: Promote — write outputs after broadcast acceptance.

Inserts output rows (immutable log), spendable entries, basket memberships, output details, and tags in one transaction.

Parameters:

  • action_id (Integer)
  • outputs (Array<Hash>)

    each: :satoshis, :vout, :locking_script, :derivation_prefix, :derivation_suffix, :sender_identity_key, :basket, :tags, :description, :custom_instructions, :change

Returns:

  • (Array<Integer>)

    output IDs in the same order as outputs

Raises:

  • (NotImplementedError)


59
60
61
# File 'lib/bsv/wallet/interface/store.rb', line 59

def promote_action(action_id:, outputs:)
  raise NotImplementedError
end

#promote_change_to_spendable(action_id:) ⇒ Object

Promote change outputs to spendable for an action.

Creates spendable rows for change outputs that don’t already have one. Called after broadcast acceptance or in the no_send path.

Parameters:

  • action_id (Integer)

Raises:

  • (NotImplementedError)


213
214
215
# File 'lib/bsv/wallet/interface/store.rb', line 213

def promote_change_to_spendable(action_id:)
  raise NotImplementedError
end

#query_actions(labels:, label_query_mode: :any, limit: 10, offset: 0, include_labels: false, include_inputs: false, include_input_locking_scripts: false, include_input_unlocking_scripts: false, include_outputs: false, include_output_locking_scripts: false) ⇒ Hash

Query actions by labels with pagination.

Returns:

  • (Hash)

    :total, :actions

Raises:

  • (NotImplementedError)


91
92
93
94
95
96
97
# File 'lib/bsv/wallet/interface/store.rb', line 91

def query_actions(labels:, label_query_mode: :any, limit: 10, offset: 0,
                  include_labels: false, include_inputs: false,
                  include_input_locking_scripts: false,
                  include_input_unlocking_scripts: false,
                  include_outputs: false, include_output_locking_scripts: false)
  raise NotImplementedError
end

#query_certificates(certifiers:, types:, limit: 10, offset: 0) ⇒ Hash

Query certificates by certifiers and types.

Returns:

  • (Hash)

    :total, :certificates

Raises:

  • (NotImplementedError)


152
153
154
# File 'lib/bsv/wallet/interface/store.rb', line 152

def query_certificates(certifiers:, types:, limit: 10, offset: 0)
  raise NotImplementedError
end

#query_change_output_vouts(action_id:) ⇒ Array<Integer>

Return vout positions of change outputs for an action.

Queries outputs joined to output_details where change is true. Used by Engine#query_change_outpoints for the no_send_change response.

Parameters:

  • action_id (Integer)

Returns:

  • (Array<Integer>)

    vout positions

Raises:

  • (NotImplementedError)


203
204
205
# File 'lib/bsv/wallet/interface/store.rb', line 203

def query_change_output_vouts(action_id:)
  raise NotImplementedError
end

#query_outputs(basket:, tags: nil, tag_query_mode: :any, limit: 10, offset: 0, include_locking_scripts: false, include_custom_instructions: false, include_tags: false, include_labels: false) ⇒ Hash

Query spendable outputs in a basket with optional tag filtering.

Returns:

  • (Hash)

    :total, :outputs

Raises:

  • (NotImplementedError)


102
103
104
105
106
107
108
# File 'lib/bsv/wallet/interface/store.rb', line 102

def query_outputs(basket:, tags: nil, tag_query_mode: :any,
                  limit: 10, offset: 0,
                  include_locking_scripts: false,
                  include_custom_instructions: false,
                  include_tags: false, include_labels: false)
  raise NotImplementedError
end

#reap_stale_actions(threshold:) ⇒ Integer

Delete stale unsigned or unbroadcast actions older than the threshold. CASCADE deletes inputs, releasing locked UTXOs.

Parameters:

  • threshold (Integer)

    age in seconds

Returns:

  • (Integer)

    number of actions reaped

Raises:

  • (NotImplementedError)


238
239
240
# File 'lib/bsv/wallet/interface/store.rb', line 238

def reap_stale_actions(threshold:)
  raise NotImplementedError
end

#relinquish_output(output_id:) ⇒ Object

Remove an output from the UTXO set and its basket. The output row stays in the immutable log.

Parameters:

  • output_id (Integer)

Raises:

  • (NotImplementedError)


116
117
118
# File 'lib/bsv/wallet/interface/store.rb', line 116

def relinquish_output(output_id:)
  raise NotImplementedError
end

#resolve_inputs_for_signing(action_id:) ⇒ Array<Hash>

Resolve the full context for each locked input of an action.

Joins inputs → outputs → actions (the action that created the output, not the current action) to gather the source outpoint, satoshis, locking script, and derivation parameters needed for transaction construction and signing.

Parameters:

  • action_id (Integer)

Returns:

  • (Array<Hash>)

    ordered by vin, each: :vin, :sequence, :source_wtxid (32-byte binary, wire byte order), :source_vout, :source_satoshis, :source_locking_script (binary), :derivation_prefix, :derivation_suffix, :sender_identity_key

Raises:

  • (RuntimeError)

    if any source action has a nil wtxid



190
191
192
# File 'lib/bsv/wallet/interface/store.rb', line 190

def resolve_inputs_for_signing(action_id:)
  raise NotImplementedError
end

#save_certificate(certificate) ⇒ Object

Persist a certificate with its fields.

Raises:

  • (NotImplementedError)


145
146
147
# File 'lib/bsv/wallet/interface/store.rb', line 145

def save_certificate(certificate)
  raise NotImplementedError
end

#set_setting(key:, value:) ⇒ Object

Set a setting value (upsert).

Raises:

  • (NotImplementedError)


171
172
173
# File 'lib/bsv/wallet/interface/store.rb', line 171

def set_setting(key:, value:)
  raise NotImplementedError
end

#sign_action(action_id:, wtxid:, raw_tx:, change_outputs: []) ⇒ Object

Phase 2: Attach wtxid and signed raw transaction to an action.

When change_outputs is present, writes change output rows (outputs + output_details) atomically within the same database transaction. No spendable rows — promotion happens after broadcast acceptance. This ensures signing failure produces zero orphan rows.

Parameters:

  • action_id (Integer)
  • wtxid (String)

    32-byte binary wtxid (wire byte order)

  • raw_tx (String)

    binary-encoded signed transaction

  • change_outputs (Array<Hash>) (defaults to: [])

    optional change outputs to write atomically. Each: :satoshis, :vout, :locking_script, :derivation_prefix, :derivation_suffix, :sender_identity_key

Raises:

  • (NotImplementedError)


45
46
47
# File 'lib/bsv/wallet/interface/store.rb', line 45

def sign_action(action_id:, wtxid:, raw_tx:, change_outputs: [])
  raise NotImplementedError
end