ReadModelStorage class abstract
Abstract interface for read-model storage operations.
This interface handles query operations for wallet data projections, including UTXOs, transactions, block headers, and merkle proofs. This represents the "read side" of CQRS pattern.
Rules every backend follows (audit 2026-09-14 S-15, S-19; contract tests
in test/storage/wallet_lifecycle_contract.dart):
- A wallet exists when its metadata row exists (storeWallet); UTXO, transaction or address rows alone do not create a wallet.
- deleteWallet is a hard delete; storing the wallet again creates it afresh.
- Queries for an unknown wallet return empty results (zero balance, null metadata) and never throw.
- List queries return the newest rows first (
createdAtdescending): listWallets, getWalletIds, getUTXOs, getUTXOsByPlugin, getTransactionHistory, getTransactionsByStatus, getAddressesWithMetadata, getTransactionsByAddress and the invoice lists.
- Implementers
Constructors
Properties
- hashCode → int
-
The hash code for this object.
no setterinherited
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
checkAddresses(
String walletId, List< String> addresses) → Future<Map< String, bool> > - Batch check if addresses belong to wallet (optimized for bulk operations)
-
countSpentUTXOs(
String walletId) → Future< int> - How many of the wallet's UTXO rows are spent.
-
deletePaymentChannel(
String channelId) → Future< void> - Delete a payment channel
-
deleteUTXO(
String walletId, String txid, int vout) → Future< void> - Delete a UTXO from the read model.
-
deleteWallet(
String walletId) → Future< void> - Delete all data for a specific wallet.
-
getAddressCount(
String walletId) → Future< int> - Get the count of addresses for a wallet (for verification during import)
-
getAddressesByPurpose(
String walletId, String purpose) → Future< List< AddressMetadata> > -
The wallet's address rows whose purpose is
purpose(for examplewatch), in no particular order. Filtered in the backend: only the matching rows are loaded (bead libspiffy-p4kv). -
getAddressesWithMetadata(
String walletId, {bool? includeUnused, bool? isChange, int? limit, int? offset}) → Future< List< AddressMetadata> > - Get all addresses for a wallet with pagination
-
getAddressMetadata(
String walletId, String address) → Future< AddressMetadata?> - Get address metadata if it belongs to wallet
-
getAddressRange(
String walletId, {required int startIndex, required int count, bool isChange = false}) → Future< List< AddressMetadata> > - Get addresses by derivation range (efficient for HD wallets)
-
getAddressTransactionCount(
String walletId, String address) → Future< int> - Get transaction count for an address
-
getAncestorTransactionsBatch(
List< String> txids) → Future<Map< String, String> > -
The raw hex of every stored ancestor transaction among
txids, as a map txid → rawHex (txids without a row are absent). -
getAvailableUTXOs(
String walletId) → Future< List< BitcoinUtxo> > - Get only available (unspent and unreserved) UTXOs for a wallet.
-
getBalance(
String walletId) → Future< BigInt> - Calculate the total balance for a wallet.
-
getBestHeight(
) → Future< int> - Get current best block height
-
getBlockHeaderByHash(
String hash) → Future< BlockHeader?> - Get block header by hash
-
getBlockHeaderByHeight(
int height) → Future< BlockHeader?> - Get block header by height
-
getBlockHeaderRange(
int fromHeight, int toHeight) → Future< List< BlockHeader> > - Get range of block headers
-
getChainTip(
) → Future< BlockHeader?> - Get current chain tip header
-
getConfirmedTransactionsFromHeight(
int minHeight, {bool includeWithoutHeight = false}) → Future< List< BitcoinTransaction> > -
Confirmed rows of every wallet whose
blockHeightis at leastminHeight; withincludeWithoutHeight, also confirmed rows that have no block height (bead libspiffy-ctkm). Rows come newest first (createdAtdescending). -
getDeferredPayment(
String walletId, String txid) → Future< DeferredPayment?> -
The deferred payment
txidofwalletId, or null. -
getHeightByBlockHash(
String hash) → Future< int?> - Get height for a block hash
-
getInvoice(
String invoiceId) → Future< InvoiceReadModel?> - Get a specific invoice by ID.
-
getInvoicesByStatus(
InvoiceStatus status, {String? walletId}) → Future< List< InvoiceReadModel> > - Get all invoices with a specific status, newest first.
-
getInvoicesByWallet(
String walletId) → Future< List< InvoiceReadModel> > - Get all invoices for a specific wallet, newest first.
-
getMerkleProof(
String txid) → Future< MerkleProof?> -
The current proof of
txid: its one MerkleProof.isCurrent row (MerkleProofStatus.verified or MerkleProofStatus.pendingHeader), or null. Orphaned and rejected rows are never returned. -
getMerkleProofCount(
{String? walletId}) → Future< int> - Get the count of stored merkle proofs.
-
getMerkleProofHistory(
String txid) → Future< List< MerkleProof> > -
Every proof row stored for
txid, orphaned and rejected ones included, oldest first. -
getMerkleProofsBatch(
List< String> txids) → Future<Map< String, MerkleProof> > - Batch get the current proofs by txid list (see getMerkleProof).
-
getMerkleProofsByStatus(
MerkleProofStatus status) → Future< List< MerkleProof> > -
Every proof row with
status(for example the MerkleProofStatus.pendingHeader proofs to check once headers arrive). -
getMerkleProofsByStatusBetweenHeights(
MerkleProofStatus status, int fromHeight, int toHeight) → Future< List< MerkleProof> > -
The proof rows with
statuswhose block height is betweenfromHeightandtoHeight(both inclusive), oldest first (bead libspiffy-hg0). -
getMerkleProofsByStatusChangedSince(
MerkleProofStatus status, DateTime since) → Future< List< MerkleProof> > -
The proof rows with
statuswhose status changed at or aftersince(MerkleProof.statusChangedAt), oldest first (bead libspiffy-hccp). Rows without astatusChangedAtare not returned. -
getMerkleProofsForBlock(
String blockHash) → Future< List< MerkleProof> > -
The current (MerkleProof.isCurrent) proofs that name
blockHash. -
getOutputsAwaitingAncestorProof(
String walletId, {int maxDepth = 20}) → Future< List< OutputAwaitingProof> > - The wallet's unspent outputs that cannot be proven to a counterparty right now, each with the ancestors that stand in the way (bead libspiffy-0lx).
-
getPaymentChannel(
String channelId) → Future< PaymentChannel?> - Get a payment channel by ID.
-
getPaymentChannelsForWallet(
String walletId) → Future< List< PaymentChannel> > - Get all payment channels for a wallet.
-
getPaymentUTXOs(
String walletId) → Future< List< BitcoinUtxo> > - Get available UTXOs suitable for BSV payments.
-
getPendingReceive(
String walletId, String txid) → Future< PendingReceive?> -
The parked receive of (
walletId,txid), resolved or not. -
getPendingReceivesUpToHeight(
int height, {int limit = 64}) → Future< List< PendingReceive> > -
The receives still waiting (PendingReceive.isWaiting) whose
neededHeightis at mostheight, oldest first, at mostlimitof them. -
getRecentHeaders(
int count) → Future< List< BlockHeader> > - Get recent block headers
-
getTransaction(
String txid, {String? walletId}) → Future< BitcoinTransaction?> - Get a specific transaction by ID.
-
getTransactionAddresses(
String walletId, String txid) → Future< TransactionAddresses> - Get all addresses involved in a transaction
-
getTransactionHistory(
String walletId, {int? limit, int? offset}) → Future< List< BitcoinTransaction> > - Get transaction history for a wallet
-
getTransactionsBatch(
List< String> txids) → Future<Map< String, BitcoinTransaction> > - Batch get transactions by txid list
-
getTransactionsByAddress(
String walletId, String address, {String? direction, int? limit, int? offset}) → Future< List< String> > - Get all transactions involving a specific address
-
getTransactionsByStatus(
TransactionStatus status, {String? walletId}) → Future< List< BitcoinTransaction> > - Get transactions by status
-
getTransactionsByStatusSince(
TransactionStatus status, DateTime since, {int limit = 100}) → Future< List< BitcoinTransaction> > -
The rows with
statuslast updated at or aftersince, newest first (updatedAtdescending), at mostlimitof them (bead libspiffy-5bju). -
getTransactionsByTxids(
List< String> txids) → Future<List< BitcoinTransaction> > -
Every wallet's row for each of
txids(bead libspiffy-ctkm). -
getUTXO(
String walletId, String txid, int vout) → Future< BitcoinUtxo?> - The wallet's UTXO row for one outpoint, or null when it holds none.
-
getUTXOs(
String walletId, {bool includeSpent = false}) → Future< List< BitcoinUtxo> > - Get all UTXOs for a specific wallet.
-
getUTXOsByPlugin(
String walletId, String pluginId, {Map< String, dynamic> ? metadataFilter}) → Future<List< BitcoinUtxo> > - Get UTXOs managed by a specific plugin.
-
getUTXOsByTxid(
String walletId, String txid, {bool includeSpent = false}) → Future< List< BitcoinUtxo> > -
The wallet's UTXO rows created by
txid, newest first. -
getWallet(
String walletId) → Future< Map< String, dynamic> ?> -
Get wallet metadata; null for an unknown or deleted wallet. The
metadataentry is a map, empty when the wallet has none, never null. -
getWalletAddresses(
String walletId) → Future< List< String> > - Get all addresses for a wallet
-
getWalletIds(
) → Future< List< String> > - Get a list of all wallet IDs in storage.
-
getWatchOnlyBalance(
String walletId) → Future< BigInt> -
The watch-only part of the wallet's getPaymentUTXOs: available UTXOs
the wallet holds no key for because a key they need is a watch address
(bead libspiffy-vsap). Not part of getBalance; the coordinator's
BalanceResponse.watchOnlyBalance. -
isWalletAddress(
String walletId, String address) → Future< bool> - Check if an address belongs to a wallet (O(1) hash lookup)
-
listDeferredPayments(
String walletId, {DeferredPaymentQuery query = const DeferredPaymentQuery()}) → Future< DeferredPaymentPage> -
A page of
walletId's deferred payments matchingquery, in its order (createdAt, then txid; newest first unless DeferredPaymentQuery.oldestFirst). Backends answer the default outstanding-only query from an index on (wallet, state, createdAt), never by reading every row. Throws FormatException for a cursor this API did not produce. -
listInvoices(
{String? walletId, InvoiceStatus? status}) → Future< List< InvoiceReadModel> > - List invoices, newest first.
-
listWallets(
) → Future< List< String> > - List the IDs of all existing wallets, newest first.
-
markHeaderAsOrphaned(
String hash) → Future< void> - Mark a block header as orphaned due to reorganization
-
markMerkleProofOrphaned(
String txid, {String? blockHash, List< String> ? onlyIfMerkleProof, DateTime? at}) → Future<bool> -
Mark the current proof of
txidorphaned: its block left the active chain (audit 3b0, bead libspiffy-mny). The row is kept and stays readable through getMerkleProofHistory; getMerkleProof no longer returns it. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
resolvePendingReceive(
String walletId, String txid, String resolution, {DateTime? at}) → Future< bool> -
Record that the receive of (
walletId,txid) stopped waiting:resolutionsays why (it was recorded, or it failed for a reason more headers cannot change). The row is kept, and no longer replayed. -
storeAncestorTransaction(
String txid, String rawHex) → Future< void> -
Store the raw transaction
rawHexoftxidas ancestor evidence. -
storeBlockHeader(
BlockHeader header, int height) → Future< void> -
Store a block header as part of the active chain at
height. -
storeBlockHeadersBulk(
List< (BlockHeader, int)> headers) → Future<void> - Bulk store block headers for fast initial sync (CDN import).
-
storeDeferredPayment(
DeferredPayment payment) → Future< void> -
Insert or replace the row of
payment(key: walletId, txid). -
storeInvoice(
InvoiceReadModel invoice) → Future< void> -
Store an invoice read model (insert, or replace an existing row with
the same
invoiceId). -
storeMerkleProof(
String txid, MerkleProof proof) → Future< void> - Store merkle proof for a transaction.
-
storePaymentChannel(
PaymentChannel channel) → Future< void> -
Store a payment channel (insert, or replace every mutable column of an
existing row with the same
channelId). -
storePendingReceive(
PendingReceive receive) → Future< void> -
Park
receiveuntil headers reach itsneededHeight, or update the row already parked for its (walletId, txid). -
storeRevertedTransaction(
String walletId, BitcoinTransaction transaction) → Future< void> -
Stores
transactionas the row of (walletId, txid) with the status, block height and confirmations it carries, even when that lowers a confirmed status: the one way a confirmation is taken back, used for a reorganization past the confirming block or a proof its block header contradicts (audit 3b0, bead libspiffy-7dj). A non-confirmed record clears the stored block height. Raw hex and the other rules of storeTransaction apply; nothing is deleted. -
storeTransaction(
String walletId, BitcoinTransaction transaction) → Future< void> - Store a raw transaction in the read model.
-
storeTransactionAddresses(
String walletId, String txid, List< TransactionAddressLink> links) → Future<void> - Store transaction-address junction records.
-
storeWallet(
String walletId, String name, {String? rootAddress, String? networkType, Map< String, dynamic> ? metadata}) → Future<void> - Store or update wallet metadata.
-
toString(
) → String -
A string representation of this object.
inherited
-
updateAddressUsage(
String walletId, String address, {DateTime? usedAt, BigInt? balanceDelta}) → Future< void> - Update address usage statistics.
-
updateInvoiceStatus(
String invoiceId, InvoiceStatus status, {String? txid, BigInt? amountReceived, DateTime? paidAt}) → Future< void> - Update the status of an invoice.
-
updatePaymentChannelBalance(
String channelId, BigInt clientBalance, BigInt serverBalance) → Future< void> - Update payment channel balances
-
updatePaymentChannelState(
String channelId, String state) → Future< void> - Update payment channel state.
-
upsertAddress(
String walletId, AddressMetadata metadata) → Future< void> - Store or update address metadata
-
upsertUTXO(
String walletId, BitcoinUtxo utxo) → Future< void> - Upsert (insert or update) a UTXO in the read model.
-
walletExists(
String walletId) → Future< bool> - Check if a wallet exists in storage.
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited