Skip to main content

smplx_sdk/
utils.rs

1use bitcoin_hashes::HashEngine;
2use sha2::{Digest, Sha256};
3
4use bip39::Mnemonic;
5
6use simplicityhl::elements::{AssetId, ContractHash, OutPoint, Script};
7use simplicityhl::simplicity::bitcoin;
8use simplicityhl::simplicity::bitcoin::secp256k1;
9use simplicityhl::simplicity::hashes::{Hash, sha256};
10
11/// Generates a radom menemonic with 12 words.
12///
13/// # Panics
14/// Panics if the underlying mnemonic generation fails (e.g. invalid word count configuration).
15#[must_use]
16pub fn random_mnemonic() -> String {
17    let mnemonic = Mnemonic::generate(12).expect("word count should be valid");
18
19    mnemonic.to_string()
20}
21
22/// Generates a hardcoded "unspendable" Taproot public key.
23///
24/// # Panics
25/// Panics if the hardcoded byte slice is not exactly 32 bytes or cannot be parsed into a valid `XOnlyPublicKey` (which should never happen statically).
26#[must_use]
27pub fn tr_unspendable_key() -> secp256k1::XOnlyPublicKey {
28    secp256k1::XOnlyPublicKey::from_slice(&[
29        0x50, 0x92, 0x9b, 0x74, 0xc1, 0xa0, 0x49, 0x54, 0xb7, 0x8b, 0x4b, 0x60, 0x35, 0xe9, 0x7a, 0x5e, 0x07, 0x8a,
30        0x5a, 0x0f, 0x28, 0xec, 0x96, 0xd5, 0x47, 0xbf, 0xee, 0x9a, 0xce, 0x80, 0x3a, 0xc0,
31    ])
32    .expect("key should be valid")
33}
34
35/// Calculates new sha256 midstate and binds generated entropy to the specific outpoint.
36#[must_use]
37pub fn asset_entropy(outpoint: &OutPoint, entropy: [u8; 32]) -> sha256::Midstate {
38    let contract_hash = ContractHash::from_byte_array(entropy);
39    AssetId::generate_asset_entropy(*outpoint, contract_hash)
40}
41
42/// Hashes arbitrary data with and additional `TapData` and tags.
43#[must_use]
44pub fn tap_data_hash(data: &[u8]) -> sha256::Hash {
45    let tag = sha256::Hash::hash(b"TapData");
46
47    let mut eng = sha256::Hash::engine();
48    eng.input(tag.as_byte_array());
49    eng.input(tag.as_byte_array());
50    eng.input(data);
51
52    sha256::Hash::from_engine(eng)
53}
54
55/// Computes the SHA-256 hash of a given script and returns the resulting 32-byte array.
56#[must_use]
57pub fn hash_script(script: &Script) -> [u8; 32] {
58    let mut hasher = Sha256::new();
59
60    sha2::digest::Update::update(&mut hasher, script.as_bytes());
61    hasher.finalize().into()
62}
63
64/// Converts Satoshi amount into BTC.
65#[must_use]
66pub fn sat2btc(sat: u64) -> f64 {
67    bitcoin::Amount::from_sat(sat).to_btc()
68}
69
70/// Converts BTC amount into Satoshi.
71#[must_use]
72pub fn btc2sat(btc: u64) -> u64 {
73    bitcoin::Amount::from_int_btc(btc).to_sat()
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79
80    #[test]
81    fn generates_mnemonic() {
82        let _ = random_mnemonic();
83    }
84}