79 lines
2.2 KiB
Rust
79 lines
2.2 KiB
Rust
use std::collections::HashMap;
|
|
|
|
use cryptoxide::hashing::blake2b_256;
|
|
use minicbor::encode;
|
|
use pallas_addresses::ShelleyPaymentPart;
|
|
use pallas_crypto::hash::{Hash, Hasher};
|
|
use pallas_crypto::key::ed25519::Signature;
|
|
use pallas_crypto::{self, key::ed25519::SecretKey};
|
|
use pallas_primitives::conway::{Tx, VKeyWitness};
|
|
|
|
use crate::tx::plutus::non_empty_set;
|
|
use crate::utils::v2a;
|
|
|
|
use rand::{rngs::OsRng, TryRngCore};
|
|
|
|
const PREFIX: &str = "wallet_";
|
|
|
|
pub struct Wallet {
|
|
pub skey: [u8; 32],
|
|
}
|
|
|
|
impl Wallet {
|
|
pub fn vkey(&self) -> [u8; 32] {
|
|
SecretKey::from(self.skey).public_key().into()
|
|
}
|
|
|
|
pub fn key_hash(&self) -> Hash<28> {
|
|
Hasher::<224>::hash(SecretKey::from(self.skey).public_key().as_ref())
|
|
}
|
|
|
|
pub fn payment_credential(&self) -> ShelleyPaymentPart {
|
|
ShelleyPaymentPart::Key(self.key_hash())
|
|
}
|
|
|
|
pub fn sign_hash(&self, h: &[u8; 32]) -> Signature {
|
|
SecretKey::from(self.skey).sign(h)
|
|
}
|
|
|
|
pub fn sign(&self, tx: &mut Tx) {
|
|
let mut msg = Vec::new();
|
|
encode(&tx.transaction_body, &mut msg).unwrap();
|
|
let tx_hash = blake2b_256(&msg);
|
|
let sig = self.sign_hash(&tx_hash);
|
|
tx.transaction_witness_set.vkeywitness = non_empty_set(vec![VKeyWitness {
|
|
vkey: self.vkey().to_vec().into(),
|
|
signature: sig.as_ref().to_vec().into(),
|
|
}])
|
|
}
|
|
}
|
|
|
|
pub fn from_env(env: &HashMap<String, String>) -> Wallet {
|
|
let wallet_env: HashMap<String, String> = env
|
|
.iter()
|
|
.filter_map(|(k, v)| k.strip_prefix(PREFIX).map(|k| (k.to_string(), v.clone())))
|
|
.collect();
|
|
let raw = wallet_env.get("key").expect("wallet key not found");
|
|
let skey = parse_raw_skey(raw);
|
|
Wallet { skey }
|
|
}
|
|
|
|
pub fn generate() -> [u8; 32] {
|
|
let mut key = [0u8; 32];
|
|
OsRng.try_fill_bytes(&mut key).unwrap();
|
|
key
|
|
}
|
|
|
|
fn parse_raw_skey(raw: &str) -> [u8; 32] {
|
|
// FIXME :: Not tested
|
|
if raw.len() == 64 {
|
|
// Assume hex
|
|
v2a(hex::decode(raw).expect("expected hex")).expect("wrong length")
|
|
} else if raw.len() == 70 {
|
|
// Assume Bech
|
|
v2a(bech32::decode(raw).unwrap().1).expect("wrong length")
|
|
} else {
|
|
panic!("Not supported")
|
|
}
|
|
}
|