upsertUTXO method

  1. @override
Future<void> upsertUTXO(
  1. String walletId,
  2. BitcoinUtxo utxo
)
override

Upsert (insert or update) a UTXO in the read model.

Used by projections to persist UTXO state changes.

Parameters:

  • walletId: Unique identifier for the wallet
  • utxo: UTXO to store

Implementation

@override
Future<void> upsertUTXO(String walletId, BitcoinUtxo utxo) async {
  _ensureInitialized();

  await _pool!.execute(
    Sql.named('''
      INSERT INTO bitcoin_utxos (
        wallet_id, txid, vout, utxo_key, satoshis, script_pub_key, address,
        block_height, confirmations, status, created_at, spent_at,
        spent_in_tx_id, script_type, is_spendable, category
      ) VALUES (
        @walletId, @txid, @vout, @utxoKey, @satoshis, @scriptPubKey, @address,
        @blockHeight, @confirmations, @status, @createdAt, @spentAt,
        @spentInTxId, @scriptType, @isSpendable, @category
      )
      ON CONFLICT (utxo_key) DO UPDATE SET
        satoshis = @satoshis,
        script_pub_key = @scriptPubKey,
        address = @address,
        block_height = @blockHeight,
        confirmations = @confirmations,
        status = @status,
        spent_at = @spentAt,
        spent_in_tx_id = @spentInTxId,
        is_spendable = @isSpendable
    '''),
    parameters: {
      'walletId': walletId,
      'txid': utxo.txid,
      'vout': utxo.vout,
      'utxoKey': '${utxo.txid}:${utxo.vout}',
      'satoshis': utxo.satoshis.toInt(),
      'scriptPubKey': utxo.scriptPubKey,
      'address': utxo.address,
      'blockHeight': utxo.blockHeight,
      'confirmations': utxo.confirmations ?? 0,
      'status': utxo.status.name,
      'createdAt': utxo.createdAt,
      'spentAt': null, // Set separately when spent
      'spentInTxId': null,
      'scriptType': 'p2pkh',
      'isSpendable': true,
      'category': 'funding',
    },
  );
}