SpentDustNullifierStore

@Singleton
class SpentDustNullifierStore @Inject constructor(dataStore: DataStore<Preferences>)

Durable, per-address record of dust nullifiers the wallet has spent and submitted but whose spend the indexer's dustLedgerEvents stream has not yet reflected.

Why this exists. The dust event stream does not reliably/promptly include the wallet's own dust fee spends (see docs/indexer-dust-fee-spend-question.md). So right after a fee-paying move, the synced dust state still lists the spent UTXO as available, and the next move re-selects it — the node then rejects the transaction with Custom error: 115 ("UTXO already spent"). The balancer must be able to skip nullifiers the wallet already spent, independent of the stream.

Lifecycle. A nullifier is recorded on a successful submit and pruned via retainPresent on the next balance, once the synced dust state no longer holds its UTXO (the stream has reflected the spend). The set is therefore bounded to the wallet's in-flight fee spends — submitted but not yet reflected in the stream. Excluding a nullifier whose UTXO is already gone would be a harmless no-op anyway, so the set is always correct; pruning just keeps it small.

Nullifiers are stored lowercase hex.

Constructors

Link copied to clipboard
@Inject
constructor(dataStore: DataStore<Preferences>)

Functions

Link copied to clipboard
suspend fun clear(address: String)

Drop all tracking for an address (e.g. wallet reset).

Link copied to clipboard
suspend fun recordSpent(address: String, nullifierHex: String)

Record a nullifier the wallet just spent + submitted, so it isn't re-selected.

Link copied to clipboard
suspend fun retainPresent(address: String, presentNullifiers: Set<String>)

Prune recorded nullifiers the chain has confirmed spent. presentNullifiers is the set of nullifiers (lowercase hex) the freshly-synced dust state still holds. A recorded nullifier is kept only while its UTXO is still present (stream behind); once it's gone (stream caught up), it's dropped.

Link copied to clipboard
suspend fun spentNullifiers(address: String): Set<String>

Nullifiers (lowercase hex) the wallet has spent but the stream hasn't confirmed gone.