iuna

iuna - experimental devnet protocol
git clone https://iuna.jhx.app/git/iuna.git
Log | Files | Refs | README | LICENSE

wallet.rs (2002B)


      1 use ed25519_dalek::{Signature, Signer, SigningKey};
      2 use sha2::{Digest, Sha256};
      3 
      4 use super::block::LeaderProofPayload;
      5 use super::{
      6     LeaderProof, PUBLIC_KEY_BYTES, RevealBundle, RevealBundlePayload, decode_hex_array, hex_encode,
      7 };
      8 
      9 const WALLET_SEED_DOMAIN: &str = "iuna-wallet-seed";
     10 
     11 #[derive(Clone, Debug, Eq, PartialEq)]
     12 pub struct Wallet {
     13     address: String,
     14     secret: String,
     15 }
     16 
     17 impl Wallet {
     18     pub fn from_seed(seed: &str) -> Self {
     19         let seed_hash = Sha256::digest(format!("{WALLET_SEED_DOMAIN}:{seed}").as_bytes());
     20         let mut signing_seed = [0_u8; 32];
     21         signing_seed.copy_from_slice(&seed_hash);
     22         let signing_key = SigningKey::from_bytes(&signing_seed);
     23         let secret = hex_encode(signing_seed);
     24         let address = hex_encode(signing_key.verifying_key().to_bytes());
     25         Self { address, secret }
     26     }
     27 
     28     pub fn address(&self) -> &str {
     29         &self.address
     30     }
     31 
     32     pub(super) fn sign_payload(&self, payload: &str) -> String {
     33         let seed =
     34             decode_hex_array::<PUBLIC_KEY_BYTES>(&self.secret).expect("wallet secret is valid hex");
     35         let signing_key = SigningKey::from_bytes(&seed);
     36         let signature: Signature = signing_key.sign(payload.as_bytes());
     37         hex_encode(signature.to_bytes())
     38     }
     39 
     40     pub(super) fn leader_proof(&self, payload: &LeaderProofPayload) -> LeaderProof {
     41         let signature = self.sign_payload(&payload.canonical());
     42         LeaderProof {
     43             ticket_id: payload.ticket_id.clone(),
     44             public_key: self.address.clone(),
     45             signature,
     46         }
     47     }
     48 
     49     pub(super) fn reveal_bundle(&self, payload: RevealBundlePayload) -> RevealBundle {
     50         let signature = self.sign_payload(&payload.canonical());
     51         RevealBundle {
     52             height: payload.height,
     53             prev_hash: payload.prev_hash,
     54             slot: payload.slot,
     55             member: self.address.clone(),
     56             reveals: payload.reveals,
     57             signature,
     58         }
     59     }
     60 }