User Story
As a wallet application developer, I want TransactionRecord to carry the transaction's lifecycle status (mempool → IS-locked → confirmed → chain-locked) so that I can display meaningful status indicators to users without re-deriving state from height/block_hash fields.
Problem
TransactionContext already distinguishes Mempool, InBlock, and InChainLockedBlock — but record_transaction() in ManagedAccount discards the variant after extracting height/block_hash:
// managed_account/mod.rs:385-390
let tx_record = TransactionRecord {
height: context.block_height(), // Some(h) or None
block_hash: context.block_hash(), // Some(hash) or None
// TransactionContext variant is lost here
...
};
Consumers (like dash-evo-tool) can only infer height.is_some() → confirmed vs unconfirmed, losing the richer status information that was available at recording time.
Requested Changes
1. Add status field to TransactionRecord
pub struct TransactionRecord {
// ... existing fields ...
/// Transaction lifecycle status
pub status: TransactionContext,
}
Preserve the TransactionContext that's already passed to record_transaction().
2. Set Utxo.is_instantlocked on InstantSend lock receipt
The is_instantlocked field exists on Utxo and is used in coin selection (is_spendable(), coin_selection.rs), but is never set to true — it's initialized as false in Utxo::new() and no code path flips it.
When SyncEvent::InstantLockReceived fires, UTXOs belonging to the locked transaction should be updated.
3. Add status to WalletEvent::TransactionReceived
WalletEvent::TransactionReceived {
// ... existing fields ...
status: TransactionContext,
}
So consumers know if a received transaction is mempool/confirmed/chain-locked without re-querying the wallet.
4. (Nice to have) Add WalletEvent::TransactionStatusChanged
WalletEvent::TransactionStatusChanged {
wallet_id: WalletId,
txid: Txid,
old_status: TransactionContext,
new_status: TransactionContext,
}
Fires on status transitions (Mempool → IS-locked → Confirmed → ChainLocked), enabling reactive UI updates.
Context
dash-evo-tool PR dashpay/dash-evo-tool#776 integrates the MempoolManager with BloomFilter strategy. With mempool tracking active, the wallet now sees unconfirmed transactions — but we cannot distinguish them from IS-locked transactions in the UI because the status information is discarded upstream.
We're adding a TransactionStatus enum on the evo-tool side and inferring what we can from height, but full lifecycle tracking requires these upstream changes.
🤖 Co-authored by Claudius the Magnificent AI Agent
User Story
As a wallet application developer, I want
TransactionRecordto carry the transaction's lifecycle status (mempool → IS-locked → confirmed → chain-locked) so that I can display meaningful status indicators to users without re-deriving state fromheight/block_hashfields.Problem
TransactionContextalready distinguishesMempool,InBlock, andInChainLockedBlock— butrecord_transaction()inManagedAccountdiscards the variant after extractingheight/block_hash:Consumers (like dash-evo-tool) can only infer
height.is_some()→ confirmed vs unconfirmed, losing the richer status information that was available at recording time.Requested Changes
1. Add
statusfield toTransactionRecordPreserve the
TransactionContextthat's already passed torecord_transaction().2. Set
Utxo.is_instantlockedon InstantSend lock receiptThe
is_instantlockedfield exists onUtxoand is used in coin selection (is_spendable(),coin_selection.rs), but is never set totrue— it's initialized asfalseinUtxo::new()and no code path flips it.When
SyncEvent::InstantLockReceivedfires, UTXOs belonging to the locked transaction should be updated.3. Add
statustoWalletEvent::TransactionReceivedSo consumers know if a received transaction is mempool/confirmed/chain-locked without re-querying the wallet.
4. (Nice to have) Add
WalletEvent::TransactionStatusChangedFires on status transitions (Mempool → IS-locked → Confirmed → ChainLocked), enabling reactive UI updates.
Context
dash-evo-tool PR dashpay/dash-evo-tool#776 integrates the
MempoolManagerwithBloomFilterstrategy. With mempool tracking active, the wallet now sees unconfirmed transactions — but we cannot distinguish them from IS-locked transactions in the UI because the status information is discarded upstream.We're adding a
TransactionStatusenum on the evo-tool side and inferring what we can fromheight, but full lifecycle tracking requires these upstream changes.🤖 Co-authored by Claudius the Magnificent AI Agent