Skip to content

feat(wasm-utxo-cli): add psbt create/add-input/add-output/sign subcommands#311

Merged
OttoAllmendinger merged 5 commits into
masterfrom
otto/T1-3672-transparent-signing-and-psbt
Jul 6, 2026
Merged

feat(wasm-utxo-cli): add psbt create/add-input/add-output/sign subcommands#311
OttoAllmendinger merged 5 commits into
masterfrom
otto/T1-3672-transparent-signing-and-psbt

Conversation

@OttoAllmendinger

Copy link
Copy Markdown
Contributor

Summary

Stack for T1-3672: transparent single-key signing in wasm-utxo plus composable
PSBT build/sign CLI subcommands for regtest fixture generation (including Zcash).

Commits

  • feat(wasm-utxo): Network::requires_prev_tx_for_legacy_input predicate
  • refactor(wasm-utxo): move sighash_fork_id to Network, drop wrapper
  • feat(wasm-utxo): Zcash transparent signing + generalized single-key helpers (transparent_signing.rs)
  • feat(wasm-utxo-cli): address from-descriptor subcommand
  • feat(wasm-utxo-cli): psbt create / add-input / add-output / sign subcommands

Test plan

  • cargo check --lib in packages/wasm-utxo
  • cargo test --lib fixed_script_wallet::bitgo_psbt::sighash:: in packages/wasm-utxo
  • cargo build in packages/wasm-utxo/cli
  • Manual pipe: psbt create | add-input | add-output | sign for BTC and tzec

Refs: T1-3672

…cate

Rust-side source of truth for whether a legacy (non-segwit) transparent
input needs the full previous transaction (non_witness_utxo) or can rely
on witness_utxo alone. Mirrors requiresPrevTxForP2sh in
js/fixedScriptWallet/prevTx.ts (added in T1-3654 / PR #306), generalized
from P2SH to legacy inputs generally: ZIP-243 (Zcash) and BIP-143/FORKID
(BCH family) sighashes commit the input amount regardless of script
type, making non_witness_utxo cryptographically pointless for those
coins.

Refs: T1-3672
Move SIGHASH_FORKID lookup from fixed_script_wallet::get_sighash_fork_id
to Network::sighash_fork_id as the single source of truth. Inline call
sites in bitgo_psbt and drop the redundant wrapper and its re-export.

Refs: T1-3672
@linear-code

linear-code Bot commented Jul 6, 2026

Copy link
Copy Markdown

T1-3672

@OttoAllmendinger OttoAllmendinger force-pushed the otto/T1-3672-transparent-signing-and-psbt branch from 2098c55 to 888f876 Compare July 6, 2026 11:37
…ey signing helpers

Adds ZIP-243 transparent-input signing/finalization to WrapPsbt
(sign_zcash_with_prv, sign_zcash_all_with_ecpair, finalize_mut_zcash,
extract_zcash_transaction), and factors the core into shared non-wasm
helpers in a new src/transparent_signing.rs module: SingleKeySigner,
script_pubkey_from_descriptor, add_input_with_descriptor,
sign_with_privkey, sign_zcash_with_privkey,
finalize_and_encode_transaction, finalize_and_encode_zcash_transaction.
These are plain functions over miniscript::bitcoin::psbt::Psbt with no
wasm_bindgen surface, so they live outside src/wasm/ and are reusable
by any consumer (e.g. the wasm-utxo-cli crate), not just WrapPsbt.

script_pubkey_from_descriptor resolves a descriptor string that may
embed private keys (e.g. pkh(<privkey>)) via
Descriptor::parse_descriptor, for deriving an address directly from a
signing descriptor.

add_input_with_descriptor takes a definite descriptor string (not
hardcoded to pkh) and works for all networks: it uses the checked
PsbtExt::update_input_with_descriptor (BIP174-safe) when a
non_witness_utxo is given, or the unchecked
PsbtInputExt::update_with_descriptor_unchecked when omitted, which is
only safe for value-committing sighash networks (new
Network::requires_prev_tx_for_legacy_input predicate: Zcash/BCH-family)
where a lying witness_utxo can't misreport the spent amount.

sign_with_privkey/finalize_and_encode_transaction support all non-Zcash
sighash families via Network::sighash_fork_id: plain Psbt::sign/
finalize_mut_with_fork_id(None) for BTC-like networks,
sign_forkid/finalize_mut_with_fork_id(Some(id)) for the BCH family.

ZcashTransactionParts::from_extracted_transaction/::extract_from_psbt
live as associated functions on ZcashTransactionParts in
src/zcash/transaction.rs.

Refs: T1-3672
Print the address for a descriptor (WIF/hex/xpub-based), which may
embed a private key (e.g. pkh(<wif>)) via wasm-utxo's
script_pubkey_from_descriptor. General utility for deriving addresses
from descriptors on the command line, not tied to any particular coin
or script type.

Refs: T1-3672
…mands

Four composable subcommands under `psbt`, replacing the earlier
single-shot build-sign command: `psbt create`, `psbt add-input`,
`psbt add-output`, `psbt sign`. Each reads/writes a PSBT as hex via
stdin/stdout (or a file path), so they pipe together, e.g.:

  psbt create | psbt add-input - --network tzec --txid ... --descriptor pkh(<pubkey>) \
    | psbt add-output - --address ... --network tzec \
    | psbt sign - --network tzec --privkey ... --consensus-branch-id 0xc2d6d0b4

`add-input` and `sign` work for all networks, not just Zcash, using
the wasm-utxo library helpers added in the parent commit:

- `add-input` requires `--prev-tx` (a full previous transaction)
  unless `--network` is a value-committing network (Zcash/BCH-family)
  whose sighash already commits the input amount.
- `sign` dispatches the sighash algorithm on `--network`: plain,
  FORKID (BCH family), or Zcash ZIP-243. Manually verified end-to-end
  for all three sighash families.

This lets the indexer-utxo regtest fixture generator build+sign a
transparent Zcash transaction off-node for zebrad's sendrawtransaction.

Refs: T1-3672
@OttoAllmendinger OttoAllmendinger force-pushed the otto/T1-3672-transparent-signing-and-psbt branch from 888f876 to bbc43fa Compare July 6, 2026 11:46
@OttoAllmendinger OttoAllmendinger marked this pull request as ready for review July 6, 2026 12:02
@OttoAllmendinger OttoAllmendinger requested a review from a team as a code owner July 6, 2026 12:02
@OttoAllmendinger OttoAllmendinger merged commit 5b5297d into master Jul 6, 2026
13 checks passed
@OttoAllmendinger OttoAllmendinger deleted the otto/T1-3672-transparent-signing-and-psbt branch July 6, 2026 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants