bitcoin-psbt

v2026.09.24

Partially Signed Bitcoin Transaction format: BIP174 (v0), BIP370 (v2), BIP371 (Taproot fields). Roles (Creator, Updater, Signer, Combiner, Finalizer, Extractor), required fields per input/output type, Taproot-specific fields (tap_key_sig, tap_script_sig, tap_leaf_script, tap_bip32_derivation), magic bytes, separators. USE WHEN: building/signing/coordinating PSBTs, debugging "why won't my hardware wallet sign", cross-vendor multisig flows.

GitHub
Install command
npx skhub add claude-dev-suite/bitcoin-psbt
Markdown
SKILL.md

PSBT (BIP174 / BIP370 / BIP371)

PSBT = a binary container for a transaction-in-progress, where one party constructs the skeleton, others contribute signatures, and a finalizer emits the broadcastable transaction.

Versions

  • v0 (BIP174) — original. Magic psbt\xff. Tx is fully serialized in PSBT_GLOBAL_UNSIGNED_TX.
  • v2 (BIP370) — version field, per-input/output amount fields. Allows incremental construction without re-encoding the whole tx. Required for some workflows (BOLT12, advanced taproot).
  • BIP371 adds Taproot-specific fields (orthogonal to version).

Roles

RoleResponsibility
CreatorBuilds initial PSBT skeleton (inputs, outputs, no sigs).
UpdaterAdds metadata: non_witness_utxo, witness_utxo, derivation paths, redeem/witness scripts, taptree info.
SignerReads PSBT, produces partial sigs for inputs it controls.
CombinerMerges multiple Signers' partial PSBTs into one.
FinalizerReplaces partial sigs with final_scriptSig / final_scriptWitness.
ExtractorPulls final tx from finalized PSBT for broadcast.

Tools: walletprocesspsbt, combinepsbt, finalizepsbt, decodepsbt, analyzepsbt (Bitcoin Core); hwi signtx (hardware wallet); Sparrow/Specter/Caravan for coordination.

Wire format (v0)

[5 bytes]  magic = b"psbt" + 0xff
[ globals section ]
[ for each input:  inputs section, terminated by 0x00 ]
[ for each output: outputs section, terminated by 0x00 ]

Each section is a series of <key, value> pairs:

[varint] key length
[1 byte] key type
[..]     key data
[varint] value length
[..]     value data

End of section = 0x00 byte (zero-length key).

Required input fields by output type being spent

Output typeRequired
Legacy P2PKH/P2SHnon_witness_utxo (full prev tx)
SegWit v0 (P2WPKH/P2WSH)witness_utxo (just the spent output) AND non_witness_utxo recommended (defends against fee-bumping attack on signing devices)
P2SH-wrapped SegWitboth, plus redeem_script
P2WSHwitness_script
Taproot key-pathwitness_utxo + taproot_internal_key + tap_bip32_derivation
Taproot script-pathabove + tap_leaf_script (script + control block) + tap_script_sig

Always include all spent prevouts for Taproot inputs — sighash commits to all of them (BIP341).

Key BIP174 fields (selected)

SectionTypeName
Global0x00PSBT_GLOBAL_UNSIGNED_TX
Global0x01PSBT_GLOBAL_XPUB
Global0xfbPSBT_GLOBAL_VERSION (v2 only)
Input0x00PSBT_IN_NON_WITNESS_UTXO
Input0x01PSBT_IN_WITNESS_UTXO
Input0x02PSBT_IN_PARTIAL_SIG
Input0x03PSBT_IN_SIGHASH_TYPE
Input0x04PSBT_IN_REDEEM_SCRIPT
Input0x05PSBT_IN_WITNESS_SCRIPT
Input0x06PSBT_IN_BIP32_DERIVATION
Input0x07PSBT_IN_FINAL_SCRIPTSIG
Input0x08PSBT_IN_FINAL_SCRIPTWITNESS
Input0x13PSBT_IN_TAP_KEY_SIG (BIP371)
Input0x14PSBT_IN_TAP_SCRIPT_SIG
Input0x15PSBT_IN_TAP_LEAF_SCRIPT
Input0x16PSBT_IN_TAP_BIP32_DERIVATION
Input0x17PSBT_IN_TAP_INTERNAL_KEY
Input0x18PSBT_IN_TAP_MERKLE_ROOT
Output0x00PSBT_OUT_REDEEM_SCRIPT
Output0x01PSBT_OUT_WITNESS_SCRIPT
Output0x02PSBT_OUT_BIP32_DERIVATION
Output0x05PSBT_OUT_TAP_INTERNAL_KEY
Output0x06PSBT_OUT_TAP_TREE
Output0x07PSBT_OUT_TAP_BIP32_DERIVATION

Proprietary fields use type 0xfc with key prefix.

Encoding helpers

PSBT can be encoded as:

  • Binary (canonical wire format).
  • Base64 (most common transport between wallets).
  • Hex (less common, larger).

A "PSBT object" with the right magic bytes round-trips losslessly.

Common bugs

  • Missing non_witness_utxo for SegWit inputs on hardware signers → device refuses to sign (post Coinkite/Trezor/Ledger fix for fee-bumping attack).
  • Wrong bip32_derivation paths → device cannot find the key.
  • Combining PSBTs from different versions (v0 ↔ v2) → format error.
  • Missing tap_internal_key for Taproot inputs → finalizer cannot reconstruct script-path / verify key-path.
  • Calling Finalizer before all required signers contributed → leaves partial sigs in place; tx will be invalid if extracted.

See also

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

MIT

Source path

skills/bitcoin/protocol/psbt

Default branch

main

Latest commit

9496306

Tree SHA

fe4e2f1