Skip to main content

WalletRead

Trait WalletRead 

Source
pub trait WalletRead {
    type Error: Debug;
    type AccountId: Copy + Debug + Eq + Hash;
    type Account: Account<AccountId = Self::AccountId>;

Show 39 methods // Required methods fn get_account_ids(&self) -> Result<Vec<Self::AccountId>, Self::Error>; fn get_account( &self, account_id: Self::AccountId, ) -> Result<Option<Self::Account>, Self::Error>; fn get_derived_account( &self, derivation: &Zip32Derivation, ) -> Result<Option<Self::Account>, Self::Error>; fn validate_seed( &self, account_id: Self::AccountId, seed: &SecretVec<u8>, ) -> Result<bool, Self::Error>; fn seed_relevance_to_derived_accounts( &self, seed: &SecretVec<u8>, ) -> Result<SeedRelevance<Self::AccountId>, Self::Error>; fn get_account_for_ufvk( &self, ufvk: &UnifiedFullViewingKey, ) -> Result<Option<Self::Account>, Self::Error>; fn list_addresses( &self, account: Self::AccountId, ) -> Result<Vec<AddressInfo>, Self::Error>; fn find_account_for_address<P: Parameters>( &self, params: &P, address: &Address, ) -> Result<Option<Self::AccountId>, FindAccountForAddressError<Self::Error>>; fn get_last_generated_address_matching( &self, account: Self::AccountId, address_filter: UnifiedAddressRequest, ) -> Result<Option<UnifiedAddress>, Self::Error>; fn get_account_birthday( &self, account: Self::AccountId, ) -> Result<BlockHeight, Self::Error>; fn get_wallet_birthday(&self) -> Result<Option<BlockHeight>, Self::Error>; fn get_wallet_recover_until( &self, ) -> Result<Option<BlockHeight>, Self::Error>; fn get_wallet_summary( &self, confirmations_policy: ConfirmationsPolicy, ) -> Result<Option<WalletSummary<Self::AccountId>>, Self::Error>; fn chain_height(&self) -> Result<Option<BlockHeight>, Self::Error>; fn get_block_hash( &self, block_height: BlockHeight, ) -> Result<Option<BlockHash>, Self::Error>; fn block_metadata( &self, height: BlockHeight, ) -> Result<Option<BlockMetadata>, Self::Error>; fn block_fully_scanned(&self) -> Result<Option<BlockMetadata>, Self::Error>; fn get_max_height_hash( &self, ) -> Result<Option<(BlockHeight, BlockHash)>, Self::Error>; fn block_max_scanned(&self) -> Result<Option<BlockMetadata>, Self::Error>; fn suggest_scan_ranges(&self) -> Result<Vec<ScanRange>, Self::Error>; fn get_target_and_anchor_heights( &self, min_confirmations: NonZeroU32, ) -> Result<Option<(TargetHeight, BlockHeight)>, Self::Error>; fn get_tx_height( &self, txid: TxId, ) -> Result<Option<BlockHeight>, Self::Error>; fn get_unified_full_viewing_keys( &self, ) -> Result<HashMap<Self::AccountId, UnifiedFullViewingKey>, Self::Error>; fn get_memo(&self, note_id: NoteId) -> Result<Option<Memo>, Self::Error>; fn get_transaction( &self, txid: TxId, ) -> Result<Option<Transaction>, Self::Error>; fn get_sapling_nullifiers( &self, query: NullifierQuery, ) -> Result<Vec<(Self::AccountId, Nullifier)>, Self::Error>; fn get_ironwood_nullifiers( &self, query: NullifierQuery, ) -> Result<Vec<(Self::AccountId, Nullifier)>, Self::Error>; fn get_unspent_transparent_outpoints( &self, ) -> Result<HashMap<OutPoint, Self::AccountId>, Self::Error>; fn get_transparent_receiver_accounts( &self, ) -> Result<HashMap<TransparentAddress, (Self::AccountId, Option<TransparentKeyScope>)>, Self::Error>; fn transaction_data_requests( &self, ) -> Result<Vec<TransactionDataRequest>, Self::Error>; fn get_received_outputs( &self, txid: TxId, target_height: TargetHeight, confirmations_policy: ConfirmationsPolicy, ) -> Result<Vec<ReceivedTransactionOutput>, Self::Error>; // Provided methods fn anchor_retention_interval(&self) -> AnchorRetentionInterval { ... } fn pool_migration_params<P: Parameters>( &self, params: &P, ) -> PoolMigrationParams { ... } fn get_orchard_nullifiers( &self, _query: NullifierQuery, ) -> Result<Vec<(Self::AccountId, Nullifier)>, Self::Error> { ... } fn get_transparent_receivers( &self, _account: Self::AccountId, _include_change: bool, _include_standalone: bool, ) -> Result<HashMap<TransparentAddress, TransparentAddressMetadata>, Self::Error> { ... } fn get_ephemeral_transparent_receivers( &self, _account: Self::AccountId, _exposure_depth: u32, _exclude_used: bool, ) -> Result<HashMap<TransparentAddress, TransparentAddressMetadata>, Self::Error> { ... } fn get_transparent_balances( &self, _account: Self::AccountId, _target_height: TargetHeight, _confirmations_policy: ConfirmationsPolicy, ) -> Result<TransparentBalances, Self::Error> { ... } fn get_transparent_address_metadata( &self, _account: Self::AccountId, _address: &TransparentAddress, ) -> Result<Option<TransparentAddressMetadata>, Self::Error> { ... } fn utxo_query_height( &self, _account: Self::AccountId, ) -> Result<BlockHeight, Self::Error> { ... }
}
Expand description

Read-only operations required for light wallet functions.

This trait defines the read-only portion of the storage interface atop which higher-level wallet operations are implemented. It serves to allow wallet functions to be abstracted away from any particular data storage substrate.

Required Associated Types§

Source

type Error: Debug

The type of errors that may be generated when querying a wallet data store.

Source

type AccountId: Copy + Debug + Eq + Hash

The type of the account identifier.

An account identifier corresponds to at most a single unified spending key’s worth of spend authority, such that both received notes and change spendable by that spending authority will be interpreted as belonging to that account.

Source

type Account: Account<AccountId = Self::AccountId>

The concrete account type used by this wallet backend.

Required Methods§

Source

fn get_account_ids(&self) -> Result<Vec<Self::AccountId>, Self::Error>

Returns a vector with the IDs of all accounts known to this wallet.

Source

fn get_account( &self, account_id: Self::AccountId, ) -> Result<Option<Self::Account>, Self::Error>

Returns the account corresponding to the given ID, if any.

Source

fn get_derived_account( &self, derivation: &Zip32Derivation, ) -> Result<Option<Self::Account>, Self::Error>

Returns the account corresponding to a given [SeedFingerprint] and [zip32::AccountId], if any.

Source

fn validate_seed( &self, account_id: Self::AccountId, seed: &SecretVec<u8>, ) -> Result<bool, Self::Error>

Verifies that the given seed corresponds to the viewing key for the specified account.

Returns:

  • Ok(true) if the viewing key for the specified account can be derived from the provided seed.
  • Ok(false) if the derived viewing key does not match, or the specified account is not present in the database.
  • Err(_) if a Unified Spending Key cannot be derived from the seed for the specified account or the account has no known ZIP-32 derivation.
Source

fn seed_relevance_to_derived_accounts( &self, seed: &SecretVec<u8>, ) -> Result<SeedRelevance<Self::AccountId>, Self::Error>

Checks whether the given seed is relevant to any of the derived accounts (where Account::source is AccountSource::Derived) in the wallet.

This API does not check whether the seed is relevant to any imported account, because that would require brute-forcing the ZIP 32 account index space.

Source

fn get_account_for_ufvk( &self, ufvk: &UnifiedFullViewingKey, ) -> Result<Option<Self::Account>, Self::Error>

Returns the account corresponding to a given UnifiedFullViewingKey, if any.

Source

fn list_addresses( &self, account: Self::AccountId, ) -> Result<Vec<AddressInfo>, Self::Error>

Returns information about every address tracked for this account.

An exposed unified address can omit the transparent receiver that the wallet tracks at its diversifier index. The result then also contains that receiver, as an Address::Transparent entry whose AddressSource has the same diversifier index.

Source

fn find_account_for_address<P: Parameters>( &self, params: &P, address: &Address, ) -> Result<Option<Self::AccountId>, FindAccountForAddressError<Self::Error>>

Returns the wallet account that controls the given address, if any.

Backends that can answer this query from an indexed lookup should implement it directly. Backends without such an index can delegate to defaults::find_account_for_address, which implements the semantics described below using UnifiedIncomingViewingKey::decrypt_diversifiers and a linear scan over Self::get_account_ids / Self::list_addresses.

§Unified Addresses

For a Unified Address each account’s UnifiedIncomingViewingKey is asked, via UnifiedIncomingViewingKey::decrypt_diversifiers, whether it could have derived any shielded receiver of the UA. An account matches if at least one shielded receiver is attributable to it — including receivers that have never been previously exposed by the wallet. If the shielded receivers of the UA are attributable to more than one account, this is treated as an inconsistent (“frankenstein”) address and FindAccountForAddressError::UnifiedAddressConflict is returned rather than arbitrarily selecting one account.

Backends are permitted to additionally resolve UAs by exact match against their tracked-address index before (or instead of) running the UIVK-algebra step, provided the exact-match result is consistent with at least one account identified by the algebraic step.

§Non-Unified Addresses

Backends should resolve bare shielded addresses (Sapling) via the same UIVK-algebraic path where feasible, so that an address derivable from an account’s UIVK is resolved whether or not it has been previously exposed. Backends that do not can treat a bare shielded address as an exact-match lookup over their tracked-address index.

Transparent and TEX addresses are resolved by exact match against tracked addresses only, since a diversifier index cannot be recovered from a transparent receiver alone.

§Returns
  • Ok(Some(account_id)) if the address is controlled by a single account known to this wallet.
  • Ok(None) if no receiver of the address is recognized as belonging to any account.
  • Err(FindAccountForAddressError::Backend(_)) if the lookup fails due to a backend error.
  • Err(FindAccountForAddressError::UnifiedAddressConflict) if the provided address is a Unified Address whose receiver components map to different accounts.
Source

fn get_last_generated_address_matching( &self, account: Self::AccountId, address_filter: UnifiedAddressRequest, ) -> Result<Option<UnifiedAddress>, Self::Error>

Returns the most recently generated unified address for the specified account that conforms to the specified address filter, if the account identifier specified refers to a valid account for this wallet.

This will return Ok(None) if no previously generated address conforms to the specified request.

Source

fn get_account_birthday( &self, account: Self::AccountId, ) -> Result<BlockHeight, Self::Error>

Returns the birthday height for the given account, or an error if the account is not known to the wallet.

Source

fn get_wallet_birthday(&self) -> Result<Option<BlockHeight>, Self::Error>

Returns the birthday height for the wallet.

This returns the earliest birthday height among accounts maintained by this wallet, or Ok(None) if the wallet has no initialized accounts.

Source

fn get_wallet_recover_until(&self) -> Result<Option<BlockHeight>, Self::Error>

Returns the height at which the wallet as a whole will have exited recovery mode.

This returns the latest recover_until height among accounts maintained by this wallet (see AccountBirthday::recover_until), or Ok(None) if no account has a recovery horizon set (for example, in a wallet whose accounts were all created at the chain tip rather than restored from backup). Heights below the returned value, exclusive, are in scope for wallet recovery for at least one account.

Source

fn get_wallet_summary( &self, confirmations_policy: ConfirmationsPolicy, ) -> Result<Option<WalletSummary<Self::AccountId>>, Self::Error>

Returns a WalletSummary that represents the sync status and the wallet balances as of the chain tip given the specified confirmation policy for all accounts known to the wallet, or Ok(None) if the wallet has no summary data available.

Source

fn chain_height(&self) -> Result<Option<BlockHeight>, Self::Error>

Returns the height of the chain as known to the wallet as of the most recent call to WalletWrite::update_chain_tip.

This will return Ok(None) if the height of the current consensus chain tip is unknown.

Source

fn get_block_hash( &self, block_height: BlockHeight, ) -> Result<Option<BlockHash>, Self::Error>

Returns the block hash for the block at the given height, if the associated block data is available. Returns Ok(None) if the hash is not found in the database.

Source

fn block_metadata( &self, height: BlockHeight, ) -> Result<Option<BlockMetadata>, Self::Error>

Returns the available block metadata for the block at the specified height, if any.

Source

fn block_fully_scanned(&self) -> Result<Option<BlockMetadata>, Self::Error>

Returns the metadata for the block at the height to which the wallet has been fully scanned.

This is the height for which the wallet has fully trial-decrypted this and all preceding blocks above the wallet’s birthday height. Along with this height, this method returns metadata describing the state of the wallet’s note commitment trees as of the end of that block.

Source

fn get_max_height_hash( &self, ) -> Result<Option<(BlockHeight, BlockHash)>, Self::Error>

Returns the block height and hash for the block at the maximum scanned block height.

This will return Ok(None) if no blocks have been scanned.

Source

fn block_max_scanned(&self) -> Result<Option<BlockMetadata>, Self::Error>

Returns block metadata for the maximum height that the wallet has scanned.

If the wallet is fully synced, this will be equivalent to block_fully_scanned; otherwise the maximal scanned height is likely to be greater than the fully scanned height due to the fact that out-of-order scanning can leave gaps.

Source

fn suggest_scan_ranges(&self) -> Result<Vec<ScanRange>, Self::Error>

Returns a vector of suggested scan ranges based upon the current wallet state.

This method should only be used in cases where the CompactBlock data that will be made available to scan_cached_blocks for the requested block ranges includes note commitment tree size information for each block; or else the scan is likely to fail if notes belonging to the wallet are detected.

The returned range(s) may include block heights beyond the current chain tip. Ranges are returned in order of descending priority, and higher-priority ranges should always be scanned before lower-priority ranges; in particular, ranges with ScanPriority::Verify priority must always be scanned first in order to avoid blockchain continuity errors in the case of a reorg.

Source

fn get_target_and_anchor_heights( &self, min_confirmations: NonZeroU32, ) -> Result<Option<(TargetHeight, BlockHeight)>, Self::Error>

Returns the default target height (for the block in which a new transaction would be mined) and anchor height (to use for a new transaction), given the range of block heights that the backend knows about.

This will return Ok(None) if no block data is present in the database.

Source

fn get_tx_height(&self, txid: TxId) -> Result<Option<BlockHeight>, Self::Error>

Returns the block height in which the specified transaction was mined, or Ok(None) if the transaction is not known to the wallet or not in the main chain.

Source

fn get_unified_full_viewing_keys( &self, ) -> Result<HashMap<Self::AccountId, UnifiedFullViewingKey>, Self::Error>

Returns all unified full viewing keys known to this wallet.

Source

fn get_memo(&self, note_id: NoteId) -> Result<Option<Memo>, Self::Error>

Returns the memo for a note.

Returns Ok(None) if the note is known to the wallet but memo data has not yet been populated for that note, or if the note identifier does not correspond to a note that is known to the wallet.

Source

fn get_transaction( &self, txid: TxId, ) -> Result<Option<Transaction>, Self::Error>

Returns the transaction with the given txid, if known to the wallet.

Returns None if the txid is not known to the wallet or if the raw transaction data is not available.

Source

fn get_sapling_nullifiers( &self, query: NullifierQuery, ) -> Result<Vec<(Self::AccountId, Nullifier)>, Self::Error>

Returns the nullifiers for Sapling notes that the wallet is tracking, along with their associated account IDs, that are either unspent or have not yet been confirmed as spent (in that a spending transaction known to the wallet has not yet been included in a block).

Source

fn get_ironwood_nullifiers( &self, query: NullifierQuery, ) -> Result<Vec<(Self::AccountId, Nullifier)>, Self::Error>

Available on crate feature orchard only.

Returns the nullifiers for Ironwood notes that the wallet is tracking, along with their associated account IDs, that are either unspent or have not yet been confirmed as spent. Ironwood nullifiers are Orchard-shaped but are tracked as a separate pool.

This is a required method (like WalletRead::get_sapling_nullifiers) rather than defaulting to a panic: it is called on the scan path, so a backend that does not override it would abort the process on the first scan. Requiring it surfaces the omission at compile time instead.

Source

fn get_unspent_transparent_outpoints( &self, ) -> Result<HashMap<OutPoint, Self::AccountId>, Self::Error>

Available on crate feature transparent-inputs only.

Returns the outpoints of the transparent outputs that the wallet holds and does not know to have been spent, each mapped to the account that received it.

The result is the transparent counterpart of get_sapling_nullifiers(NullifierQuery::Unspent): it is the set of identifiers whose appearance in a scanned block reveals a spend of wallet funds. Unlike the queries that serve input selection, it applies no confirmation, coinbase-maturity or note-locking filter; an output is included whenever the wallet could still observe a spend of it.

This is a required method rather than one defaulting to a panic, for the same reason as Self::get_ironwood_nullifiers: it is called on the scan path, so a backend that did not override it would abort the process on the first scan.

Source

fn get_transparent_receiver_accounts( &self, ) -> Result<HashMap<TransparentAddress, (Self::AccountId, Option<TransparentKeyScope>)>, Self::Error>

Available on crate feature transparent-inputs only.

Returns every transparent receiver the wallet knows of, mapped to the account that controls it and, for an HD-derived receiver, the change-level key scope used to derive it.

The map covers receivers of every provenance: external and change receivers, ephemeral receivers, and addresses imported without key material. A scanned transparent output pays the wallet exactly when its recipient address is a key of this map.

This is a required method rather than one defaulting to a panic, for the same reason as Self::get_ironwood_nullifiers: it is called on the scan path, so a backend that did not override it would abort the process on the first scan.

Source

fn transaction_data_requests( &self, ) -> Result<Vec<TransactionDataRequest>, Self::Error>

Returns a vector of TransactionDataRequest values that describe information needed by the wallet to complete its view of transaction history.

Requests for the same transaction data may be returned repeatedly by successive data requests. The caller of this method should consider the latest set of requests returned by this method to be authoritative and to subsume that returned by previous calls.

Callers should poll this method on a regular interval, not as part of ordinary chain scanning, which already produces requests for transaction data enhancement. Note that responding to a set of transaction data requests may result in the creation of new transaction data requests, such as when it is necessary to fill in purely-transparent transaction history by walking the chain backwards via transparent inputs.

Source

fn get_received_outputs( &self, txid: TxId, target_height: TargetHeight, confirmations_policy: ConfirmationsPolicy, ) -> Result<Vec<ReceivedTransactionOutput>, Self::Error>

Returns a vector of ReceivedTransactionOutput values describing the outputs of the specified transaction that were received by the wallet. The number of confirmations until each received output will be considered spendable is determined based upon the specified target height and confirmations policy.

Provided Methods§

Source

fn anchor_retention_interval(&self) -> AnchorRetentionInterval

Returns the interval on which this wallet retains note commitment tree checkpoints as durable anchors.

A ZIP 318 pool migration anchors each of its pool-crossing transfers to a boundary of this interval, and proves the transfer long after that boundary has passed; the proof can only be constructed if the wallet kept the boundary’s checkpoint. Reading the grid back off the wallet that maintains it — rather than configuring the migration separately — is what guarantees the two agree.

The default implementation returns AnchorRetentionInterval::ZIP_318, which matches the retention a backend performs if it does not configure the interval. A backend that DOES make retention configurable must override this to report the interval it actually retains, or migrations over it will draw anchors it has pruned.

Source

fn pool_migration_params<P: Parameters>( &self, params: &P, ) -> PoolMigrationParams

Returns the ZIP 318 pool-migration parameters in force for this wallet on the network that params describe: the specified values, with the anchor bucket grid taken from Self::anchor_retention_interval.

Every decision that depends on the grid must consult this rather than the network defaults, so that a wallet retaining a non-standard interval is treated consistently: bucketing an anchor and judging the resulting transaction a canonical crossing are the same question asked twice, and they must be asked of the same grid. Overriding Self::anchor_retention_interval is sufficient; this composes it.

Source

fn get_orchard_nullifiers( &self, _query: NullifierQuery, ) -> Result<Vec<(Self::AccountId, Nullifier)>, Self::Error>

Available on crate feature orchard only.

Returns the nullifiers for Orchard notes that the wallet is tracking, along with their associated account IDs, that are either unspent or have not yet been confirmed as spent (in that a spending transaction known to the wallet has not yet been included in a block).

Source

fn get_transparent_receivers( &self, _account: Self::AccountId, _include_change: bool, _include_standalone: bool, ) -> Result<HashMap<TransparentAddress, TransparentAddressMetadata>, Self::Error>

Available on crate feature transparent-inputs only.

Returns the set of non-ephemeral transparent receivers associated with the given account controlled by this wallet.

The set contains all non-ephemeral transparent receivers that are known to have been derived under this account. Wallets should scan the chain for UTXOs sent to these receivers.

§Parameters
  • account: The identifier for the account from which transparent receivers should be returned.
  • include_change: A flag indicating whether transparent change addresses should be returned.
  • include_standalone: A flag indicating whether imported standalone addresses associated with the account should be returned. The value of this flag is ignored unless the transparent-key-import feature is enabled.

Use Self::get_ephemeral_transparent_receivers to obtain the ephemeral transparent receivers.

Source

fn get_ephemeral_transparent_receivers( &self, _account: Self::AccountId, _exposure_depth: u32, _exclude_used: bool, ) -> Result<HashMap<TransparentAddress, TransparentAddressMetadata>, Self::Error>

Available on crate feature transparent-inputs only.

Returns the set of previously-exposed ephemeral transparent receivers generated by the given account controlled by this wallet.

The set contains all ephemeral transparent receivers that are known to have been derived under this account within exposure_depth blocks of the chain tip. Wallets may scan the chain for UTXOs sent to these receivers, but should do so in a fashion that does not reveal that they are controlled by the same wallet. If the next_check_time field is set for a returned TransparentAddressMetadata, the wallet application should defer any query to any public light wallet server for this address until next_check_time has passed; when using a light wallet server that is trusted for privacy, this delay may be omitted.

§Parameters
  • account: The identifier for the account from which transparent receivers should be returned.
  • exposure_depth: Implementations of this method should return only addresses exposed at heights greater than chain_tip_height - exposure_depth.
  • exclude_used: When set to true, do not return addresses that are known to have already received funds in a transaction.
Source

fn get_transparent_balances( &self, _account: Self::AccountId, _target_height: TargetHeight, _confirmations_policy: ConfirmationsPolicy, ) -> Result<TransparentBalances, Self::Error>

Available on crate feature transparent-inputs only.

Returns a mapping from each transparent receiver associated with the specified account to the key scope for that address and the balance of funds given the specified target height and confirmations policy.

Source

fn get_transparent_address_metadata( &self, _account: Self::AccountId, _address: &TransparentAddress, ) -> Result<Option<TransparentAddressMetadata>, Self::Error>

Available on crate feature transparent-inputs only.

Returns the metadata associated with a given transparent receiver in an account controlled by this wallet, if available.

This is equivalent to (but may be implemented more efficiently than):

ⓘ
Ok(
    if let Some(result) = self.get_transparent_receivers(account, true)?.get(address) {
        Some(result.clone())
    } else {
        self.get_ephemeral_transparent_receivers(account, u32::MAX, false)?
            .get(address)
            .cloned()
    },
)

Returns Ok(None) if the address is not recognized, or we do not have metadata for it. Returns Ok(Some(metadata)) if we have the metadata.

Source

fn utxo_query_height( &self, _account: Self::AccountId, ) -> Result<BlockHeight, Self::Error>

Available on crate feature transparent-inputs only.

Returns the maximum block height at which a transparent output belonging to the wallet has been observed.

We must start looking for UTXOs for addresses within the current gap limit as of the block height at which they might have first been revealed. This would have occurred when the gap advanced as a consequence of a transaction being mined. The address at the start of the current gap was potentially first revealed after the address at index gap_start - (gap_limit + 1) received an output in a mined transaction; therefore, we take that height to be where we should start searching for UTXOs.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl WalletRead for MockWalletDb

Available on crate features test-dependencies only.