selectAndLockUtxos
suspend fun selectAndLockUtxos(address: String, tokenType: String, requiredAmount: BigInteger): UtxoSelector.SelectionResult
Select and lock UTXOs for transaction (atomic operation).
Critical: Prevents Double-Spend Race Condition
This method performs selection and locking in a SINGLE database transaction:
SELECT available UTXOs (sorted by value, smallest first)
Perform coin selection (smallest-first algorithm)
UPDATE selected UTXOs to PENDING state
Atomicity: Room's @Transaction ensures this is a single SQLite transaction. No other thread can select the same UTXOs between steps 1-3.
Why Atomic?
// ❌ WITHOUT @Transaction (RACE CONDITION):
Thread A: SELECT utxos WHERE state = AVAILABLE → [utxo1, utxo2]
Thread B: SELECT utxos WHERE state = AVAILABLE → [utxo1, utxo2] // SAME UTXOs!
Thread A: UPDATE utxos SET state = PENDING
Thread B: UPDATE utxos SET state = PENDING
Result: DOUBLE-SPEND! Both threads use same UTXOs
// ✅ WITH @Transaction (SAFE):
Thread A: [SELECT + UPDATE in one transaction] → LOCKS [utxo1, utxo2]
Thread B: [waits for Thread A's transaction to complete]
Thread B: SELECT utxos WHERE state = AVAILABLE → [utxo3, utxo4] // Different UTXOs!
Result: SAFE! Each thread gets different UTXOsContent copied to clipboard
Uses the smallest-first coin selection and state management strategy standard to the Midnight wallet model.
Usage in Transaction Builder:
// Lock UTXOs for transaction
val result = utxoManager.selectAndLockUtxos(
address = senderAddress,
tokenType = "NIGHT",
requiredAmount = BigInteger("100000000")
)
when (result) {
is SelectionResult.Success -> {
// Build transaction with result.selectedUtxos
// Create change output with result.change (if 0)
}
is SelectionResult.InsufficientFunds -> {
// Show error to user
}
}
// If transaction fails, unlock UTXOs:
utxoManager.unlockUtxos(result.selectedUtxos.map { it.id })Content copied to clipboard
Return
SelectionResult (Success with locked UTXOs, or InsufficientFunds)
Parameters
address
Owner address
tokenType
Token type to select
requiredAmount
Amount needed (in smallest units)