Skip to content
gmikeskaPublic

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

EmVault

EmVault

Wrapper crate for the EmVault multi-signature custody architecture.

See the CHANGELOG for release notes.

It provides a unified, backend-agnostic foundation for building secure m-of-n federations that can mix consumer hardware wallets (Trezor, Ledger, etc. — any signer that can export a BIP-48 XPUB and sign a P2WSH sortedmulti or Taproot multi_a PSBT) with HSMs (via PKCS#11) in the same federation. EmVault handles descriptor construction, heterogeneous signing coordination, federation mutation, efficient multi-account migrations, and recovery templates — while staying a pure library with no runtime or network ownership.

It also carries the handful of framework-agnostic utilities that every app needs but that don't belong in emvault-core (env-var + hex helpers).

📦 Demo Implementations

Want to see emvault wired into a real application? Two reference web apps exercise the library end-to-end and are the fastest way to learn the API:

  • test-app-xpub — self-custody, multi-party signing. Users bring their own hardware wallet, onboard an XPUB, and co-sign m-of-n P2WSH or Taproot transactions through a proposal lifecycle.

  • test-app-pkcs11 — custodial HSM-backed wallets. A federation of HSMs signs every spend server-side, across both Bitcoin and Elements/Liquid.

Each repo ships a FEATURES.md that maps every capability to the source symbol that implements it. Point your AI coding agent at a demo repo and its FEATURES.md for a complete implementation guide to the architecture — it has everything an agent needs to understand the full feature surface, data flow, and where each piece lives in the code.

The library family

Crate Role Repository
emvault-core Backend-agnostic core: Signer trait, Federation, descriptor builder, PSBT pipeline, migration, recovery, snapshots, roster, the shared wallet view types. https://github.com/gmikeska/emvault-core
emvault-xpub XPUB signer backend for consumer hardware wallets (Trezor, Jade, Ledger, Coldcard, Passport). https://github.com/gmikeska/emvault-xpub
emvault-pkcs11 PKCS#11 / HSM signer backend. https://github.com/gmikeska/emvault-pkcs11
emvault-elements Elements/Liquid support: confidential descriptors, PSET pipeline, client-side wollet, daemon RPC. https://github.com/gmikeska/emvault-elements
emvault-dev-signer Dev/CI HsmBackend that pairs with libemvault_dev_hsm. https://github.com/gmikeska/emvault-dev-signer
emvault-esplora Nodeless Esplora + Waterfalls chain backend (sync/broadcast, no local node). Behind the esplora feature; re-exported as emvault::core::esplora. https://github.com/gmikeska/emvault-esplora
emvault-electrum Descriptor-private electrs/Electrum chain backend (sync/broadcast + a scripthash watch layer). Behind the electrum feature; re-exported as emvault::core::electrum. https://github.com/gmikeska/emvault-electrum
libemvault_dev_hsm Software-only PKCS#11 shared library for dev/CI — see HSM Integration for how HSMs connect to EmVault. https://github.com/gmikeska/libemvault_dev_hsm

Why namespaced modules

emvault-core and emvault-elements both expose descriptor, error, network, and federated_wallet modules and overlapping item names (to_multipath_string, NetworkType vs ElementsNetwork, KeyMode vs CtKeyMode). A flat pub use ::* of every backend would collide, so each crate keeps its own namespace here, and the prelude gathers the high-frequency, unambiguous types for the common case.

Namespace Always on? Backed by
emvault::core yes emvault-core
emvault::config yes this crate (env-var + hex helpers)
emvault::xpub xpub feature emvault-xpub
emvault::pkcs11 pkcs11 feature emvault-pkcs11
emvault::elements elements feature emvault-elements
emvault::dev_signer dev-signer feature emvault-dev-signer
emvault::prelude yes curated re-exports (feature-gated entries)

Feature gates

Backends are optional dependencies behind features so a build pulls in exactly what it uses and nothing more (a Bitcoin-only app must not compile the HSM/Elements dependency stack):

Feature Effect
xpub Consumer hardware-wallet signer (emvault::xpub).
pkcs11 HSM-backed signer (emvault::pkcs11).
elements Elements/Liquid support (emvault::elements); turns on emvault-core/elements and forwards the Elements feature into pkcs11 and xpub only if that backend is also enabled (weak ?/ dep), so both HSM and Liquid-capable xpub signers advertise Liquid.
dev-signer Dev/CI HSM helper (emvault::dev_signer); implies pkcs11.
esplora Nodeless Esplora + Waterfalls chain backend, re-exported as emvault::core::esplora (forwards emvault-core/esplora → the emvault-esplora crate).
electrum Descriptor-private electrs/Electrum chain backend (sync/broadcast + scripthash watch layer), re-exported as emvault::core::electrum (forwards emvault-core/electrum → the emvault-electrum crate).
elements-electrum Nodeless Elements/Liquid sync over Electrum (emvault::elements::nodeless); implies elements and turns on emvault-elements/electrum.
elements-esplora Nodeless Elements/Liquid sync over Esplora + Waterfalls (emvault::elements::nodeless); implies elements and turns on emvault-elements/esplora.
test-utils Exposes test scaffolding (MockSigner, fixtures, the Elements testkit) to downstream test suites.

emvault::core and emvault::config are always available.

Usage

# Bitcoin-only consumer hardware wallets:
emvault = { version = "0.10", features = ["xpub"] }

# HSM federation with Elements + dev helpers:
emvault = { version = "0.10", features = ["pkcs11", "elements", "dev-signer"] }

# Custodial HSM wallets synced over a private Electrum server:
emvault = { version = "0.10", features = ["pkcs11", "electrum"] }

Prelude

One import for the types most consumers touch (backend-specific entries are feature-gated to match the enabled namespaces):

use emvault::prelude::*;
// Federation, DescriptorBuilder, build_federation, BuiltFederation,
// SigningCoordinator, UnsignedPsbt, FinalizedPsbt, NetworkType, …
// + ExternalSigner (xpub), Pkcs11Signer (pkcs11), ElementsWollet (elements)

emvault::config

Framework-agnostic helpers shared by every consuming app — always available, no backend feature needed:

use emvault::config::{require, optional, hex_decode, hex_encode, ConfigError};

let secret = hex_decode(&require("APP_SESSION_SECRET")?)?;
let manifest = optional("TREZOR_MANIFEST_EMAIL");
# Ok::<(), emvault::config::ConfigError>(())

Build and test

cargo build                       # core + config only
cargo build --all-features        # every backend
cargo test --all-features
cargo clippy --all-targets --all-features -- -D warnings -W clippy::pedantic
cargo doc --no-deps --all-features

License

MIT OR Apache-2.0.

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages