255 lines
9.7 KiB
Rust
255 lines
9.7 KiB
Rust
use std::collections::HashMap;
|
|
|
|
use log::debug;
|
|
use sdk_client::api::{
|
|
create_login_transaction, create_pairing_transaction, dump_device, dump_message_cache, dump_wallet, get_outputs, login, pair_device, reset_device, restore_device, set_message_cache, setup
|
|
};
|
|
use sdk_common::network::{
|
|
CachedMessage, CachedMessageStatus,
|
|
};
|
|
use sdk_common::sp_client::bitcoin::OutPoint;
|
|
use sdk_common::sp_client::spclient::OwnedOutput;
|
|
use serde_json;
|
|
|
|
use tsify::JsValueSerdeExt;
|
|
use wasm_bindgen_test::*;
|
|
|
|
mod utils;
|
|
|
|
use utils::*;
|
|
|
|
wasm_bindgen_test_configure!(run_in_browser);
|
|
|
|
#[wasm_bindgen_test]
|
|
fn test_pairing() {
|
|
setup();
|
|
debug!("==============================================\nStarting test_pairing\n==============================================");
|
|
|
|
// ========================= Alice
|
|
helper_switch_device(ALICE_LOGIN_WALLET.to_owned());
|
|
|
|
debug!("Alice sends a pairing transaction to Bob");
|
|
let alice_pairing_tx = create_pairing_transaction(helper_get_bob_address(), 1).unwrap();
|
|
|
|
let get_outputs_result = get_outputs().unwrap();
|
|
|
|
let alice_outputs: HashMap<OutPoint, OwnedOutput> = get_outputs_result.into_serde().unwrap();
|
|
|
|
let alice_pairing_tweak_data =
|
|
helper_get_tweak_data(&alice_pairing_tx.transaction, alice_outputs);
|
|
|
|
// Alice parse her own transaction
|
|
let alice_msg_id =
|
|
helper_parse_transaction(&alice_pairing_tx.transaction, &alice_pairing_tweak_data).id;
|
|
|
|
let alice_wallet = dump_wallet().unwrap();
|
|
let alice_cache = dump_message_cache().unwrap();
|
|
|
|
// ======================= Bob
|
|
reset_device().unwrap();
|
|
helper_switch_device(BOB_LOGIN_WALLET.to_owned());
|
|
|
|
// Bob receives Alice pairing transaction
|
|
// if he agrees, he must send another pairing transaction to Alice
|
|
// he can also spend the output that notified him that will become Alice first session key
|
|
debug!("Bob parses Alice pairing transaction");
|
|
helper_parse_transaction(&alice_pairing_tx.transaction, &alice_pairing_tweak_data);
|
|
|
|
debug!("Bob receives the prd");
|
|
helper_parse_cipher(alice_pairing_tx.new_network_msg.prd_cipher.unwrap());
|
|
|
|
debug!("Bob receives the pcd");
|
|
let alice_pairing_res = helper_parse_cipher(alice_pairing_tx.new_network_msg.pcd_cipher.unwrap());
|
|
|
|
assert!(alice_pairing_res.status == CachedMessageStatus::Pairing);
|
|
// Bob takes the txid of the incoming transaction from Alice, he will need it for pairing
|
|
let incoming_txid = alice_pairing_res.commited_in.unwrap().txid;
|
|
|
|
// At this point, user must validate the pairing proposal received from Alice
|
|
|
|
debug!("Bob sends a pairing transaction back");
|
|
let bob_pairing_tx = create_pairing_transaction(alice_pairing_res.sender.unwrap(), 1).unwrap();
|
|
|
|
let get_outputs_result = get_outputs().unwrap();
|
|
|
|
let bob_outputs: HashMap<OutPoint, OwnedOutput> = get_outputs_result.into_serde().unwrap();
|
|
|
|
let bob_pairing_tweak_data = helper_get_tweak_data(&bob_pairing_tx.transaction, bob_outputs);
|
|
|
|
helper_parse_transaction(&bob_pairing_tx.transaction, &bob_pairing_tweak_data);
|
|
|
|
debug!("Bob pairs device with Alice");
|
|
let pairing_process = pair_device(DEFAULT_NYM.to_owned(), bob_pairing_tx.new_network_msg.id, incoming_txid.to_string()).unwrap();
|
|
|
|
// sign the pairing process
|
|
|
|
// send it to Alice so that she can sign it too
|
|
|
|
// commit it to a transaction to make it public
|
|
|
|
// ======================== Alice
|
|
reset_device().unwrap();
|
|
helper_switch_device(alice_wallet);
|
|
set_message_cache(alice_cache).unwrap();
|
|
|
|
// parse Bob's pairing transaction
|
|
helper_parse_transaction(&bob_pairing_tx.transaction, &bob_pairing_tweak_data);
|
|
helper_parse_cipher(bob_pairing_tx.new_network_msg.prd_cipher.unwrap());
|
|
|
|
let bob_pairing_msg = helper_parse_cipher(bob_pairing_tx.new_network_msg.pcd_cipher.unwrap());
|
|
|
|
assert!(bob_pairing_msg.status == CachedMessageStatus::Pairing);
|
|
|
|
debug!("Alice pairs device");
|
|
pair_device(DEFAULT_NYM.to_owned(), alice_msg_id, bob_pairing_tx.txid).unwrap();
|
|
}
|
|
|
|
#[wasm_bindgen_test]
|
|
fn test_first_login() {
|
|
reset_device().unwrap();
|
|
setup();
|
|
debug!("==============================================\nStarting test_first_login\n==============================================");
|
|
|
|
restore_device(BOB_PAIRED_DEVICE.to_owned()).unwrap();
|
|
set_message_cache(
|
|
serde_json::from_str::<Vec<CachedMessage>>(BOB_PAIRING_CACHE)
|
|
.unwrap()
|
|
.into_iter()
|
|
.map(|v| v.to_string())
|
|
.collect(),
|
|
)
|
|
.unwrap();
|
|
|
|
// Bob can now spend the notification output, that will become Alice's first session key
|
|
debug!("Bob first login");
|
|
let bob_first_login_tx = create_login_transaction(1).unwrap();
|
|
|
|
let get_outputs_result = get_outputs().unwrap();
|
|
|
|
let bob_outputs: HashMap<OutPoint, OwnedOutput> = get_outputs_result.into_serde().unwrap();
|
|
|
|
let bob_login_tweak_data = helper_get_tweak_data(&bob_first_login_tx.transaction, bob_outputs);
|
|
|
|
debug!("Bob parses his own login transaction");
|
|
helper_parse_transaction(&bob_first_login_tx.transaction, &bob_login_tweak_data);
|
|
|
|
let bob_device = dump_device().unwrap();
|
|
let bob_cache = dump_message_cache().unwrap();
|
|
|
|
// ======================== Alice
|
|
reset_device().unwrap();
|
|
restore_device(ALICE_PAIRED_DEVICE.to_owned()).unwrap();
|
|
set_message_cache(
|
|
serde_json::from_str::<Vec<CachedMessage>>(ALICE_PAIRING_CACHE)
|
|
.unwrap()
|
|
.into_iter()
|
|
.map(|v| v.to_string())
|
|
.collect(),
|
|
)
|
|
.unwrap();
|
|
|
|
debug!("Alice finds out the login demand from Bob");
|
|
helper_parse_transaction(&bob_first_login_tx.transaction, &bob_login_tweak_data);
|
|
helper_parse_cipher(bob_first_login_tx.new_network_msg.prd_cipher.unwrap());
|
|
let bob_login_msg = helper_parse_cipher(bob_first_login_tx.new_network_msg.pcd_cipher.unwrap());
|
|
|
|
// At this point Alice can fire up the revokation output if the login demand is illegitimate
|
|
// OR she must answer with a login transaction to Bob
|
|
debug!("Alice first login");
|
|
let alice_first_login_tx = create_login_transaction(1).unwrap();
|
|
|
|
let get_outputs_result = get_outputs().unwrap();
|
|
|
|
let alice_outputs: HashMap<OutPoint, OwnedOutput> = get_outputs_result.into_serde().unwrap();
|
|
|
|
let alice_login_tweak_data =
|
|
helper_get_tweak_data(&alice_first_login_tx.transaction, alice_outputs);
|
|
|
|
helper_parse_transaction(&alice_first_login_tx.transaction, &alice_login_tweak_data);
|
|
|
|
login(bob_login_msg.id, alice_first_login_tx.transaction.clone()).unwrap();
|
|
|
|
// ======================= Bob
|
|
reset_device().unwrap();
|
|
restore_device(bob_device).unwrap();
|
|
set_message_cache(bob_cache).unwrap();
|
|
|
|
helper_parse_transaction(&alice_first_login_tx.transaction, &alice_login_tweak_data);
|
|
helper_parse_cipher(alice_first_login_tx.new_network_msg.prd_cipher.unwrap());
|
|
let alice_login_msg = helper_parse_cipher(alice_first_login_tx.new_network_msg.pcd_cipher.unwrap());
|
|
|
|
assert!(alice_login_msg.status == CachedMessageStatus::Login);
|
|
|
|
login(alice_login_msg.id, bob_first_login_tx.transaction).unwrap();
|
|
}
|
|
|
|
#[wasm_bindgen_test]
|
|
fn test_login() {
|
|
reset_device().unwrap();
|
|
setup();
|
|
debug!("==============================================\nStarting test_login\n==============================================");
|
|
|
|
// ======================= Alice
|
|
restore_device(ALICE_LOGGED_DEVICE.to_owned()).unwrap();
|
|
|
|
debug!("Alice sends a login transaction to Bob, which creates a new key for him");
|
|
let alice_login_tx = create_login_transaction(1).unwrap();
|
|
|
|
let get_outputs_result = get_outputs().unwrap();
|
|
|
|
let alice_outputs: HashMap<OutPoint, OwnedOutput> = get_outputs_result.into_serde().unwrap();
|
|
|
|
let alice_login_tweak_data = helper_get_tweak_data(
|
|
&alice_login_tx.transaction,
|
|
alice_outputs
|
|
);
|
|
|
|
debug!("Parsing Alice login transaction");
|
|
helper_parse_transaction(&alice_login_tx.transaction, &alice_login_tweak_data);
|
|
|
|
let alice_device = dump_device().unwrap();
|
|
let alice_cache = dump_message_cache().unwrap();
|
|
|
|
// ============================== Bob
|
|
reset_device().unwrap();
|
|
restore_device(BOB_LOGGED_DEVICE.to_owned()).unwrap();
|
|
|
|
debug!("Bob finds out the login demand from Alice");
|
|
helper_parse_transaction(&alice_login_tx.transaction, &alice_login_tweak_data);
|
|
helper_parse_cipher(alice_login_tx.new_network_msg.prd_cipher.unwrap());
|
|
let alice_login_msg = helper_parse_cipher(alice_login_tx.new_network_msg.pcd_cipher.unwrap());
|
|
|
|
// Bob must confirm that he agrees to log in
|
|
|
|
// Boutons "login" ou "Refuser"
|
|
// At this point Bob can fire up the revokation output if the login demand is illegitimate
|
|
// revoke_paired_device(1).unwrap();
|
|
// OR it must answer with a login transaction to Alice
|
|
let bob_login_tx = create_login_transaction(1).unwrap();
|
|
|
|
let get_outputs_result = get_outputs().unwrap();
|
|
|
|
let bob_outputs: HashMap<OutPoint, OwnedOutput> = get_outputs_result.into_serde().unwrap();
|
|
|
|
let bob_login_tweak_data = helper_get_tweak_data(&bob_login_tx.transaction, bob_outputs);
|
|
|
|
debug!("Bob parses his own login transaction");
|
|
helper_parse_transaction(&bob_login_tx.transaction, &bob_login_tweak_data);
|
|
|
|
login(alice_login_msg.id, alice_login_tx.transaction.clone()).unwrap();
|
|
|
|
// =================== Alice
|
|
|
|
reset_device().unwrap();
|
|
restore_device(alice_device).unwrap();
|
|
set_message_cache(alice_cache).unwrap();
|
|
|
|
helper_parse_transaction(&bob_login_tx.transaction, &bob_login_tweak_data);
|
|
helper_parse_cipher(bob_login_tx.new_network_msg.prd_cipher.unwrap());
|
|
let bob_login_msg = helper_parse_cipher(bob_login_tx.new_network_msg.pcd_cipher.unwrap());
|
|
|
|
assert!(bob_login_msg.status == CachedMessageStatus::Login);
|
|
|
|
login(bob_login_msg.id, alice_login_tx.transaction).unwrap();
|
|
}
|