use std::collections::HashMap; use sdk_client::api::{ create_device_from_sp_wallet, create_process_init_transaction, get_outputs, pair_device, reset_device, setup, CreateProcessInitTransactionArguments }; use sdk_client::lock_processes; use sdk_common::network::CachedMessage; use sdk_common::pcd::{Member, Pcd, Role}; use sdk_common::prd::Prd; use sdk_common::process::{Process, ValidationRules}; use sdk_common::sp_client::bitcoin::OutPoint; use sdk_common::sp_client::spclient::OwnedOutput; use sdk_common::uuid::Uuid; use sdk_common::log::debug; use serde_json::{self, json, Value}; 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 reset_device().unwrap(); create_device_from_sp_wallet(ALICE_LOGIN_WALLET.to_owned()).unwrap(); // Alice creates the new member with Bob address let new_member = Member::new( DEFAULT_NYM.to_owned(), helper_get_alice_address().try_into().unwrap(), helper_get_bob_address().try_into().unwrap(), Role::User ); let initial_state = json!({ "nym": DEFAULT_NYM, "members": [ new_member, ], "current_session_tx": null, }); let validation_rules = ValidationRules::new( 1.0, Role::Admin, 1.0 ); let mut member2fields: HashMap> = HashMap::new(); member2fields.insert(new_member, initial_state.as_object().unwrap().keys().map(|k| k.to_owned()).collect()); // We define the process for pairing let pairing_process = Process::new( "pairing".to_owned(), validation_rules, String::default(), String::default(), String::default(), Value::Null, OutPoint::null() ); // we can update our local device now pair_device(pairing_process.uuid.clone(), helper_get_bob_address(), initial_state.to_string()).unwrap(); debug!("Alice sends a transaction commiting to an init prd to Bob"); let args = CreateProcessInitTransactionArguments { member2fields, process: pairing_process, stringified_pcd: initial_state.to_string() }; let alice_pairing_return = create_process_init_transaction(args, 1).unwrap(); let get_outputs_result = get_outputs().unwrap(); let alice_outputs: HashMap = get_outputs_result.into_serde().unwrap(); let alice_pairing_tweak_data = helper_get_tweak_data(&alice_pairing_return.transaction, alice_outputs); // Alice parse her own transaction helper_parse_transaction(&alice_pairing_return.transaction, &alice_pairing_tweak_data).id; // ======================= Bob reset_device().unwrap(); create_device_from_sp_wallet(BOB_LOGIN_WALLET.to_owned()).unwrap(); // Bob receives Alice pairing transaction debug!("Bob parses Alice pairing transaction"); helper_parse_transaction(&alice_pairing_return.transaction, &alice_pairing_tweak_data); debug!("Bob receives the prd"); let mut bob_retrieved_prd = CachedMessage::default(); for message in alice_pairing_return.new_messages.iter() { for cipher in message.cipher.iter() { match helper_parse_cipher(cipher.clone()) { Ok(res) => bob_retrieved_prd = res, Err(_) => continue } } } if bob_retrieved_prd == CachedMessage::default() { panic!("Bob failed to retrieve Alice message"); } debug!("Bob receives the pcd"); let mut bob_retrieved_pcd = CachedMessage::default(); for message in alice_pairing_return.new_messages { for cipher in message.cipher { match helper_parse_cipher(cipher) { Ok(res) => bob_retrieved_pcd = res, Err(_) => continue } } } if bob_retrieved_pcd == CachedMessage::default() { panic!("Bob failed to retrieve Alice message"); } // At this point, user must validate the pairing proposal received from Alice debug!("Bob pairs device with Alice"); let process = lock_processes().unwrap(); let prd: Prd = serde_json::from_str(&bob_retrieved_prd.prd.unwrap()).unwrap(); let relevant_process = process.get(&Uuid::parse_str(&prd.process_uuid).unwrap()).unwrap(); // decrypt the pcd and update bob device if let Some(initial_state) = relevant_process.get_status_at(0) { let keys = initial_state.keys; let mut pcd = initial_state.encrypted_pcd; pcd.decrypt_fields(&keys).unwrap(); pair_device(relevant_process.get_process().uuid, helper_get_alice_address(), pcd.to_string()).unwrap(); } // To make the pairing effective, alice and bob must now spend their respective output into a new transaction // Once we know this tx id, we can commit to the relay }