whisky_wallet/wallet/
mod.rs1pub mod derivation_indices;
2pub mod mnemonic;
3pub mod root_key;
4use bip39::{Language, Mnemonic};
5use derivation_indices::DerivationIndices;
6pub use mnemonic::MnemonicWallet;
7pub use root_key::RootKeyWallet;
8use whisky_common::WError;
9use whisky_csl::{
10 csl::{Bip32PrivateKey, FixedTransaction, PrivateKey, PublicKey},
11 sign_transaction,
12};
13
14pub enum WalletType {
15 MnemonicWallet(MnemonicWallet),
16 RootKeyWallet(RootKeyWallet),
17 Cli(String),
18}
19
20pub struct Wallet {
21 pub wallet_type: WalletType,
22}
23
24pub struct Account {
25 pub private_key: PrivateKey,
26 pub public_key: PublicKey,
27}
28
29impl Account {
30 pub fn sign_transaction(&self, tx_hex: &str) -> Result<String, WError> {
31 let mut tx = FixedTransaction::from_hex(tx_hex)
32 .map_err(WError::from_err("Account - failed to deserialize tx hex"))?;
33 tx.sign_and_add_vkey_signature(&self.private_key)
34 .map_err(WError::from_err("Account - failed to sign transaction"))?;
35 Ok(tx.to_hex())
36 }
37}
38
39impl Wallet {
40 pub fn new(wallet_type: WalletType) -> Self {
41 Self { wallet_type }
42 }
43
44 pub fn new_cli(cli_skey: &str) -> Self {
45 Self {
46 wallet_type: WalletType::Cli(cli_skey.to_string()),
47 }
48 }
49
50 pub fn new_mnemonic(mnemonic_phrase: &str) -> Self {
51 Self {
52 wallet_type: WalletType::MnemonicWallet(MnemonicWallet {
53 mnemonic_phrase: mnemonic_phrase.to_string(),
54 derivation_indices: DerivationIndices::default(),
55 }),
56 }
57 }
58
59 pub fn new_root_key(root_key: &str) -> Self {
60 Self {
61 wallet_type: WalletType::RootKeyWallet(RootKeyWallet {
62 root_key: root_key.to_string(),
63 derivation_indices: DerivationIndices::default(),
64 }),
65 }
66 }
67
68 pub fn payment_account(&mut self, account_index: u32, key_index: u32) -> &mut Self {
69 match &mut self.wallet_type {
70 WalletType::MnemonicWallet(mnemonic_wallet) => {
71 mnemonic_wallet.payment_account(account_index, key_index);
72 }
73 WalletType::RootKeyWallet(root_key_wallet) => {
74 root_key_wallet.payment_account(account_index, key_index);
75 }
76 _ => {}
77 }
78 self
79 }
80
81 pub fn stake_account(&mut self, account_index: u32, key_index: u32) -> &mut Self {
82 match &mut self.wallet_type {
83 WalletType::MnemonicWallet(mnemonic_wallet) => {
84 mnemonic_wallet.stake_account(account_index, key_index);
85 }
86 WalletType::RootKeyWallet(root_key_wallet) => {
87 root_key_wallet.stake_account(account_index, key_index);
88 }
89 _ => {}
90 }
91 self
92 }
93
94 pub fn drep_account(&mut self, account_index: u32, key_index: u32) -> &mut Self {
95 match &mut self.wallet_type {
96 WalletType::MnemonicWallet(mnemonic_wallet) => {
97 mnemonic_wallet.drep_account(account_index, key_index);
98 }
99 WalletType::RootKeyWallet(root_key_wallet) => {
100 root_key_wallet.drep_account(account_index, key_index);
101 }
102 _ => {}
103 }
104 self
105 }
106
107 pub fn sign_tx(&self, tx_hex: &str) -> Result<String, WError> {
108 match &self.wallet_type {
109 WalletType::Cli(cli_skey) => {
110 let signed_tx = sign_transaction(tx_hex, &[cli_skey])
111 .map_err(WError::from_err("Wallet - sign_tx"))?;
112 Ok(signed_tx)
113 }
114 _ => {
115 let account = self
116 .get_account()
117 .map_err(WError::from_err("Wallet - sign_tx"))?;
118 let signed_tx = account
119 .sign_transaction(tx_hex)
120 .map_err(WError::from_err("Wallet - sign_tx"))?;
121 Ok(signed_tx.to_string())
122 }
123 }
124 }
125
126 pub fn get_account(&self) -> Result<Account, WError> {
127 let private_key: PrivateKey = match &self.wallet_type {
128 WalletType::MnemonicWallet(mnemonic_wallet) => {
129 let mnemonic =
130 Mnemonic::from_phrase(&mnemonic_wallet.mnemonic_phrase, Language::English)
131 .map_err(WError::from_err(
132 "Wallet - get_account - failed to create mnemonic",
133 ))?;
134 let entropy = mnemonic.entropy();
135 let mut root_key = Bip32PrivateKey::from_bip39_entropy(entropy, &[]);
136 for index in &mnemonic_wallet.derivation_indices.0 {
137 root_key = root_key.derive(index.clone());
138 }
139 root_key.to_raw_key()
140 }
141 WalletType::RootKeyWallet(root_key_wallet) => {
142 let mut root_key = Bip32PrivateKey::from_bech32(&root_key_wallet.root_key)
143 .map_err(WError::from_err(
144 "Wallet - get_account - invalid root key hex",
145 ))?;
146 for index in &root_key_wallet.derivation_indices.0 {
147 root_key = root_key.derive(index.clone());
148 }
149 root_key.to_raw_key()
150 }
151 WalletType::Cli(private_key) => PrivateKey::from_hex(&private_key).map_err(
152 WError::from_err("Wallet - get_account - invalid private key hex"),
153 )?,
154 };
155 let public_key = private_key.to_public();
156 Ok(Account {
157 private_key,
158 public_key,
159 })
160 }
161}