-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5cdde0f
commit bcb8ab4
Showing
3 changed files
with
173 additions
and
53 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,60 +1,164 @@ | ||
use secp256k1::{PublicKey, Secp256k1}; | ||
|
||
use walleth::{Keychain, Signable, Controller}; | ||
use walleth::{Controller, Keychain, Signable}; | ||
|
||
const MNEMONIC: &str = | ||
"grocery belt target explain clay essay focus spatial skull brain measure matrix toward visual protect owner stone scale slim ghost panda exact combine game"; | ||
|
||
#[test] | ||
fn it_creates_new_vault() { | ||
let keychain = Keychain::new(); | ||
assert_eq!(keychain.get_state().accounts.len(), 0); | ||
mod new { | ||
use super::*; | ||
|
||
#[test] | ||
fn it_creates_a_new_keychain() { | ||
let keychain = Keychain::new(); | ||
assert_eq!(keychain.get_state().accounts.len(), 0); | ||
} | ||
} | ||
|
||
#[test] | ||
fn it_adds_a_new_account() { | ||
let mut keychain = Keychain::new(); | ||
mod from_mnemonic { | ||
use super::*; | ||
|
||
keychain.add_account().unwrap(); | ||
#[test] | ||
fn it_creates_a_new_keychain_from_mnemonic() { | ||
let keychain = Keychain::from_mnemonic(MNEMONIC.to_string()); | ||
assert!(keychain.is_ok()); | ||
} | ||
|
||
assert_eq!(keychain.get_state().accounts.len(), 1); | ||
#[test] | ||
fn it_fails_with_wrong_mnemonic() { | ||
let keychain = Keychain::from_mnemonic("this is wrong".to_string()); | ||
assert!(!keychain.is_ok()); | ||
} | ||
} | ||
|
||
#[test] | ||
fn it_creates_new_vault_from_existing_mnemonic() { | ||
Keychain::from_mnemonic(MNEMONIC.to_string()).unwrap(); | ||
mod add_account { | ||
use super::*; | ||
|
||
#[test] | ||
fn it_adds_a_new_account() { | ||
let mut keychain = Keychain::from_mnemonic(MNEMONIC.to_string()).unwrap(); | ||
|
||
let key = keychain.add_account().unwrap(); | ||
|
||
assert_eq!(keychain.get_state().accounts.len(), 1); | ||
assert_eq!(keychain.get_state().accounts[0].address, key.address); | ||
assert_eq!( | ||
keychain.get_state().accounts[0].address, | ||
"0x356281bf5382846adf421cf4d4a9421f5f158592".to_string() | ||
); | ||
} | ||
|
||
#[test] | ||
fn it_fails_when_locked() { | ||
let mut keychain = Keychain::from_mnemonic(MNEMONIC.to_string()).unwrap(); | ||
keychain.lock("my password").unwrap(); | ||
|
||
let account = keychain.add_account(); | ||
|
||
assert!(!account.is_ok()); | ||
} | ||
} | ||
|
||
#[test] | ||
fn it_adds_the_same_key_given_the_same_mnemonic() { | ||
let mut keychain = Keychain::from_mnemonic(MNEMONIC.to_string()).unwrap(); | ||
mod use_signer { | ||
use super::*; | ||
use secp256k1::{PublicKey, Secp256k1}; | ||
|
||
let key = keychain.add_account().unwrap(); | ||
#[test] | ||
fn it_signs_a_message() { | ||
let mut keychain = Keychain::from_mnemonic(MNEMONIC.to_string()).unwrap(); | ||
let key = keychain.add_account().unwrap(); | ||
let message = Signable::from_bytes(b"Hello world!").unwrap(); | ||
|
||
assert_eq!(keychain.get_state().accounts.len(), 1); | ||
assert_eq!(keychain.get_state().accounts[0].address, key.address); | ||
assert_eq!( | ||
keychain.get_state().accounts[0].address, | ||
"0x356281bf5382846adf421cf4d4a9421f5f158592".to_string() | ||
); | ||
let signature = keychain | ||
.use_signer(key.address, |signer| signer.sign(&message).unwrap()) | ||
.unwrap(); | ||
|
||
assert!(Secp256k1::new() | ||
.verify_ecdsa( | ||
&message.to_signable_message(), | ||
&signature, | ||
&PublicKey::from_slice(&key.public_key.to_bytes()).unwrap() | ||
) | ||
.is_ok()); | ||
} | ||
} | ||
|
||
#[test] | ||
fn it_signs_a_message_with_use_signer_hook() { | ||
let mut keychain = Keychain::from_mnemonic(MNEMONIC.to_string()).unwrap(); | ||
let key = keychain.add_account().unwrap(); | ||
let message = Signable::from_bytes(b"Hello world!").unwrap(); | ||
let secp256k1 = Secp256k1::new(); | ||
mod lock { | ||
use super::*; | ||
|
||
#[test] | ||
fn it_locks_the_keychain() { | ||
let mut keychain = Keychain::from_mnemonic(MNEMONIC.to_string()).unwrap(); | ||
|
||
keychain.lock("my password").unwrap(); | ||
|
||
assert!(!keychain.add_account().is_ok()); | ||
} | ||
} | ||
|
||
mod unlock { | ||
use super::*; | ||
|
||
#[test] | ||
fn it_unlocks_the_keychain() { | ||
let mut keychain = Keychain::new(); | ||
let account = keychain.add_account().unwrap(); | ||
keychain.lock("password").unwrap(); | ||
|
||
let recovered_accounts = keychain.unlock("password").unwrap(); | ||
|
||
assert_eq!(account.address, recovered_accounts[0].address); | ||
} | ||
} | ||
|
||
mod update { | ||
|
||
use super::*; | ||
|
||
#[test] | ||
fn it_updates_the_keychain_store() { | ||
let mut keychain = Keychain::new(); | ||
keychain.add_account().unwrap(); | ||
|
||
keychain.update(|state| { | ||
state.accounts = vec![]; | ||
}); | ||
|
||
assert_eq!(keychain.get_state().accounts.len(), 0); | ||
} | ||
} | ||
|
||
mod subscribe { | ||
// use std::sync::mpsc::channel; | ||
// use std::thread; | ||
|
||
// TODO: .subscribe listener should implement `Send` trait | ||
//#[test] | ||
//fn it_subscribes_to_keychain_updates() { | ||
// let mut keychain = Keychain::new(); | ||
// let (tx, rx) = channel(); | ||
// | ||
// let handle = thread::spawn(move || { | ||
// keychain.subscribe(move |state| { | ||
// tx.send(state.accounts.len()).unwrap(); | ||
// }); | ||
// }); | ||
// | ||
// keychain.add_account().unwrap(); | ||
// | ||
// assert_eq!(rx.recv().unwrap(), 1); | ||
// | ||
// handle.join().unwrap(); | ||
//} | ||
} | ||
|
||
mod get_state { | ||
use super::*; | ||
|
||
#[test] | ||
fn it_gets_the_keychain_state() { | ||
let keychain = Keychain::new(); | ||
|
||
let signature = keychain | ||
.use_signer(key.address, |signer| signer.sign(&message).unwrap()) | ||
.unwrap(); | ||
let state = keychain.get_state(); | ||
|
||
assert!(secp256k1 | ||
.verify_ecdsa( | ||
&message.to_signable_message(), | ||
&signature, | ||
&PublicKey::from_slice(&key.public_key.to_bytes()).unwrap() | ||
) | ||
.is_ok()); | ||
assert_eq!(state.accounts.len(), 0); | ||
} | ||
} |