Skip to main content

kobe_primitives/
lib.rs

1//! Kobe core primitives — the foundation of every chain crate.
2//!
3//! This crate owns the type system shared by every `kobe-<chain>` crate:
4//! the [`Wallet`] entry point, the [`Derive`] / [`DeriveExt`] traits, the
5//! typed [`DerivedPublicKey`] enum, the unified [`DeriveError`], and the
6//! BIP-32 / SLIP-10 / Camouflage primitives that chain crates compose.
7//!
8//! # Module map
9//!
10//! ```text
11//!                        Wallet                (mnemonic + 64-byte BIP-39 seed)
12//!                    ┌─────┴─────┐
13//!    derive_secp256k1│           │  derive_ed25519
14//!                    ▼           ▼
15//!    bip32::DerivedSecp256k1Key     slip10::DerivedEd25519Key
16//!                    │           │
17//!    used by BTC / EVM /         │  used by Solana / Sui /
18//!    Cosmos / Tron / Spark /     │  Aptos / TON /
19//!    Fil / XRPL / Arweave /      │  Casper (ed25519)
20//!    Nostr / Casper (secp)       │
21//!                    └─────┬─────┘
22//!                          ▼
23//!                   DerivedAccount  ─◄── every chain wraps this
24//!                   (path + sk + pk + address)
25//! ```
26//!
27//! [`camouflage`] is an orthogonal utility (entropy-layer XOR encryption
28//! that turns one BIP-39 mnemonic into another) gated behind its own feature.
29//!
30//! # Zeroize policy
31//!
32//! Every sensitive byte string is wiped when dropped:
33//!
34//! - [`Wallet`] — zeroizes the mnemonic and the 64-byte seed.
35//! - [`DerivedAccount::private_key_bytes`] / [`private_key_hex`][`DerivedAccount::private_key_hex`]
36//!   — hand out `&Zeroizing<…>` or `Zeroizing<…>` copies.
37//! - [`bip32::DerivedSecp256k1Key`] / [`slip10::DerivedEd25519Key`] —
38//!   zeroize their signing key material, chain code, and every byte view.
39//! - [`camouflage::encrypt`] / [`camouflage::decrypt`] — return `Zeroizing<String>`.
40//!
41//! Public keys and on-chain addresses are **not** zeroized: by design they
42//! carry no secret material.
43//!
44//! # `no_std` surface
45//!
46//! | Feature           | Needs `alloc` | Purpose                                |
47//! | ----------------- | :-----------: | -------------------------------------- |
48//! | `std`  (default)  |       ✔       | `std::error::Error`, OS RNG            |
49//! | `alloc`           |       ✔       | [`Wallet`], [`DerivedAccount`], [`mnemonic`] |
50//! | `bip32`           |       ✔       | [`bip32::DerivedSecp256k1Key`]         |
51//! | `slip10`          |       ✔       | [`slip10::DerivedEd25519Key`]          |
52//! | `encoding`        |       ✔       | [`encoding`] (`hash160` / `Base58Check`) |
53//! | `camouflage`      |       ✔       | [`camouflage`] (PBKDF2 XOR helpers)    |
54//! | `raw-seed`        |       ✔\*     | [`Wallet::seed`] escape hatch (off by default) |
55//! | `rand` / `rand_core` |     ✔       | [`Wallet::generate`]                   |
56//! | `test-vectors`    |       ✗       | Re-export of canonical BIP-39 fixtures |
57//!
58//! \*`raw-seed` needs `alloc` (via the `Wallet` type) but adds no extra crates.
59//!
60//! Only [`DeriveError`] and [`test_vectors`] compile in pure `no_std`
61//! without `alloc`. Everything else requires at least `alloc`.
62//!
63//! # Quick tour
64//!
65//! ```no_run
66//! use kobe_primitives::Wallet;
67//!
68//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
69//! // 1. Build a wallet from a BIP-39 mnemonic:
70//! let wallet = Wallet::from_mnemonic(
71//!     "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
72//!     None,
73//! )?;
74//!
75//! // 2. Derive secp256k1 / Ed25519 keys at BIP-32 / SLIP-10 paths
76//! //    (enable the `bip32` / `slip10` features):
77//! # #[cfg(feature = "bip32")]
78//! assert_eq!(wallet.derive_secp256k1("m/44'/60'/0'/0/0")?.compressed_pubkey().len(), 33);
79//! # #[cfg(feature = "slip10")]
80//! assert_eq!(wallet.derive_ed25519("m/44'/501'/0'/0'")?.public_key_bytes().len(), 32);
81//! # Ok(())
82//! # }
83//! ```
84//!
85//! For chain-specific derivation (Bitcoin addresses, Ethereum checksummed
86//! addresses, Solana keypairs, etc.), reach for the matching chain crate
87//! (`kobe-btc`, `kobe-evm`, `kobe-svm`, …) via the [`kobe`] umbrella crate.
88//!
89//! [`kobe`]: https://docs.rs/kobe
90
91#![cfg_attr(not(feature = "std"), no_std)]
92// `proptest` is a workspace dev-dependency used only by the integration
93// tests under `tests/`. Library-test compilation triggers rustc's
94// `unused_crate_dependencies` lint; suppress it for test builds only so
95// production compilation still enforces the lint.
96#![cfg_attr(
97    test,
98    allow(
99        unused_crate_dependencies,
100        reason = "proptest is only referenced by the tests/ integration binary"
101    )
102)]
103
104#[cfg(feature = "alloc")]
105extern crate alloc;
106
107#[cfg(feature = "alloc")]
108mod derive;
109mod error;
110#[cfg(feature = "alloc")]
111mod style;
112#[cfg(feature = "alloc")]
113mod wallet;
114
115#[cfg(feature = "bip32")]
116pub mod bip32;
117#[cfg(feature = "camouflage")]
118pub mod camouflage;
119#[cfg(feature = "encoding")]
120pub mod encoding;
121#[cfg(feature = "alloc")]
122pub mod mnemonic;
123#[cfg(feature = "slip10")]
124pub mod slip10;
125
126pub use bip39::Language;
127#[cfg(feature = "rand_core")]
128pub use bip39::rand_core;
129#[cfg(feature = "alloc")]
130pub use derive::{
131    Derive, DeriveExt, DerivedAccount, DerivedPublicKey, PublicKeyKind, derive_range,
132};
133pub use error::DeriveError;
134#[cfg(feature = "alloc")]
135pub use style::{DerivationStyle, ParseDerivationStyleError};
136#[cfg(feature = "alloc")]
137pub use wallet::Wallet;
138
139/// Convenient Result alias.
140pub type Result<T> = core::result::Result<T, DeriveError>;
141
142/// Well-known BIP-39 / SLIP-10 test vectors, exposed for downstream test suites.
143///
144/// Gated on the `test-vectors` feature so they do **not** ship with the
145/// default binary/`lib` build. The module contains only `&'static str`
146/// constants and is available in `no_std + no_alloc` environments.
147#[cfg(feature = "test-vectors")]
148pub mod test_vectors {
149    /// All-zero 128-bit entropy — yields the canonical BIP-39 test mnemonic
150    /// (`"abandon abandon … about"`). Cross-verified against the BIP-39
151    /// reference implementations and `iancoleman.io/bip39`.
152    pub const MNEMONIC_ABANDON: &str = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
153
154    /// 64-byte BIP-39 seed derived from [`MNEMONIC_ABANDON`] with an empty
155    /// passphrase, lowercase hex.
156    pub const SEED_HEX_ABANDON: &str = "5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4";
157}