Research/Bitcoin

PSBT Workflows for Multisig: Coordinating Multiple Signers Without Trust

Practical guide to using PSBTs for multisig transaction coordination across hardware wallets, watch-only nodes, and air-gapped signers.

bcSatoruJul 19, 2026

Spending from a multisig wallet means getting multiple independent parties to agree on the same transaction without ever sharing private keys. Before PSBTs (Partially Signed Bitcoin Transactions), this coordination was fragile: signers needed compatible software, identical transaction serialization, and often a live connection to each other. PSBTs, formalized in BIP 174, introduced a standard container format that any wallet can produce, any signer can process, and any coordinator can combine. The result is trustless multisig coordination across hardware wallets, air-gapped devices, and watch-only nodes.

What Problem Do PSBTs Solve?

A Bitcoin transaction requires valid signatures for every input before it can be broadcast. In a single-key setup, one wallet handles everything. In a multisig configuration, the keys live on separate devices, potentially in different physical locations. The challenge: how does each signer know exactly what they are signing, without trusting a coordinator to construct the transaction honestly?

PSBTs solve this by packaging the unsigned transaction together with all the metadata each signer needs: UTXO data for fee verification, redeem scripts for multisig validation, and BIP 32 derivation paths so hardware wallets can locate the correct keys. Each signer independently verifies the transaction on their trusted display, adds their signature, and returns the result. No signer needs to trust any other participant.

Anatomy of a PSBT

A PSBT is a binary container starting with the magic bytes 0x70736274FF (the ASCII string "psbt" followed by a separator byte). It contains three sections: a global map, one per-input map for each transaction input, and one per-output map for each output. Every section is a sequence of key-value pairs terminated by a null byte.

Global Map

In PSBT version 0, the global map contains the full unsigned transaction (with empty scriptSigs and witnesses). It may also include extended public keys ( xpubs) with their master fingerprints and derivation paths, allowing signers to identify which keys belong to them.

Per-Input Fields

Each input map carries the data signers need to verify what they are spending and to produce valid signatures.

FieldPurposeWhen Required
Non-Witness UTXOFull previous transaction, so signers can verify the TXID and amount being spentLegacy (non-SegWit) inputs
Witness UTXOJust the spent output (amount + scriptPubKey), sufficient for SegWit inputsSegWit inputs
Partial SignatureA DER-encoded ECDSA signature keyed by the signer's compressed public keyAdded by each signer
Redeem ScriptThe P2SH redeem script containing the multisig policyP2SH and P2SH-P2WSH multisig
Witness ScriptThe P2WSH witness script (the actual multisig program)P2WSH and P2SH-P2WSH multisig
BIP 32 DerivationMaps each public key to its master fingerprint and derivation pathWhen hardware wallets need to locate signing keys
Sighash TypeSpecifies which parts of the transaction are covered by the sighash flagWhen non-default sighash is needed

Per-Output Fields

Output maps include redeem scripts, witness scripts, and BIP 32 derivation data for change outputs. These let wallets verify that change is returning to an address they control, preventing a malicious coordinator from redirecting funds.

Why Witness UTXO matters for hardware wallets: Without the spent output's amount, a signing device cannot calculate the transaction fee. An attacker could craft a PSBT that overpays fees by millions of satoshis. BIP 174 requires either the full previous transaction (non-witness UTXO) or the witness UTXO so signers can independently verify the fee before approving.

The Six Roles in a PSBT Workflow

BIP 174 defines six distinct roles that can be performed by different software or devices. In practice, some roles are combined (a coordinator wallet often acts as Creator, Updater, Combiner, and Extractor), but the separation matters for security: the signing role is isolated on trusted hardware.

  1. Creator: constructs an empty PSBT with the unsigned transaction template (inputs, outputs, locktime)
  2. Updater: enriches the PSBT with UTXO data, redeem/witness scripts, and BIP 32 derivation paths for all cosigner keys
  3. Signer: examines each input, locates the matching private key, verifies the transaction on a trusted display, and adds a partial signature
  4. Combiner: merges multiple PSBTs for the same transaction into one, collecting all partial signatures
  5. Finalizer: when enough signatures exist, assembles the complete scriptSig and/or witness data and strips intermediate metadata
  6. Extractor: produces the fully serialized network transaction, ready for broadcast

Walkthrough: 2-of-3 Multisig with PSBTs

Consider a treasury setup with three signing devices: a Coldcard held by the CFO, a Foundation Passport stored in a safe deposit box, and a Trezor kept by an operations lead. A watch-only wallet running Sparrow on a networked laptop acts as the coordinator. Any two of three signers can authorize a spend.

Step 1: Wallet Setup

Each hardware wallet exports its extended public key (xpub) via USB, QR code, or SD card. The coordinator imports all three xpubs and constructs an output descriptor:

wsh(sortedmulti(2, [fingerprint_A/48h/0h/0h/2h]xpub_A/*, [fingerprint_B/48h/0h/0h/2h]xpub_B/*, [fingerprint_C/48h/0h/0h/2h]xpub_C/*))

The sortedmulti function (BIP 67) ensures deterministic key ordering so all participants derive identical addresses regardless of the order they import keys. The wsh() wrapper produces native P2WSH addresses, which have lower fees than P2SH-wrapped alternatives. The coordinator's wallet is watch-only: it has no private keys and cannot sign.

Step 2: Create the PSBT

When the organization needs to make a payment, the coordinator builds the transaction. Using bitcoin-cli:

bitcoin-cli -rpcwallet="treasury_watch" walletcreatefundedpsbt '[]' '[{"bc1q...destination": 0.5}]'

This command selects UTXOs, adds a change output, populates all input metadata (witness UTXOs, witness scripts, BIP 32 derivation paths for all three cosigner keys), and returns a base64-encoded PSBT. The coordinator saves this as a .psbt file.

Step 3: Distribute to Signers

The coordinator sends the unsigned PSBT to the CFO and the operations lead. Transport options depend on the signing device:

  • Coldcard: copy the .psbt file to a MicroSD card and physically hand it over
  • Trezor: connect via USB to Sparrow and sign directly
  • Keystone or SeedSigner: display as animated QR code for the device camera to scan

The signers do not need to communicate with each other. Each independently receives the same unsigned PSBT.

Step 4: Sign

Each signing device parses the PSBT, extracts the transaction details, and displays them on its trusted screen: destination address, amount, fee, and change output. The signer verifies these details match the intended payment, then approves. The device locates its private key using the BIP 32 derivation path embedded in the PSBT, produces a partial signature, and writes it into the PSBT's PSBT_IN_PARTIAL_SIG field keyed by the signer's compressed public key.

For a Coldcard using an SD card, the device writes a new file with -signed appended to the filename. The original unsigned file is not overwritten.

Step 5: Combine, Finalize, Broadcast

The coordinator collects both signed PSBTs and merges them:

bitcoin-cli combinepsbt '["psbt_from_cfo", "psbt_from_ops"]'

The Combiner merges all partial signatures into a single PSBT. The Finalizer then assembles the witness stack (the two signatures plus the witness script) and strips intermediate metadata:

bitcoin-cli finalizepsbt <combined_psbt>

If successful, this returns {"hex": "...", "complete": true}. The coordinator broadcasts the raw transaction with sendrawtransaction.

Sequential vs parallel signing: The workflow above uses parallel signing: both signers receive the original unsigned PSBT independently. Alternatively, signers can work sequentially: the CFO signs first and passes the partially signed PSBT to the operations lead, who adds the second signature. Sequential signing skips the combine step since the second signer's wallet appends its signature to the existing one. Both approaches produce identical final transactions.

PSBT Version 0 vs Version 2

BIP 370 introduced PSBT version 2 to address a fundamental limitation of v0: the unsigned transaction is locked at creation time. Once the Creator sets the inputs and outputs, no participant can modify them. This blocks interactive protocols like PayJoin and CoinJoin, where participants contribute inputs during construction.

AspectPSBT v0 (BIP 174)PSBT v2 (BIP 370)
Global transactionFull unsigned transaction stored in the global mapNo global transaction: data distributed across input/output maps
Input/output modificationFixed at creationModifiable until the Constructor clears the modifiable flags
New roleN/AConstructor: adds inputs/outputs before signing begins
Per-input fieldsUTXO data, scripts, derivations, partial signaturesSame, plus PREVIOUS_TXID, OUTPUT_INDEX, SEQUENCE, and locktime requirements
Per-output fieldsScripts and derivations onlySame, plus AMOUNT and SCRIPT (formerly in the global tx)
InteroperabilityUniversal: supported by all PSBT-aware softwareGrowing adoption: Coldcard, Ledger Bitcoin app, Sparrow, BDK
ConversionCannot convert to v2Can downconvert to v0 by reconstructing the unsigned tx

For standard multisig workflows, PSBT v0 remains the practical choice: it has universal support and the fixed transaction structure is not a limitation when all inputs and outputs are known upfront. Version 2 becomes necessary for interactive construction protocols and is required by BIP 375 for sending to silent payment addresses.

Taproot PSBTs and BIP 371

Taproot introduced Schnorr signatures and script trees, which required new PSBT fields defined in BIP 371. For key-path spends, signers produce a single 64-byte Schnorr signature stored in PSBT_IN_TAP_KEY_SIG. For script-path spends (used in Taproot-based multisig), each signer adds a PSBT_IN_TAP_SCRIPT_SIG entry keyed by their X-only public key and the relevant leaf hash. Additional fields carry the internal key, Merkle root, leaf scripts, and Taproot-specific BIP 32 derivation data.

Air-Gapped Signing Methods

Air-gapped signing eliminates all electronic communication between the signing device and any networked system. PSBTs are uniquely suited for air-gapped workflows because the format is self-contained: the signer receives everything needed to verify and sign without querying a node.

MicroSD Card

The coordinator writes the .psbt file to a FAT32 MicroSD card. The signer physically inserts the card into the hardware wallet, reviews the transaction on the device display, approves, and the device writes a signed .psbt file back to the card. The card is then returned to the coordinator. This method has no size limitations and works with complex transactions containing many inputs. Coldcard and Foundation Passport both support this workflow.

Animated QR Codes

For devices with cameras (SeedSigner, Keystone, Blockstream Jade), the PSBT is encoded as a sequence of animated QR frames. Two competing standards exist:

  • UR (Uniform Resources) by Blockchain Commons: uses fountain codes for error recovery, with the ur:psbt type tag. Frames can be captured in any order. Adopted by Sparrow, Keystone, Foundation Passport, and others
  • BBQr (Better Bitcoin QR) by Coinkite: uses Base32 encoding optimized for QR alphanumeric mode, with optional Zlib compression reducing payload by roughly 30%. Supports payloads up to 3.5 MB across 1,295 frames. Adopted by Coldcard Q

NFC

Near-field communication enables tap-to-sign workflows at a distance of under 4 cm. The unsigned PSBT is transferred on the first tap; the signed result returns on the second tap. NFC is practical for simple transactions (PSBTs under roughly 8 KB), but multisig transactions with multiple inputs may exceed this limit. Coldcard Mk5 and Q support NFC, though it is disabled by default.

PSBT Coordination Tools

Sparrow Wallet

Sparrow is a desktop Bitcoin wallet designed around descriptors and PSBTs. It serves as a full PSBT coordinator: creating transactions, exporting to hardware wallets via USB/QR/file, importing signed PSBTs, combining signatures, and broadcasting. Sparrow supports mixing hardware wallets from different manufacturers in a single multisig setup and provides a visual PSBT inspector showing all fields, signatures, and fee data. It connects to Bitcoin Core, Electrum servers, or public servers (with optional Tor).

Caravan

Caravan is an open-source, stateless multisig coordination tool originally built by Unchained Capital. It runs entirely in the browser with no backend: all transaction construction, PSBT creation, and signature combination happen client-side. Caravan supports Trezor, Ledger, Coldcard, and manual key import, with BCURv2 animated QR support for fully air-gapped signing. Because Caravan is stateless, users must externally back up their multisig configuration (xpubs, derivation paths, and the descriptor).

Bitcoin Core CLI

Bitcoin Core provides the full set of PSBT commands for scripting and automation. The key commands map directly to PSBT roles:

CommandPSBT RolesDescription
walletcreatefundedpsbtCreator + UpdaterSelects UTXOs, creates the PSBT, and populates all metadata
walletprocesspsbtUpdater + SignerAdds missing metadata and signs with available wallet keys
descriptorprocesspsbtUpdater + SignerSigns using provided descriptors without requiring a wallet (added in Bitcoin Core 25.0)
combinepsbtCombinerMerges multiple signed PSBTs for the same transaction
finalizepsbtFinalizer + ExtractorConstructs final witness data and returns the raw transaction
decodepsbtDiagnosticOutputs a human-readable JSON dump of all PSBT fields
analyzepsbtDiagnosticReports per-input status, estimated fees, and the next required role

Programmatic PSBT Libraries

Developers building multisig coordination software can choose from mature libraries across multiple languages.

  • bitcoinjs-lib (JavaScript/TypeScript): the Psbt class provides full lifecycle support including addInput, signInput, combine, finalizeAllInputs, and extractTransaction. It supports HD signing via signInputHD and Taproot via signTaprootInput
  • rust-bitcoin (Rust): the bitcoin::psbt module implements BIP 174, with a separate psbt-v2 crate for BIP 370. Integrates with rust-miniscript for policy-based spending
  • BDK (Bitcoin Dev Kit): a higher-level wallet library built on rust-bitcoin that handles coin selection, fee estimation, and descriptor-based key management automatically. Available in Rust with bindings for Swift, Kotlin/JVM, Python, and WASM
  • python-bitcointx: a Python library with a PartiallySignedTransaction class supporting PSBT creation and signing

For a comparison of wallet development frameworks, see the Bitcoin wallet SDK comparison.

Security Considerations

Fee Verification

The most critical security property of PSBTs is enabling signers to independently verify the transaction fee. Without UTXO data, a signer cannot calculate the difference between total input value and total output value. BIP 174 mandates that Updaters include either the full previous transaction (for legacy inputs) or the witness UTXO (for SegWit inputs) so signers can perform this check. Hardware wallets should reject PSBTs that lack this data.

Change Output Verification

A malicious coordinator could construct a PSBT where the change address is controlled by the attacker instead of the multisig quorum. The BIP 32 derivation paths in the output map let hardware wallets verify that change outputs belong to the same descriptor as the inputs. Signers should confirm on their device display that the change output is flagged as "internal" or "change."

Address Display Attacks

Hardware wallet attack vectors include compromised coordinator software that displays a different destination address than the one in the PSBT. Signers must always verify the destination address on the hardware wallet's own display, never on the coordinator's screen.

Defense in depth: PSBTs do not eliminate the need to verify transactions on trusted hardware. They ensure signers have the data to verify, but the human must still check the destination address, amount, and fee on the signing device's display before approving.

From Multisig PSBTs to Threshold Signatures

PSBT-based multisig coordination works, but it has inherent costs. Every input in a 2-of-3 multisig transaction carries two 72-byte DER signatures plus the witness script containing all three public keys. This consumes more block space than single-sig transactions, which translates directly to higher fees. The multisig structure is also visible on-chain: anyone analyzing the blockchain can identify multisig spends and infer the quorum policy.

FROST (Flexible Round-Optimized Schnorr Threshold signatures) takes a different approach. FROST threshold signatures allow a group of signers to collaboratively produce a single Schnorr signature that is indistinguishable from a regular single-key signature on-chain. The signing coordination still happens off-chain across multiple devices, but the result is a compact key-path spend that reveals nothing about the underlying threshold structure.

Spark uses FROST at its core: the user and the Spark operators collectively hold a threshold key, and transfers require collaborative signing without any party having complete key material. The coordination challenge is similar to PSBT multisig, but solved at the protocol layer rather than at the transaction format layer. For developers building on Spark, the Spark SDK handles threshold signing coordination automatically, without requiring manual PSBT construction.

When to Use PSBTs vs Alternatives

PSBTs are the right tool when you need on-chain multisig coordination with hardware wallet isolation. For other scenarios, alternatives may be more appropriate:

ScenarioBest ApproachWhy
Treasury cold storage (2-of-3, 3-of-5)PSBT multisigMaximum security with air-gapped hardware wallets, on-chain enforcement
Frequent payments with shared controlMuSig2 or FROSTLower fees, better privacy, single on-chain signature
Instant transfers with self-custodySparkOff-chain settlement with threshold security, no on-chain footprint per transfer
Collaborative transaction building (PayJoin, CoinJoin)PSBT v2Modifiable inputs/outputs allow interactive construction
Programmatic spending policiesMiniscript + PSBTPolicies expressed as descriptors, automated PSBT construction and signing

Getting Started

For teams setting up their first multisig workflow, start with Sparrow and two hardware wallets from different manufacturers. Create a 2-of-3 on testnet (or signet) first to practice the full cycle: wallet creation, PSBT export, signing on each device, combination, and broadcast. Graduate to mainnet only after the workflow feels routine and every team member can independently verify transactions on their device.

For developers integrating PSBT workflows into applications, the wallet SDK comparison covers library options across languages. BDK is the most batteries-included choice for Rust-based projects, while bitcoinjs-lib remains the standard for JavaScript/TypeScript.

For those exploring off-chain alternatives to on-chain multisig, Spark's documentation covers how FROST-based threshold signing achieves similar multi-party security without the on-chain overhead.

This article is for educational purposes only. It does not constitute financial or investment advice. Bitcoin and Layer 2 protocols involve technical and financial risk. Always do your own research and understand the tradeoffs before using any protocol.