1 · Create — draft the unsigned PSBT
Assemble a PSBT from UTXOs you control. Every input carries its witness UTXO (amount + scriptPubKey) so any signer can verify the sighash. Amounts are whole grains (1 PRL = 108 grains) — exact BigInt math, no floats.
Inputs one per line: txid:vout:amountGrains:internalKeyHex + optional leaf ASM
Outputs one per line: prl1…:amountGrains or OP_RETURN:hexdata
2 · Inspect — read every byte before you sign
Paste any PSBT (this desk's or another wallet's). The inspector parses the BIP-174 maps, decodes each input's witness UTXO, internal key, tap leaves and partial signatures, and flags anything suspicious — before a key ever touches it.
3 · Sign — one input, one key, verified before it sticks
Sign a single input. The desk computes the exact BIP-341 sighash, signs with BIP-340 Schnorr, then re-verifies the signature before writing it into the PSBT. The private key lives in memory only for the signing call and is wiped immediately after.
4 · Combine — merge co-signer PSBTs
Two signers, two PSBTs, one transaction. Combining requires byte-identical unsigned transactions and refuses conflicting signatures — the merge is order-independent and idempotent.
5 · Finalize — verify everything, emit the transaction
Finalizing re-verifies every signature against its own
BIP-341 sighash, assembles the witnesses ([sig] for keypath,
[sig, script, control block] for scriptpath), and serializes the
complete transaction. Nothing is broadcast — broadcasting is your node's job.
6 · Methodology & honest limits
What this desk does
- Create — builds a BIP-174 PSBT: global unsigned tx, per-input witness UTXOs, Taproot internal keys, and single-leaf tap scripts with their control blocks. Amounts are exact BigInt grains (1 PRL = 108).
- Inspect — parses every BIP-174 map, decodes witness UTXOs, checks each leaf's control block against its internal key, and names every partial signature's sighash type. Read it before you sign it.
- Sign — computes the exact BIP-341 sighash (all 7 sighash types), signs BIP-340 Schnorr, and re-verifies before mutating the PSBT. Keypath accepts the internal key (desk applies the TapTweak) or an already-tweaked key; scriptpath requires the key to appear as a 32-byte push in a declared leaf.
- Combine — merges PSBT maps key-wise; requires byte-identical unsigned transactions; rejects conflicting signatures and duplicate keys.
- Finalize — re-verifies every signature against its own sighash, strips partial-sig metadata per BIP-174, and emits the witness transaction.
- Address rules — BIP-350 bech32m, HRP
prl, witness version 1, 32-byte program, canonical re-encode — same rules as the audited Names desk.
Crypto lineage
- No new cryptography. Every primitive is vendored from the audited
sign/src/crypto.jscore (pearlpurse lineage): SHA-256, tagged hashes, the TapTweak (tapTweak/tweakPrivKeypath), BIP-340 Schnorr, and bech32m. - The PSBT sighash construction is differentially pinned against the audited
keypathSigDigestEx— byte-identical digests for SIGHASH_DEFAULT and SIGHASH_SINGLE|ANYONECANPAY across inputs. The test suite re-runs that pinning. - PSBT serialization, the BIP-341 message layout, script assembly and witness building are
new code in
src/psbt-core.js— covered by 39 tests (158 assertions), including malformed-PSBT rejections, 1-bit tamper tests, and combine conflict rejection.