rustywallet-psbt

Crates.iorustywallet-psbt
lib.rsrustywallet-psbt
version0.1.0
created_at2026-01-02 17:41:23.751441+00
updated_at2026-01-02 17:41:23.751441+00
descriptionPSBT (BIP174/BIP370) implementation for Bitcoin wallet development
homepage
repositoryhttps://github.com/rustywallet/rustywallet
max_upload_size
id2018935
size138,147
Septian Fariz Faturohman (nirvagold)

documentation

https://docs.rs/rustywallet-psbt

README

rustywallet-psbt

PSBT (Partially Signed Bitcoin Transaction) implementation for Bitcoin wallet development.

Crates.io Documentation License: MIT

Features

  • BIP174 (PSBT v0) - Full support for standard PSBT format
  • BIP370 (PSBT v2) - Support for improved PSBT format
  • All BIP174 Roles - Creator, Updater, Signer, Combiner, Finalizer, Extractor
  • Multiple Input Types - P2PKH, P2WPKH, P2SH, P2WSH, P2TR
  • Hardware Wallet Compatible - Interoperable with Ledger, Trezor, Coldcard

Installation

[dependencies]
rustywallet-psbt = "0.1"

Quick Start

Parse PSBT

use rustywallet_psbt::Psbt;

// From base64
let psbt = Psbt::from_base64("cHNidP8BAH...")?;

// From bytes
let psbt = Psbt::from_bytes(&bytes)?;

println!("Inputs: {}", psbt.input_count());
println!("Outputs: {}", psbt.output_count());

Create PSBT

use rustywallet_psbt::Psbt;

// Create from unsigned transaction
let unsigned_tx = vec![/* transaction bytes */];
let psbt = Psbt::from_unsigned_tx(unsigned_tx)?;

// Or create PSBT v2
let psbt = Psbt::new_v2(2, 2); // 2 inputs, 2 outputs

Update PSBT

use rustywallet_psbt::{Psbt, TxOut, KeySource};

let mut psbt = Psbt::from_base64("...")?;

// Add witness UTXO
psbt.update_input_with_utxo(0, TxOut {
    value: 100_000,
    script_pubkey: vec![0x00, 0x14, /* pubkey hash */],
})?;

// Add BIP32 derivation
psbt.update_input_with_bip32(
    0,
    pubkey.to_vec(),
    KeySource::new([0x01, 0x02, 0x03, 0x04], vec![84 | 0x80000000, 0, 0, 0, 0]),
)?;

Sign PSBT

use rustywallet_psbt::Psbt;
use rustywallet_keys::PrivateKey;

let mut psbt = Psbt::from_base64("...")?;
let private_key = PrivateKey::from_wif("...")?;

// Sign all inputs that match this key
let signed_count = psbt.sign(&private_key)?;
println!("Signed {} inputs", signed_count);

Combine PSBTs

use rustywallet_psbt::Psbt;

let psbt1 = Psbt::from_base64("...")?; // Signed by party 1
let psbt2 = Psbt::from_base64("...")?; // Signed by party 2

// Combine signatures
let combined = Psbt::combine(&[psbt1, psbt2])?;

Finalize and Extract

use rustywallet_psbt::Psbt;

let mut psbt = Psbt::from_base64("...")?;

// Finalize all inputs
psbt.finalize()?;

// Check if finalized
if psbt.is_finalized() {
    // Extract signed transaction
    let tx = psbt.extract_tx()?;
    println!("Transaction: {}", hex::encode(&tx));
}

BIP174 Roles

Role Description Methods
Creator Create PSBT from unsigned tx from_unsigned_tx(), new_v2()
Updater Add UTXO info, scripts, paths update_input_with_*()
Signer Add partial signatures sign(), sign_input()
Combiner Merge PSBTs combine(), merge()
Finalizer Build final scriptSig/witness finalize(), finalize_input()
Extractor Extract signed transaction extract_tx()

Supported Input Types

Type Description Support
P2PKH Legacy pay-to-pubkey-hash
P2WPKH Native SegWit
P2SH-P2WPKH Wrapped SegWit
P2SH Pay-to-script-hash
P2WSH Native SegWit script
P2SH-P2WSH Wrapped SegWit script
P2TR Taproot key path

Serialization

// To bytes
let bytes = psbt.to_bytes();

// To base64
let base64 = psbt.to_base64();

// Display (base64)
println!("{}", psbt);

// Parse from string
let psbt: Psbt = "cHNidP8BAH...".parse()?;

Error Handling

use rustywallet_psbt::{Psbt, PsbtError};

match Psbt::from_base64(input) {
    Ok(psbt) => { /* success */ }
    Err(PsbtError::InvalidMagic) => {
        eprintln!("Not a valid PSBT");
    }
    Err(PsbtError::Base64Error(e)) => {
        eprintln!("Invalid base64: {}", e);
    }
    Err(e) => {
        eprintln!("Error: {}", e);
    }
}

License

MIT License - see LICENSE for details.

Related Crates

Commit count: 0

cargo fmt