diff --git a/Cargo.toml b/Cargo.toml index b439237..c247c58 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ serde = { version = "1.0.193", features = ["derive"] } serde_json = { version = "1.0.108" } serde-wasm-bindgen = "0.6.5" # sp_client = { path = "../sp-client" } -sp_client = { git = "https://github.com/Sosthene00/sp-client.git", branch = "4nk" } +sp_client = { git = "https://github.com/Sosthene00/sp-client.git", branch = "dev" } tsify = { git = "https://github.com/Sosthene00/tsify", branch = "next" } wasm-bindgen = "0.2.91" rs_merkle = "1.4.2" diff --git a/src/device.rs b/src/device.rs index 03b93e9..ea0c52e 100644 --- a/src/device.rs +++ b/src/device.rs @@ -3,7 +3,9 @@ use tsify::Tsify; use wasm_bindgen::prelude::*; use sp_client::{ - bitcoin::OutPoint, silentpayments::utils::SilentPaymentAddress, spclient::SpWallet + SpClient, + bitcoin::OutPoint, + silentpayments::SilentPaymentAddress, }; use crate::pcd::Member; @@ -11,28 +13,28 @@ use crate::pcd::Member; #[derive(Debug, Serialize, Deserialize, Clone, Default, Tsify)] #[tsify(into_wasm_abi, from_wasm_abi)] pub struct Device { - sp_wallet: SpWallet, + sp_client: SpClient, pairing_process_commitment: Option, paired_member: Member, } impl Device { - pub fn new(sp_wallet: SpWallet) -> Self { - let local_address = sp_wallet.get_client().get_receiving_address(); + pub fn new(sp_client: SpClient) -> Self { + let local_address = sp_client.get_receiving_address(); let member = Member::new(vec![SilentPaymentAddress::try_from(local_address).unwrap()]); Self { - sp_wallet, + sp_client, pairing_process_commitment: None, paired_member: member, } } - pub fn get_wallet(&self) -> &SpWallet { - &self.sp_wallet + pub fn get_sp_client(&self) -> &SpClient { + &self.sp_client } - pub fn get_mut_wallet(&mut self) -> &mut SpWallet { - &mut self.sp_wallet + pub fn get_mut_sp_client(&mut self) -> &mut SpClient { + &mut self.sp_client } pub fn get_pairing_commitment(&self) -> Option { @@ -45,7 +47,7 @@ impl Device { } pub fn unpair(&mut self) { - let local_address = self.get_wallet().get_client().get_receiving_address(); + let local_address = self.get_sp_client().get_receiving_address(); let member = Member::new(vec![SilentPaymentAddress::try_from(local_address).unwrap()]); self.paired_member = member; self.pairing_process_commitment = None; @@ -55,8 +57,12 @@ impl Device { self.paired_member.clone() } + pub fn get_address(&self) -> SilentPaymentAddress { + self.get_sp_client().get_receiving_address() + } + pub fn get_other_addresses(&self) -> Vec { - let our_address = self.get_wallet().get_client().get_receiving_address(); + let our_address: String = self.get_sp_client().get_receiving_address().into(); self.to_member() .get_addresses() .into_iter() diff --git a/src/pcd.rs b/src/pcd.rs index a91f32a..bc49db6 100644 --- a/src/pcd.rs +++ b/src/pcd.rs @@ -14,7 +14,7 @@ use sp_client::{ bitcoin::{ consensus::serialize, hashes::{sha256t_hash_newtype, Hash, HashEngine}, secp256k1::PublicKey, OutPoint }, - silentpayments::utils::SilentPaymentAddress, + silentpayments::SilentPaymentAddress, }; use tsify::Tsify; @@ -481,7 +481,7 @@ mod tests { use serde_json::json; use sp_client::{ bitcoin::{secp256k1::SecretKey, Network}, - spclient::{SpClient, SpWallet, SpendKey}, + SpClient, SpendKey, }; use super::*; @@ -490,50 +490,36 @@ mod tests { signature::{AnkHash, Proof}, }; - fn create_alice_wallet() -> SpWallet { - SpWallet::new( - SpClient::new( - "default".to_owned(), - SecretKey::from_str( - "a67fb6bf5639efd0aeb19c1c584dd658bceda87660ef1088d4a29d2e77846973", - ) - .unwrap(), - SpendKey::Secret( - SecretKey::from_str( - "a1e4e7947accf33567e716c9f4d186f26398660e36cf6d2e711af64b3518e65c", - ) - .unwrap(), - ), - None, - Network::Signet, + fn create_alice_wallet() -> SpClient { + SpClient::new( + SecretKey::from_str( + "a67fb6bf5639efd0aeb19c1c584dd658bceda87660ef1088d4a29d2e77846973", ) .unwrap(), - None, - vec![], + SpendKey::Secret( + SecretKey::from_str( + "a1e4e7947accf33567e716c9f4d186f26398660e36cf6d2e711af64b3518e65c", + ) + .unwrap(), + ), + Network::Signet, ) .unwrap() } - fn create_bob_wallet() -> SpWallet { - SpWallet::new( - SpClient::new( - "default".to_owned(), - SecretKey::from_str( - "4d9f62b2340de3f0bafd671b78b19edcfded918c4106baefd34512f12f520e9b", - ) - .unwrap(), - SpendKey::Secret( - SecretKey::from_str( - "dafb99602721577997a6fe3da54f86fd113b1b58f0c9a04783d486f87083a32e", - ) - .unwrap(), - ), - None, - Network::Signet, + fn create_bob_wallet() -> SpClient { + SpClient::new( + SecretKey::from_str( + "4d9f62b2340de3f0bafd671b78b19edcfded918c4106baefd34512f12f520e9b", ) .unwrap(), - None, - vec![], + SpendKey::Secret( + SecretKey::from_str( + "dafb99602721577997a6fe3da54f86fd113b1b58f0c9a04783d486f87083a32e", + ) + .unwrap(), + ), + Network::Signet, ) .unwrap() } @@ -605,18 +591,17 @@ mod tests { let validation_hash2 = AnkValidationNoHash::from_merkle_root(new_state_merkle_root); let alice_spend_key: SecretKey = alice_wallet - .get_client() .get_spend_key() .try_into() .unwrap(); - let bob_spend_key: SecretKey = bob_wallet.get_client().get_spend_key().try_into().unwrap(); + let bob_spend_key: SecretKey = bob_wallet.get_spend_key().try_into().unwrap(); let alice_proof = Proof::new(AnkHash::ValidationNo(validation_hash2), alice_spend_key); let bob_proof = Proof::new(AnkHash::ValidationYes(validation_hash1), bob_spend_key); let members_list = get_members_map([ - alice_wallet.get_client().get_receiving_address(), - bob_wallet.get_client().get_receiving_address() + alice_wallet.get_receiving_address().to_string(), + bob_wallet.get_receiving_address().to_string() ]); let members: Vec<&Member> = members_list.values().collect(); @@ -667,11 +652,10 @@ mod tests { let validation_hash_no = AnkValidationNoHash::from_merkle_root(new_state_merkle_root); let alice_spend_key: SecretKey = alice_wallet - .get_client() .get_spend_key() .try_into() .unwrap(); - let bob_spend_key: SecretKey = bob_wallet.get_client().get_spend_key().try_into().unwrap(); + let bob_spend_key: SecretKey = bob_wallet.get_spend_key().try_into().unwrap(); let alice_proof = Proof::new(AnkHash::ValidationNo(validation_hash_no), alice_spend_key); let bob_proof = Proof::new(AnkHash::ValidationYes(validation_hash_yes), bob_spend_key); @@ -679,8 +663,8 @@ mod tests { let proofs = vec![alice_proof, bob_proof]; let members_list = get_members_map([ - alice_wallet.get_client().get_receiving_address(), - bob_wallet.get_client().get_receiving_address() + alice_wallet.get_receiving_address().to_string(), + bob_wallet.get_receiving_address().to_string() ]); let members: Vec<&Member> = members_list.values().collect(); @@ -715,7 +699,6 @@ mod tests { let validation_hash = AnkValidationYesHash::from_merkle_root(new_state_merkle_root); let alice_spend_key: SecretKey = alice_wallet - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -727,8 +710,8 @@ mod tests { let proofs = vec![alice_proof_1, alice_proof_2]; let members_list = get_members_map([ - alice_wallet.get_client().get_receiving_address(), - bob_wallet.get_client().get_receiving_address() + alice_wallet.get_receiving_address().to_string(), + bob_wallet.get_receiving_address().to_string() ]); let members: Vec<&Member> = members_list.values().collect(); @@ -758,7 +741,6 @@ mod tests { let validation_hash = AnkValidationYesHash::from_merkle_root(new_state_merkle_root); let alice_spend_key: SecretKey = alice_wallet - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -770,8 +752,8 @@ mod tests { let proofs = vec![alice_proof_1, alice_proof_2]; let members_list = get_members_map([ - alice_wallet.get_client().get_receiving_address(), - bob_wallet.get_client().get_receiving_address() + alice_wallet.get_receiving_address().to_string(), + bob_wallet.get_receiving_address().to_string() ]); let members: Vec<&Member> = members_list.values().collect(); @@ -790,7 +772,7 @@ mod tests { let alice_wallet = create_alice_wallet(); let member = Member::new(vec![SilentPaymentAddress::try_from( - alice_wallet.get_client().get_receiving_address(), + alice_wallet.get_receiving_address(), ) .unwrap()]); let clear_state_value = json!({"field1": "value1", "field2": "value2"}); @@ -802,7 +784,6 @@ mod tests { let new_state_merkle_root = commitments.create_merkle_tree().unwrap().root().unwrap(); let alice_spend_key: SecretKey = alice_wallet - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -823,8 +804,8 @@ mod tests { let bob_wallet = create_bob_wallet(); let members = get_members_map([ - alice_wallet.get_client().get_receiving_address(), - bob_wallet.get_client().get_receiving_address(), + alice_wallet.get_receiving_address().to_string(), + bob_wallet.get_receiving_address().to_string(), ]); let fields = vec!["field1".to_string(), "field2".to_string()]; let validation_rule1 = ValidationRule::new(1.0, vec![fields[0].clone()], 0.5).unwrap(); @@ -853,11 +834,10 @@ mod tests { let validation_hash = AnkValidationYesHash::from_merkle_root(new_state_merkle_root); let alice_spend_key: SecretKey = alice_wallet - .get_client() .get_spend_key() .try_into() .unwrap(); - let bob_spend_key: SecretKey = bob_wallet.get_client().get_spend_key().try_into().unwrap(); + let bob_spend_key: SecretKey = bob_wallet.get_spend_key().try_into().unwrap(); let alice_proof = Proof::new(AnkHash::ValidationYes(validation_hash), alice_spend_key); let bob_proof = Proof::new(AnkHash::ValidationYes(validation_hash), bob_spend_key); @@ -875,8 +855,8 @@ mod tests { let bob_wallet = create_bob_wallet(); let members_list = get_members_map([ - alice_wallet.get_client().get_receiving_address(), - bob_wallet.get_client().get_receiving_address() + alice_wallet.get_receiving_address().to_string(), + bob_wallet.get_receiving_address().to_string() ]); let fields = vec!["field1".to_string(), "field2".to_string()]; @@ -907,11 +887,10 @@ mod tests { let validation_hash = AnkValidationNoHash::from_merkle_root(new_state_merkle_root); let alice_spend_key: SecretKey = alice_wallet - .get_client() .get_spend_key() .try_into() .unwrap(); - let bob_spend_key: SecretKey = bob_wallet.get_client().get_spend_key().try_into().unwrap(); + let bob_spend_key: SecretKey = bob_wallet.get_spend_key().try_into().unwrap(); let alice_proof = Proof::new(AnkHash::ValidationNo(validation_hash), alice_spend_key); let bob_proof = Proof::new(AnkHash::ValidationNo(validation_hash), bob_spend_key); @@ -929,8 +908,8 @@ mod tests { let bob_wallet = create_bob_wallet(); let members = get_members_map([ - alice_wallet.get_client().get_receiving_address(), - bob_wallet.get_client().get_receiving_address(), + alice_wallet.get_receiving_address().to_string(), + bob_wallet.get_receiving_address().to_string(), ]); let fields = vec!["field1".to_string(), "field2".to_string()]; @@ -961,11 +940,10 @@ mod tests { // let validation_hash = AnkValidationNoHash::from_merkle_root(new_state_merkle_root); let alice_spend_key: SecretKey = alice_wallet - .get_client() .get_spend_key() .try_into() .unwrap(); - let bob_spend_key: SecretKey = bob_wallet.get_client().get_spend_key().try_into().unwrap(); + let bob_spend_key: SecretKey = bob_wallet.get_spend_key().try_into().unwrap(); let alice_proof = Proof::new(AnkHash::ValidationYes(validation_hash), alice_spend_key); let bob_proof = Proof::new(AnkHash::ValidationYes(validation_hash), bob_spend_key); @@ -983,8 +961,8 @@ mod tests { let bob_wallet = create_bob_wallet(); let members = get_members_map([ - alice_wallet.get_client().get_receiving_address(), - bob_wallet.get_client().get_receiving_address(), + alice_wallet.get_receiving_address().to_string(), + bob_wallet.get_receiving_address().to_string(), ]); let fields = vec!["field1".to_string(), "field2".to_string()]; @@ -1015,7 +993,6 @@ mod tests { // let validation_hash = AnkValidationNoHash::from_merkle_root(new_state_merkle_root); let alice_spend_key: SecretKey = alice_wallet - .get_client() .get_spend_key() .try_into() .unwrap(); diff --git a/src/prd.rs b/src/prd.rs index a4fc06f..55e08cb 100644 --- a/src/prd.rs +++ b/src/prd.rs @@ -7,8 +7,8 @@ use serde_json::{Map, Value}; use sp_client::bitcoin::hashes::{sha256t_hash_newtype, Hash, HashEngine}; use sp_client::bitcoin::secp256k1::{PublicKey, SecretKey}; use sp_client::bitcoin::OutPoint; -use sp_client::silentpayments::utils::SilentPaymentAddress; -use sp_client::spclient::SpWallet; +use sp_client::silentpayments::SilentPaymentAddress; +use sp_client::SpClient; use tsify::Tsify; use crate::pcd::{Member, Pcd, PcdCommitments, Roles}; @@ -198,8 +198,8 @@ impl Prd { } /// Generate the signed proof and serialize to send over the network - pub fn to_network_msg(&self, sp_wallet: &SpWallet) -> Result { - let spend_sk: SecretKey = sp_wallet.get_client().get_spend_key().try_into()?; + pub fn to_network_msg(&self, sp_wallet: &SpClient) -> Result { + let spend_sk: SecretKey = sp_wallet.get_spend_key().try_into()?; let mut to_sign = self.clone(); // we sign the whole prd, incl the keys, for each recipient let message_hash = diff --git a/src/process.rs b/src/process.rs index b74a2a9..95448aa 100644 --- a/src/process.rs +++ b/src/process.rs @@ -4,7 +4,7 @@ use std::{ use serde::{Deserialize, Serialize}; use serde_json::Value; -use sp_client::{bitcoin::{OutPoint, Transaction}, silentpayments::utils::SilentPaymentAddress}; +use sp_client::{bitcoin::{OutPoint, Transaction}, silentpayments::SilentPaymentAddress}; use tsify::Tsify; use crate::{ @@ -561,7 +561,9 @@ mod tests { use serde_json::json; use sp_client::{ - bitcoin::{secp256k1::SecretKey, Network, Txid}, silentpayments::utils::SilentPaymentAddress, spclient::{SpClient, SpWallet, SpendKey} + bitcoin::{secp256k1::SecretKey, Network, Txid}, + silentpayments::SilentPaymentAddress, + SpClient, SpendKey }; use crate::pcd::{Member, ValidationRule}; @@ -572,98 +574,70 @@ mod tests { const CAROL_PAIRING: &str = "a4f3d2d5ca7af258e6a2c1cfe85b85d4e3f3d1387417fd64012d3c7bfb95a9e9:0"; const DAVE_PAIRING: &str = "bd21f6acdd0e026e8c02298a51ec40dfaced34d95aec685f407ab5ac91b5f775:0"; - fn create_alice_wallet() -> SpWallet { - SpWallet::new( - SpClient::new( - "default".to_owned(), - SecretKey::from_str( - "a67fb6bf5639efd0aeb19c1c584dd658bceda87660ef1088d4a29d2e77846973", - ) - .unwrap(), - SpendKey::Secret( - SecretKey::from_str( - "a1e4e7947accf33567e716c9f4d186f26398660e36cf6d2e711af64b3518e65c", - ) - .unwrap(), - ), - None, - Network::Signet, + fn create_alice_wallet() -> SpClient { + SpClient::new( + SecretKey::from_str( + "a67fb6bf5639efd0aeb19c1c584dd658bceda87660ef1088d4a29d2e77846973", ) .unwrap(), - None, - vec![], + SpendKey::Secret( + SecretKey::from_str( + "a1e4e7947accf33567e716c9f4d186f26398660e36cf6d2e711af64b3518e65c", + ) + .unwrap(), + ), + Network::Signet, ) .unwrap() } - fn create_bob_wallet() -> SpWallet { - SpWallet::new( - SpClient::new( - "default".to_owned(), - SecretKey::from_str( - "4d9f62b2340de3f0bafd671b78b19edcfded918c4106baefd34512f12f520e9b", - ) - .unwrap(), - SpendKey::Secret( - SecretKey::from_str( - "dafb99602721577997a6fe3da54f86fd113b1b58f0c9a04783d486f87083a32e", - ) - .unwrap(), - ), - None, - Network::Signet, + fn create_bob_wallet() -> SpClient { + SpClient::new( + SecretKey::from_str( + "4d9f62b2340de3f0bafd671b78b19edcfded918c4106baefd34512f12f520e9b", ) .unwrap(), - None, - vec![], + SpendKey::Secret( + SecretKey::from_str( + "dafb99602721577997a6fe3da54f86fd113b1b58f0c9a04783d486f87083a32e", + ) + .unwrap(), + ), + Network::Signet, ) .unwrap() } - fn create_carol_wallet() -> SpWallet { - SpWallet::new( - SpClient::new( - "default".to_owned(), - SecretKey::from_str( - "e4a5906eaa1a7ab24d5fc8d9b600d47f79caa6511c056c111677b7a33e62c5e9", - ) - .unwrap(), - SpendKey::Secret( - SecretKey::from_str( - "e4c282e14668af1435e39df78403a7b406a791e3c6e666295496a6a865ade162", - ) - .unwrap(), - ), - None, - Network::Signet, + fn create_carol_wallet() -> SpClient { + SpClient::new( + SecretKey::from_str( + "e4a5906eaa1a7ab24d5fc8d9b600d47f79caa6511c056c111677b7a33e62c5e9", ) .unwrap(), - None, - vec![], + SpendKey::Secret( + SecretKey::from_str( + "e4c282e14668af1435e39df78403a7b406a791e3c6e666295496a6a865ade162", + ) + .unwrap(), + ), + Network::Signet, ) .unwrap() } - fn create_dave_wallet() -> SpWallet { - SpWallet::new( - SpClient::new( - "default".to_owned(), - SecretKey::from_str( - "261d5f9ae4d2b0d8b17ed0c52bd2be7dbce14d9ac1f0f1d4904d3ca7df03766d", - ) - .unwrap(), - SpendKey::Secret( - SecretKey::from_str( - "8441e2adbb39736f384617fafc61e0d894bf3a5c2b69801fd4476bdcce04fb59", - ) - .unwrap(), - ), - None, - Network::Signet, + fn create_dave_wallet() -> SpClient { + SpClient::new( + SecretKey::from_str( + "261d5f9ae4d2b0d8b17ed0c52bd2be7dbce14d9ac1f0f1d4904d3ca7df03766d", ) .unwrap(), - None, - vec![], + SpendKey::Secret( + SecretKey::from_str( + "8441e2adbb39736f384617fafc61e0d894bf3a5c2b69801fd4476bdcce04fb59", + ) + .unwrap(), + ), + Network::Signet, ) .unwrap() } @@ -675,16 +649,16 @@ mod tests { let dave_wallet = create_dave_wallet(); let alice_address = - SilentPaymentAddress::try_from(alice_wallet.get_client().get_receiving_address()) + SilentPaymentAddress::try_from(alice_wallet.get_receiving_address()) .unwrap(); let bob_address = - SilentPaymentAddress::try_from(bob_wallet.get_client().get_receiving_address()) + SilentPaymentAddress::try_from(bob_wallet.get_receiving_address()) .unwrap(); let carol_address = - SilentPaymentAddress::try_from(carol_wallet.get_client().get_receiving_address()) + SilentPaymentAddress::try_from(carol_wallet.get_receiving_address()) .unwrap(); let dave_address = - SilentPaymentAddress::try_from(dave_wallet.get_client().get_receiving_address()) + SilentPaymentAddress::try_from(dave_wallet.get_receiving_address()) .unwrap(); let members_map: HashMap = HashMap::from([ @@ -758,7 +732,7 @@ mod tests { fn create_pairing_process_one() -> ProcessState { let carol_wallet = create_carol_wallet(); - let carol_address = carol_wallet.get_client().get_receiving_address(); + let carol_address = carol_wallet.get_receiving_address(); let pairing_rule = ValidationRule::new(1.0, vec![PAIREDADDRESSES.to_owned()], 1.0).unwrap(); let pairing_role_def = RoleDefinition { @@ -771,16 +745,16 @@ mod tests { let private_data = BTreeMap::from([("description".to_owned(), Value::String("pairing".to_owned()))]); - let paired_addresses = Value::Array(vec![carol_address.try_into().unwrap()]); + let paired_addresses = Value::Array(vec![Value::String(carol_address.to_string())]); ProcessState::new(outpoint, Pcd::new(private_data), Pcd::new(BTreeMap::from([(PAIREDADDRESSES.to_owned(), paired_addresses)])), Roles::new(BTreeMap::from([(PAIRING.to_owned(), pairing_role_def)]))).unwrap() } fn create_pairing_process_two() -> ProcessState { let carol_wallet = create_carol_wallet(); - let carol_address = carol_wallet.get_client().get_receiving_address(); + let carol_address = carol_wallet.get_receiving_address(); let dave_wallet = create_dave_wallet(); - let dave_address = dave_wallet.get_client().get_receiving_address(); + let dave_address = dave_wallet.get_receiving_address(); let pairing_rule = ValidationRule::new(1.0, vec![PAIREDADDRESSES.to_owned()], 1.0).unwrap(); let pairing_role_def = RoleDefinition { @@ -794,8 +768,8 @@ mod tests { let private_data = BTreeMap::from([("description".to_owned(), Value::String("pairing".to_owned()))]); let paired_addresses = Value::Array(vec![ - carol_address.try_into().unwrap(), - dave_address.try_into().unwrap() + Value::String(carol_address.to_string()), + Value::String(dave_address.to_string()) ]); ProcessState::new(outpoint, Pcd::new(private_data), Pcd::new(BTreeMap::from([(PAIREDADDRESSES.to_owned(), paired_addresses)])), Roles::new(BTreeMap::from([(PAIRING.to_owned(), pairing_role_def)]))).unwrap() @@ -834,7 +808,6 @@ mod tests { let mut state = dummy_process_state(); // We sign with Carol key let carol_key: SecretKey = create_carol_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -851,12 +824,10 @@ mod tests { let mut state = dummy_process_state(); // We sign with Alice and Carol keys let alice_key: SecretKey = create_alice_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); let carol_key: SecretKey = create_carol_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -871,7 +842,6 @@ mod tests { fn test_valid_pairing() { let mut pairing_first_state = create_pairing_process_one(); let carol_key: SecretKey = create_carol_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -885,7 +855,6 @@ mod tests { fn test_error_pairing_wrong_proof() { let mut pairing_first_state = create_pairing_process_one(); let alice_key: SecretKey = create_alice_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -915,14 +884,13 @@ mod tests { ); // Add Dave address - let dave_address = create_dave_wallet().get_client().get_receiving_address(); - paired_addresses.as_array_mut().unwrap().push(Value::String(dave_address)); + let dave_address = create_dave_wallet().get_receiving_address(); + paired_addresses.as_array_mut().unwrap().push(Value::String(dave_address.to_string())); let roles = &pairing_process.get_latest_commited_state().unwrap().roles; let mut add_device_state = ProcessState::new(new_commitment, Pcd::new(BTreeMap::new()), Pcd::new(BTreeMap::from([(PAIREDADDRESSES.to_owned(), paired_addresses)])), roles.clone()).unwrap(); let carol_key: SecretKey = create_carol_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -953,10 +921,10 @@ mod tests { ); // Remove Dave address - let dave_address = create_dave_wallet().get_client().get_receiving_address(); + let dave_address = create_dave_wallet().get_receiving_address(); let paired_addresses = extract_paired_addresses(&paired_addresses).unwrap(); let filtered_paired_addresses = Value::from_iter(paired_addresses.into_iter().filter_map(|a| { - if a.to_string() != dave_address { + if a != dave_address { Some(a.to_string()) } else { None @@ -976,12 +944,10 @@ mod tests { // We need both devices to agree to remove one let carol_key: SecretKey = create_carol_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); let dave_key: SecretKey = create_dave_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -1014,14 +980,13 @@ mod tests { ); // Add Dave address - let dave_address = create_dave_wallet().get_client().get_receiving_address(); - paired_addresses.as_array_mut().unwrap().push(Value::String(dave_address)); + let dave_address = create_dave_wallet().get_receiving_address(); + paired_addresses.as_array_mut().unwrap().push(Value::String(dave_address.to_string())); let roles = &pairing_process.get_latest_commited_state().unwrap().roles; let mut add_device_state = ProcessState::new(new_commitment, Pcd::new(BTreeMap::new()), Pcd::new(BTreeMap::from([(PAIREDADDRESSES.to_owned(), paired_addresses)])), roles.clone()).unwrap(); let dave_key: SecretKey = create_dave_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -1037,17 +1002,14 @@ mod tests { fn test_valid_all_signatures() { let mut state = dummy_process_state(); let alice_key: SecretKey = create_alice_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); let bob_key: SecretKey = create_bob_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); let carol_key: SecretKey = create_carol_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -1077,7 +1039,6 @@ mod tests { // Now we take the last empty state and try to invalidate it let empty_state = process.get_state_for_id(&[0u8; 32]).unwrap(); let carol_key: SecretKey = create_carol_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -1105,7 +1066,6 @@ mod tests { // Now we take the last empty state and try to commit it to invalidate the whole process let empty_state = process.get_state_for_id_mut(&[0u8; 32]).unwrap(); let dave_key: SecretKey = create_dave_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -1120,17 +1080,14 @@ mod tests { fn test_error_carol_votes_no() { let mut state = dummy_process_state(); let alice_key: SecretKey = create_alice_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); let bob_key: SecretKey = create_bob_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); let carol_key: SecretKey = create_carol_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -1149,17 +1106,14 @@ mod tests { fn test_valid_bob_votes_no() { let mut state = dummy_process_state(); let alice_key: SecretKey = create_alice_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); let bob_key: SecretKey = create_bob_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); let carol_key: SecretKey = create_carol_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -1180,17 +1134,14 @@ mod tests { let key_to_modify = state.pcd_commitment.keys().into_iter().next().unwrap(); new_state.update_value(key_to_modify.as_str(), &Value::String("new_value1".to_string())).unwrap(); let alice_key: SecretKey = create_alice_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); let bob_key: SecretKey = create_bob_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); let carol_key: SecretKey = create_carol_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -1210,7 +1161,6 @@ mod tests { let key_to_modify = state.pcd_commitment.keys().into_iter().next().unwrap(); new_state.update_value(key_to_modify.as_str(), &Value::String("new_value1".to_string())).unwrap(); let carol_key: SecretKey = create_carol_wallet() - .get_client() .get_spend_key() .try_into() .unwrap(); @@ -1219,4 +1169,46 @@ mod tests { let result = new_state.is_valid(Some(&state), &OutPointMemberMap(get_members_map())); assert!(result.is_err()); } + + #[test] + fn test_valid_add_someone_role() { + let mut state = dummy_process_state(); + if let Some(role) = state.roles.get_mut(APOPHIS) { + role.members = vec![]; + } + let mut process = Process::new(state.commited_in); + process.insert_concurrent_state(state).unwrap(); + process.update_states_tip( + OutPoint::new( + Txid::from_str( + "cbeb4455f8d11848809bacd59bfd570243dbe7c4e9a340fa949aae3020fdb127" + ).unwrap() + , 0 + ) + ).unwrap(); + // We now try to add dave into apophis role + let mut new_roles = process.get_latest_commited_state().unwrap().roles.clone(); + + if let Some(role) = new_roles.get_mut(APOPHIS) { + role.members = vec![OutPoint::from_str(DAVE_PAIRING).unwrap()]; + } + + let mut new_state = ProcessState::new(process.get_process_tip().unwrap(), Pcd::new(BTreeMap::new()), Pcd::new(BTreeMap::new()), new_roles).unwrap(); + + // Alice and Bob validate + let alice_key: SecretKey = create_alice_wallet() + .get_spend_key() + .try_into() + .unwrap(); + let bob_key: SecretKey = create_bob_wallet() + .get_spend_key() + .try_into() + .unwrap(); + + let message_hash = new_state.get_message_hash(true).unwrap(); + new_state.validation_tokens.push(Proof::new(message_hash, alice_key)); + new_state.validation_tokens.push(Proof::new(message_hash, bob_key)); + let result = new_state.is_valid(process.get_parent_state(&new_state.commited_in), &OutPointMemberMap(get_members_map())); + assert!(result.is_ok()); + } } diff --git a/src/secrets.rs b/src/secrets.rs index c376655..6484ded 100644 --- a/src/secrets.rs +++ b/src/secrets.rs @@ -3,9 +3,8 @@ use tsify::Tsify; use crate::aes_gcm::aead::{Aead, Payload}; use crate::aes_gcm::Nonce; use crate::sp_client::bitcoin::hashes::Hash; -use crate::sp_client::silentpayments::utils::SilentPaymentAddress; +use crate::sp_client::silentpayments::SilentPaymentAddress; use crate::crypto::{Aes256Gcm, AnkSharedSecretHash, KeyInit, AAD}; -use crate::log; use serde::ser::SerializeStruct; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::collections::HashMap; diff --git a/src/silentpayments.rs b/src/silentpayments.rs index 34889e2..935b2c5 100644 --- a/src/silentpayments.rs +++ b/src/silentpayments.rs @@ -1,31 +1,20 @@ use std::collections::{HashMap, HashSet}; -use std::str::FromStr; use anyhow::{Error, Result}; use rand::{thread_rng, Rng}; -use sp_client::bitcoin::consensus::deserialize; -use sp_client::bitcoin::psbt::raw; -use sp_client::bitcoin::{Amount, OutPoint, Psbt}; -use sp_client::constants::{ - self, DUST_THRESHOLD, PSBT_SP_ADDRESS_KEY, PSBT_SP_PREFIX, PSBT_SP_SUBTYPE, -}; -use sp_client::silentpayments::utils::SilentPaymentAddress; -use sp_client::spclient::{OwnedOutput, Recipient, SpClient, SpWallet}; +use sp_client::bitcoin::{Amount, OutPoint, Transaction}; +use sp_client::{OwnedOutput, Recipient, SilentPaymentUnsignedTransaction, SpClient}; pub fn create_transaction( mandatory_inputs: Vec, + mut available_outpoints: HashMap, freezed_utxos: &HashSet, - sp_wallet: &SpWallet, + sp_client: &SpClient, mut recipients: Vec, payload: Option>, fee_rate: Amount, - fee_payer: Option, // None means sender pays everything -) -> Result { - let mut available_outpoints: HashMap = sp_wallet - .get_outputs() - .to_spendable_list(); - +) -> Result { let sum_outputs = recipients .iter() .fold(Amount::from_sat(0), |acc, x| acc + x.amount); @@ -46,13 +35,13 @@ pub fn create_transaction( let fee_provision = Amount::from_sat(1000); - for (outpoint, output) in available_outpoints { - if freezed_utxos.contains(&outpoint) { continue } + for (outpoint, output) in &available_outpoints { + if freezed_utxos.contains(outpoint) { continue } if total_available > sum_outputs.checked_add(fee_provision).unwrap() { break; } total_available += output.amount; - inputs.insert(outpoint, output); + inputs.insert(*outpoint, output.clone()); } if total_available <= sum_outputs.checked_add(fee_provision).unwrap() { @@ -71,91 +60,22 @@ pub fn create_transaction( thread_rng().fill(&mut commitment); } - let mut new_psbt = - sp_wallet - .get_client() - .create_new_psbt(inputs, recipients, Some(&commitment))?; + let new_transaction = sp_client.create_new_transaction( + available_outpoints.into_iter().collect(), + recipients, + fee_rate.to_btc() as f32, + sp_client.get_network() + )?; - let sender_address = sp_wallet.get_client().get_receiving_address(); - let change_address = sp_wallet.get_client().sp_receiver.get_change_address(); - if let Some(address) = fee_payer { - SpClient::set_fees(&mut new_psbt, fee_rate, address)?; - } else { - let candidates: Vec> = new_psbt - .outputs - .iter() - .map(|o| { - if let Some(value) = o.proprietary.get(&raw::ProprietaryKey { - prefix: PSBT_SP_PREFIX.as_bytes().to_vec(), - subtype: PSBT_SP_SUBTYPE, - key: PSBT_SP_ADDRESS_KEY.as_bytes().to_vec(), - }) { - let candidate: String = - SilentPaymentAddress::try_from(deserialize::(value).unwrap()) - .unwrap() - .into(); - return Some(candidate); - } else { - return None; - } - }) - .collect(); + let finalized_transaction = SpClient::finalize_transaction(new_transaction)?; - let fee_set = candidates.iter().filter_map(|candidate_opt| { - candidate_opt.as_ref().and_then(|c| { - if *c == change_address { - Some(SpClient::set_fees(&mut new_psbt, fee_rate, change_address.clone())) - } else if *c == sender_address { - Some(SpClient::set_fees(&mut new_psbt, fee_rate, sender_address.clone())) - } else { - None - } - }) - }).find_map(|result| result.ok()); - - if fee_set.is_none() { - return Err(Error::msg("Must specify payer for fee")); - } - }; - - let partial_secret = sp_wallet - .get_client() - .get_partial_secret_from_psbt(&new_psbt)?; - - sp_wallet - .get_client() - .fill_sp_outputs(&mut new_psbt, partial_secret)?; - let mut aux_rand = [0u8; 32]; - thread_rng().fill(&mut aux_rand); - let mut signed = sp_wallet.get_client().sign_psbt(new_psbt, &aux_rand)?; - SpClient::finalize_psbt(&mut signed)?; - - Ok(signed) + Ok(finalized_transaction) } -pub fn map_outputs_to_sp_address(psbt_str: &str) -> Result>> { - let psbt = Psbt::from_str(&psbt_str)?; - - let mut res: HashMap> = HashMap::new(); - for (i, output) in psbt.outputs.iter().enumerate() { - if let Some(value) = output.proprietary.get(&raw::ProprietaryKey { - prefix: constants::PSBT_SP_PREFIX.as_bytes().to_vec(), - subtype: constants::PSBT_SP_SUBTYPE, - key: constants::PSBT_SP_ADDRESS_KEY.as_bytes().to_vec(), - }) { - let sp_address = SilentPaymentAddress::try_from(deserialize::(value)?)?; - if let Some(vouts) = res.get_mut::(&sp_address.into()) { - vouts.push(i); - } else { - res.insert(sp_address.into(), vec![i]); - } - } else { - // Not a sp output - continue; - } - } - - Ok(res) +pub fn sign_transaction(sp_client: &SpClient, unsigned_transaction: SilentPaymentUnsignedTransaction) -> Result { + let mut aux_rand = [0u8; 32]; + thread_rng().fill(&mut aux_rand); + sp_client.sign_transaction(unsigned_transaction, &aux_rand) } // #[cfg(test)] @@ -215,8 +135,8 @@ pub fn map_outputs_to_sp_address(psbt_str: &str) -> Result Result Result