sdk_client/tests/pairing.rs
2024-08-15 16:19:29 +02:00

249 lines
9.5 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");
pair_device(bob_pairing_tx.new_network_msg.id, incoming_txid.to_string()).unwrap();
// ======================== 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(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();
}