btc_psbt library

Classes

BtcPsbtConstants
Numeric constants ported from dynamic-js-sdk's packages/bitcoin/src/ constants.ts. MUST stay identical to that file, and to this same file's ports in kotlin-btc/swift-btc/csharp-btc — a drifted vSize or dust limit silently produces a different fee than the JS SDK computes for the exact same UTXOs, not something either language's own tests would catch alone.

Enums

BtcFeePriority
Send priority, mapped onto an esplora confirmationTarget (see BtcFeePlan.feeFor's doc) — NOT mempool.space's fastestFee/ halfHourFee/economyFee tiers, which the real SDK reads but this SDK's actual API host (blockstream.info) doesn't expose.

Functions

buildUnsignedPsbt({required String accountAddress, required String recipientAddress, required int amountInSatoshis, required String publicKeyHex, required BtcFeePriority priority, required bool isTestnet, required List<BtcUtxo> allUtxos, required List<BtcFeeEstimate> feeEstimates}) → String
Builds an unsigned PSBT (base64) sending amountInSatoshis to recipientAddress from accountAddress — ports buildPsbt.ts's assembly step (the fetch+selection+fee steps above are its utils). publicKeyHex is accountAddress's own pubkey (from VerifiedCredential. walletAdditionalAddresses — see that field's doc), needed to build the P2WPKH witness script each input's witnessUtxo carries. Callers own fetching allUtxos/feeEstimates (via the injected BtcService) — this function is pure. isTestnet selects which bech32 HRP ('tb' vs 'bc') the recipient/change addresses are validated against — the Dart equivalent of the Kotlin/JS port's chainHash/network parameter.
confirmationTargetFor(BtcFeePriority priority) → int
HIGH maps to a 2-block confirmation target, MEDIUM to 6, LOW to 24 — the only part of fee estimation that stays here, because the enum is a Dart enum and the IR has none. Everything the target is then USED for lives in BtcFeePlan (generated from packages/spec/src/btc.fee-rules.ts).
feePlan(List<BtcFeeEstimate> feeEstimates, BtcFeePriority priority, int numInputs, int amountInSatoshis, int selectedTotalValue) → BtcFeePlan
The plan the generated fee arithmetic runs on.
finalizeAndExtract(String signedPsbtBase64, String publicKeyHex) → String
Finalizes a SIGNED (but not yet finalized) PSBT — after the MPC ceremony (WalletSigner.signTransaction) attaches a partial signature per input, this reads each input's own PSBT_IN_PARTIAL_SIG entry for publicKeyHex (written by the server) and builds the P2WPKH witness stack signature, pubkey by hand, exactly mirroring kotlin-btc's finalizeAndExtract (there: reading bitcoin-kmp's own parsed partialSigs map instead of hand-parsing PSBT bytes). Returns the finalized, broadcastable raw tx hex.
hash160(Uint8List data) → Uint8List
HASH160 = RIPEMD160(SHA256(data)) — the digest a P2WPKH scriptPubKey/ witness program is built from.
selectUtxosLargestFirst(List<BtcUtxo> utxos, int targetAmount) → List<BtcUtxo>
Ports selectUTXOsLargestFirst.ts: sort by value descending, accumulate until targetAmount is covered.
utxoTotal(List<BtcUtxo> utxos) → int
validateAndSelectUtxos(List<BtcUtxo> allUtxos, int amountInSatoshis, int feeEstimate, int selectedTotal, List<BtcUtxo> selectedUtxos) → List<BtcUtxo>
Ports validateAndSelectUTXOs.ts: if the largest-first selection already covers amount+fee, keep it; otherwise widen to ALL UTXOs if that's enough, else throw. Deliberately never partially widens beyond "everything" — matches the JS SDK's own fallback exactly.