Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
bitcoin-core-miniscript-ffi
FFI bindings to Bitcoin Core's miniscript and descriptor implementation.
This crate provides direct access to Bitcoin Core's C++ miniscript parser, analyzer, and descriptor system through safe Rust bindings. It enables cross-verification between Bitcoin Core and other miniscript implementations (like rust-miniscript), ensuring consensus-critical code behaves identically across implementations.
Why This Crate?
- Reference Implementation: Bitcoin Core's miniscript is the canonical implementation used by the Bitcoin network
- Cross-Verification: Validate that your miniscript implementation matches Bitcoin Core's behavior exactly
- Production Tested: Built on code that secures billions of dollars in Bitcoin
- Full Feature Parity: Supports both P2WSH (SegWit v0) and Tapscript (SegWit v1) contexts
- Descriptor Support: Full Bitcoin Core descriptor parsing with BIP32 key derivation
- Type Safety: Safe Rust wrapper with proper memory management and error handling
Features
Miniscript
- Parse miniscript expressions from strings
- Validate miniscript type correctness
- Check sanity constraints (no duplicate keys, no timelock mixing, resource limits)
- Extract type properties (B, V, K, W modifiers and more)
- Calculate maximum witness satisfaction size
- Convert miniscript back to canonical string representation
- Satisfy miniscripts with custom satisfiers (signatures, hash preimages, timelocks)
- Thread-safe:
Send + Syncimplementation
Descriptors
- Parse all standard descriptor types:
pk(),pkh(),wpkh(),sh(),wsh(),tr() - Full BIP32 extended key support (xpub/tpub derivation)
- Multi-signature descriptors:
multi(),sortedmulti() - Miniscript expressions within descriptors
- Address generation for all networks (mainnet, testnet, signet, regtest)
- Public key extraction at any derivation index
- Script expansion and size calculation
Installation
Add to your Cargo.toml:
[]
= "0.3"
Build Requirements
This crate requires:
- Rust 1.85+ (2024 edition)
- CMake 3.16+
- C++20 compatible compiler (GCC 10+, Clang 10+, or MSVC 2019+)
- Boost 1.73+ (headers only)
- Bitcoin Core source code (automatically included as a git submodule)
Linux (Debian/Ubuntu)
macOS
Windows
# Using vcpkg
vcpkg install boost:x64-windows
Building from Source
# Clone with submodules (includes Bitcoin Core source)
# Build
# Run tests
If you cloned without --recursive:
Architecture
┌────────────────────────────────────────────────────────────────┐
│ Rust Application │
├────────────────────────────────────────────────────────────────┤
│ src/lib.rs │ src/descriptor.rs │
│ ┌─────────────────┐ │ ┌────────────────────────────────────┐ │
│ │ Miniscript │ │ │ Descriptor │ │
│ │ - from_str() │ │ │ - parse() │ │
│ │ - is_valid() │ │ │ - expand() │ │
│ │ - is_sane() │ │ │ - get_address() │ │
│ │ - satisfy() │ │ │ - get_pubkeys() │ │
│ │ - to_script() │ │ │ - is_range() │ │
│ └────────┬────────┘ │ └──────┬─────────────────────────────┘ │
├───────────┼──────────┴─────────┼───────────────────────────────┤
│ │ FFI Boundary │ │
│ │ (bindgen) │ │
├───────────┼────────────────────┼───────────────────────────────┤
│ cpp/miniscript_wrapper.h/.cpp │ cpp/descriptor_wrapper.h/.cpp │
│ ┌───────────────────────────────────┴───────────────────────┐ │
│ │ C Wrapper Layer │ │
│ │ - Opaque handles (MiniscriptNode*, DescriptorNode*) │ │
│ │ - C-compatible types and callbacks │ │
│ │ - Memory management (malloc/free) │ │
│ └───────────────────────────────────────────────────────────┘ │
├────────────────────────────────────────────────────────────────┤
│ Bitcoin Core C++ (vendor/bitcoin) │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ script/miniscript.h │ script/descriptor.h │ │
│ │ script/script.h │ script/signingprovider.h │ │
│ │ key.h, pubkey.h │ key_io.h │ │
│ └───────────────────────────────────────────────────────────┘ │
├────────────────────────────────────────────────────────────────┤
│ secp256k1 │
└────────────────────────────────────────────────────────────────┘
Safety
This crate provides safe Rust wrappers around unsafe FFI calls to Bitcoin Core's C++ implementation. The unsafe code is necessary for FFI interop but is carefully encapsulated.
Safety Guarantees
- Memory Safety: All C-allocated memory is properly freed via RAII (
Dropimpl) - Null Safety: All pointer dereferences are guarded by null checks
- Lifetime Safety: Rust structs own their C++ objects and ensure proper lifetimes
- Thread Safety:
MiniscriptandDescriptorimplementSendandSync - No Undefined Behavior: All unsafe blocks have documented invariants
FFI Design
The FFI layer uses:
- Opaque handles (
MiniscriptNode*,DescriptorNode*) for C++ objects - C-compatible result types with error messages
- Callback trampolines for the Satisfier trait
- Proper memory ownership with explicit free functions
Quick Start
Miniscript Parsing
use ;
Descriptor Parsing
use ;
Satisfying Miniscripts
use ;
API Reference
Miniscript
The main type representing a parsed miniscript expression.
Descriptor
Bitcoin Core descriptor with full key derivation support.
Context
Script context for miniscript parsing.
Network
Network type for address generation.
Type Properties
The type string returned by get_type() contains single-character flags:
| Flag | Meaning |
|---|---|
B |
Base expression (consumes nothing, produces nonzero) |
V |
Verify expression (consumes nothing, produces nothing, fails if unsatisfied) |
K |
Key expression (consumes nothing, produces a public key) |
W |
Wrapped expression (consumes one stack element) |
z |
Zero-arg property (consumes no stack elements) |
o |
One-arg property (consumes exactly one stack element) |
n |
Nonzero property (never produces zero) |
d |
Dissatisfiable property (has a dissatisfaction) |
u |
Unit property (on satisfaction, puts exactly 1 on stack) |
e |
Expression property (can be used as an expression) |
f |
Forced property (always requires a signature) |
s |
Safe property (cannot be malleated) |
m |
Nonmalleable property (satisfaction is unique) |
x |
Expensive verify property |
k |
Timelock property (contains a timelock) |
Use Cases
Cross-Verification Testing
use ;
Wallet Development
use ;
Taproot Script Analysis
use ;
Thread Safety
Miniscript and Descriptor implement Send and Sync, making them safe to use across threads:
use ;
use Arc;
use thread;
let ms = new;
let handles: = .map.collect;
for h in handles
Performance
The library is optimized for production use:
- Zero-copy string handling where possible
- Minimal allocations in hot paths
- Static linking eliminates runtime overhead
- Release builds use
-O3optimization
Comparison with rust-miniscript
| Feature | bitcoin-core-miniscript-ffi | rust-miniscript |
|---|---|---|
| Implementation | Bitcoin Core C++ | Pure Rust |
| Consensus compatibility | Reference | Aims to match |
| Dependencies | Bitcoin Core, Boost | Pure Rust |
| Build complexity | Higher | Lower |
| Use case | Cross-verification, reference | Production wallets |
Recommendation: Use this crate for testing and verification. Use rust-miniscript for production applications, but verify critical paths against this crate.
Test Coverage
The library includes comprehensive tests covering:
- Validity tests: Type checking, sanity checks, resource limits
- Descriptor tests: All descriptor types, BIP32 derivation, address generation
- Satisfaction tests: Witness construction, hash preimages, timelocks
- Tapscript tests: x-only pubkeys, multi_a, no ops limit
- Edge cases: Invalid inputs, resource exhaustion, error handling
Run tests with:
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Development Setup
# Clone with submodules
# Build in debug mode
# Run all tests
# Run clippy
# Build documentation
License
This project is licensed under the MIT License - see the LICENSE file for details.
Bitcoin Core's miniscript implementation is also MIT licensed.
Acknowledgments
- The Bitcoin Core developers for the reference miniscript implementation
- Pieter Wuille for creating miniscript
- The rust-bitcoin community
Related Projects
- rust-miniscript - Pure Rust miniscript implementation
- Bitcoin Core - The reference Bitcoin implementation
- miniscript.fun - Interactive miniscript playground