Created
June 14, 2023 01:44
-
-
Save larry0x/92399bb2f9ce4b769e112ce5550091b9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! ```cargo | |
//! [dependencies] | |
//! bech32 = "0.9" | |
//! bip32 = "0.5" | |
//! dialoguer = "0.10" | |
//! hex = "0.4" | |
//! k256 = "0.13" | |
//! ripemd = "0.1" | |
//! thiserror = "1" | |
//! ``` | |
use bech32::{ToBase32, Variant}; | |
use bip32::{Language, Mnemonic, XPrv}; | |
use k256::sha2::{Digest, Sha256}; | |
use ripemd::Ripemd160; | |
const HD_PATH: &str = "m/44'/330'/0'/0/0"; | |
const BECH_PREFIX: &str = "osmo"; | |
fn main() -> Result<()> { | |
// read seed phrase from CLI | |
let mnemonic_str = read_string("Enter seed phrase:")?; | |
let mnemonic = Mnemonic::new(mnemonic_str, Language::English)?; | |
// parameters | |
let seed = mnemonic.to_seed(""); | |
let hd_path = HD_PATH.parse()?; | |
// seed phrase => private key | |
let privkey = XPrv::derive_from_path(&seed, &hd_path)?; | |
let privkey_bytes = privkey.to_bytes(); | |
let privkey_str = hex::encode(privkey_bytes); | |
// private key => public key | |
let pubkey = privkey.public_key(); | |
let pubkey_bytes = pubkey.to_bytes(); | |
let pubkey_str = hex::encode(pubkey_bytes); | |
// public key => address | |
let address_bytes = ripemd160(&sha256(&pubkey_bytes)); | |
let address_str = bech32::encode(BECH_PREFIX, address_bytes.to_base32(), Variant::Bech32)?; | |
println!("address: {address_str}"); | |
println!("privkey: {privkey_str}"); | |
println!("pubkey: {pubkey_str}"); | |
Ok(()) | |
} | |
fn sha256(bytes: &[u8]) -> Vec<u8> { | |
let mut hasher = Sha256::new(); | |
hasher.update(bytes); | |
hasher.finalize().to_vec() | |
} | |
fn ripemd160(bytes: &[u8]) -> Vec<u8> { | |
let mut hasher = Ripemd160::new(); | |
hasher.update(bytes); | |
hasher.finalize().to_vec() | |
} | |
fn read_string(prompt: impl Into<String>) -> Result<String> { | |
dialoguer::Input::new() | |
.with_prompt(prompt) | |
.report(false) | |
.interact_text() | |
.map_err(Into::into) | |
} | |
#[derive(Debug, thiserror::Error)] | |
enum Error { | |
#[error(transparent)] | |
Bech32(#[from] bech32::Error), | |
#[error(transparent)] | |
Bip32(#[from] bip32::Error), | |
#[error(transparent)] | |
Io(#[from] std::io::Error), | |
} | |
type Result<T> = core::result::Result<T, Error>; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment