Note: This is an experimental crate exploring a descriptor-based implementation of BIP-322 within the Bitcoin Dev Kit (BDK) ecosystem.
A Rust library implementing the BIP‑322: Generic Signed Message Format for Bitcoin, built on top of the Bitcoin Dev Kit (BDK) ecosystem.
bdk-bip322 enables cryptographic proof of control over Bitcoin addresses and
funds without moving coins or broadcasting transactions, while securely
committing to arbitrary messages.
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
BIP-322 defines a standardized, script-agnostic mechanism for signing and
verifying messages with Bitcoin addresses. Unlike legacy signmessage,
BIP-322 works across modern script types (SegWit, Taproot) and enables advanced use cases such as proof-of-funds.
This library provides a descriptor-based, wallet-native implementation of
BIP-322, designed for seamless integration with bdk_wallet.
- Proving ownership of Bitcoin addresses
- Cryptographic proof of reserves or funds
- User authentication in Bitcoin-based applications
- Verifying control of addresses for support or dispute resolution
- Hardware-wallet compatible message signing via PSBTs
Designed to integrate with the Bitcoin Dev Kit ecosystem:
- bdk‑wallet — descriptor-based wallets, key management, and persistence.
- PSBT-based workflows — compatible with hardware and air-gapped signers No private keys or WIFs are passed directly to this library.
This crate supports Rust 1.85.0 or newer across all feature combinations.
- Legacy: Original P2PKH
signmessage/verifymessagecompatibility - Simple: SegWit‑only witness stack format
- Full: Complete PSBT/transaction‑based format (any script, including Taproot)
- FullProofOfFunds: Extends Full format with additional UTXO inputs to prove fund ownership.
use bdk_wallet::{Wallet, KeychainKind};
use bdk_bip322::{BIP322, SignatureFormat};
// `wallet` is already created and synced
let address = wallet.peek_address(KeychainKind::External, 0).address;
let proof = wallet.sign_message(
"Hello Bitcoin",
SignatureFormat::Simple,
&address,
None,
)?;let result = wallet.verify_message(
&proof,
"Hello Bitcoin",
SignatureFormat::Simple,
&address,
)?;
assert!(result.valid);Found a bug, have an issue or a feature request? Feel free to open an issue on GitHub.