Add Process
This commit is contained in:
parent
d073b12340
commit
45628edb61
126
src/api.rs
126
src/api.rs
@ -14,6 +14,8 @@ use anyhow::Error as AnyhowError;
|
||||
use sdk_common::crypto::{
|
||||
AeadCore, Aes256Decryption, Aes256Encryption, Aes256Gcm, AnkSharedSecret, KeyInit, Purpose,
|
||||
};
|
||||
use sdk_common::device::{REVOKATION_INDEX, SESSION_INDEX};
|
||||
use sdk_common::process::{Member, PairingPcd, Process, Role, ValidationRules};
|
||||
use sdk_common::sp_client::bitcoin::blockdata::fee_rate;
|
||||
use sdk_common::sp_client::bitcoin::consensus::{deserialize, serialize};
|
||||
use sdk_common::sp_client::bitcoin::hashes::HashEngine;
|
||||
@ -47,20 +49,18 @@ use wasm_bindgen::convert::FromWasmAbi;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use sdk_common::network::{
|
||||
self, AnkFlag, CachedMessage, CachedMessageStatus, Envelope, FaucetMessage, NewTxMessage, Pcd, Prd
|
||||
self, AnkFlag, CachedMessage, CachedMessageStatus, Envelope, FaucetMessage, NewTxMessage, Pcd, Prd, PrdType
|
||||
};
|
||||
use sdk_common::silentpayments::{create_transaction, map_outputs_to_sp_address};
|
||||
|
||||
use crate::wallet::{generate_sp_wallet, lock_freezed_utxos};
|
||||
use sdk_common::sp_client::spclient::{
|
||||
derive_keys_from_seed, OutputList, OutputSpendStatus, OwnedOutput, Recipient, SpClient,
|
||||
};
|
||||
use sdk_common::sp_client::spclient::{SpWallet, SpendKey};
|
||||
use sdk_common::device::Device;
|
||||
|
||||
use crate::user::{lock_local_device, set_new_device, Device, LOCAL_DEVICE};
|
||||
use crate::user::{lock_local_device, set_new_device, LOCAL_DEVICE};
|
||||
use crate::{lock_messages, CACHEDMESSAGES};
|
||||
|
||||
use crate::process::Process;
|
||||
use crate::wallet::{generate_sp_wallet, lock_freezed_utxos};
|
||||
|
||||
pub type ApiResult<T: FromWasmAbi> = Result<T, ApiError>;
|
||||
|
||||
@ -218,7 +218,7 @@ pub fn create_new_device(birthday: u32, network_str: String) -> ApiResult<String
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn pair_device(message_id: u32, incoming_pairing_txid: String) -> ApiResult<()> {
|
||||
pub fn pair_device(nym: String, message_id: u32, incoming_pairing_txid: String) -> ApiResult<Process> {
|
||||
let mut local_device = lock_local_device()?;
|
||||
|
||||
// check that we're still in pairing phase
|
||||
@ -270,75 +270,25 @@ pub fn pair_device(message_id: u32, incoming_pairing_txid: String) -> ApiResult<
|
||||
)?;
|
||||
|
||||
message.status = CachedMessageStatus::Closed;
|
||||
|
||||
let pairing_pcd = PairingPcd::new(
|
||||
nym,
|
||||
local_device.get_wallet().get_client().get_receiving_address().try_into().unwrap(),
|
||||
local_device.get_paired_device_info().unwrap().address.try_into().unwrap(),
|
||||
SESSION_INDEX,
|
||||
REVOKATION_INDEX,
|
||||
Txid::from_str(&incoming_pairing_txid)?,
|
||||
pairing_tx.txid
|
||||
);
|
||||
|
||||
let pairing_process = Process::new_pairing_process(pairing_pcd, pairing_tx.txid);
|
||||
|
||||
Ok(pairing_process)
|
||||
} else {
|
||||
return Err(ApiError {
|
||||
message: format!("Can't find message with id {}", message_id),
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Tsify, Serialize, Deserialize)]
|
||||
#[tsify(into_wasm_abi)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct get_process_return(Vec<Process>);
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn get_processes() -> ApiResult<get_process_return> {
|
||||
let MEMBERS: [String;5] = [
|
||||
"tsp1qqdvmxycf3c3tf2qhpev0npx25rj05270d6j2pcsrfk2qn5gdy0rpwq6hd9u9sztl3fwmrzzqafzl3ymkq86aqfz5jl5egdkz72tqmhcnrswdz3pk".to_owned(),
|
||||
"tsp1qqwafwn7dcr9d6ta0w8fjtd9s53u72x9qmmtgd8adqr7454xl90a5jq3vw23l2x8ypt55nrg7trl9lwz5xr5j357ucu4sf9rfmvc0zujcpqcps6rm".to_owned(),
|
||||
"tsp1qqw02t5hmg5rxpjdkmjdnnmhvuc76wt6vlqdmn2zafnh6axxjd6e2gqcz04gzvnkzf572mur8spyx2a2s8sqzll2ymdpyz59cpl96j4zuvcdvrzxz".to_owned(),
|
||||
"tsp1qqgpay2r5jswm7vcv24xd94shdf90w30vxtql9svw7qnlnrzd6xt02q7s7z57uw0sssh6c0xddcrryq4mxup93jsh3gfau3autrawl8umkgsyupkm".to_owned(),
|
||||
"tsp1qqtsqmtgnxp0lsmnxyxcq52zpgxwugwlq8urlprs5pr5lwyqc789gjqhx5qra6g4rszsq43pms6nguee2l9trx905rk5sgntek05hnf7say4ru69y".to_owned(),
|
||||
];
|
||||
//instances of process
|
||||
let process1 = Process {
|
||||
id: 6,
|
||||
name: String::from("Messaging"),
|
||||
version: String::from("1.0"),
|
||||
members: MEMBERS.to_vec(),
|
||||
html: crate::process::HTML_MESSAGING.to_owned(),
|
||||
style: crate::process::CSS.to_owned(),
|
||||
script: "".to_owned(),
|
||||
};
|
||||
let process2 = Process {
|
||||
id: 7,
|
||||
name: String::from("Kotpart"),
|
||||
version: String::from("1.0"),
|
||||
members: MEMBERS.to_vec(),
|
||||
html: crate::process::HTML_MESSAGING.to_owned(),
|
||||
style: crate::process::CSS.to_owned(),
|
||||
script: "".to_owned(),
|
||||
};
|
||||
let process3 = Process {
|
||||
id: 8,
|
||||
name: String::from("Storage"),
|
||||
version: String::from("1.0"),
|
||||
members: MEMBERS.to_vec(),
|
||||
html: crate::process::HTML_MESSAGING.to_owned(),
|
||||
style: crate::process::CSS.to_owned(),
|
||||
script: "".to_owned(),
|
||||
};
|
||||
|
||||
// vec with the instances of processes
|
||||
let mut data_process: Vec<Process> = Vec::new();
|
||||
data_process.push(process1);
|
||||
data_process.push(process2);
|
||||
data_process.push(process3);
|
||||
Ok(get_process_return(data_process))
|
||||
}
|
||||
|
||||
#[derive(Debug, Tsify, Serialize, Deserialize)]
|
||||
#[tsify(from_wasm_abi)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct recover_data(Vec<u8>);
|
||||
|
||||
impl recover_data {
|
||||
fn as_inner(&self) -> &[u8] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Tsify, Serialize, Deserialize)]
|
||||
@ -728,6 +678,7 @@ pub fn parse_cipher(cipher_msg: String, fee_rate: u32) -> ApiResult<CachedMessag
|
||||
message: "Prd doesn't match commitment".to_owned(),
|
||||
});
|
||||
}
|
||||
message.prd_type = prd.prd_type.clone();
|
||||
message.sender = Some(prd.sender.clone());
|
||||
message.pcd_commitment = Some(prd.pcd_commitment.to_string());
|
||||
message.prd_cipher = None;
|
||||
@ -957,7 +908,20 @@ pub fn create_login_transaction(fee_rate: u32) -> ApiResult<createTransactionRet
|
||||
|
||||
let key: [u8; 32] = Aes256Gcm::generate_key(thread_rng()).into();
|
||||
|
||||
let process = Process::new(
|
||||
"empty".to_owned(),
|
||||
vec![],
|
||||
ValidationRules::new(0.0, Role::User),
|
||||
Txid::all_zeros(),
|
||||
String::default(),
|
||||
String::default(),
|
||||
String::default(),
|
||||
Value::Null
|
||||
);
|
||||
|
||||
let prd = Prd::new(
|
||||
PrdType::Message,
|
||||
process,
|
||||
local_device
|
||||
.get_wallet()
|
||||
.get_client()
|
||||
@ -966,7 +930,7 @@ pub fn create_login_transaction(fee_rate: u32) -> ApiResult<createTransactionRet
|
||||
.unwrap(),
|
||||
key,
|
||||
pcd_commitment,
|
||||
);
|
||||
)?;
|
||||
|
||||
let pcd_cipher = prd.encrypt_pcd(&pcd)?;
|
||||
|
||||
@ -1056,7 +1020,18 @@ pub fn create_pairing_transaction(
|
||||
|
||||
let pcd = Pcd::new("PAIRING".to_owned());
|
||||
|
||||
let mut res = create_notification_transaction(address, pcd, fee_rate)?;
|
||||
let process = Process::new(
|
||||
"empty".to_owned(),
|
||||
vec![],
|
||||
ValidationRules::new(0.0, Role::User),
|
||||
Txid::all_zeros(),
|
||||
String::default(),
|
||||
String::default(),
|
||||
String::default(),
|
||||
Value::Null
|
||||
);
|
||||
|
||||
let mut res = create_notification_transaction(address, process, pcd, fee_rate)?;
|
||||
|
||||
let mut messages = lock_messages()?;
|
||||
|
||||
@ -1073,6 +1048,7 @@ pub fn create_pairing_transaction(
|
||||
#[wasm_bindgen]
|
||||
pub fn create_notification_transaction(
|
||||
address: String,
|
||||
process: Process,
|
||||
pcd: Pcd,
|
||||
fee_rate: u32,
|
||||
) -> ApiResult<createTransactionReturn> {
|
||||
@ -1093,10 +1069,12 @@ pub fn create_notification_transaction(
|
||||
let key: [u8; 32] = Aes256Gcm::generate_key(thread_rng()).into();
|
||||
|
||||
let prd = Prd::new(
|
||||
PrdType::Message,
|
||||
process,
|
||||
sp_wallet.get_client().get_receiving_address().try_into().unwrap(),
|
||||
key,
|
||||
pcd_commitment
|
||||
);
|
||||
)?;
|
||||
|
||||
let prd_commitment = sha256sum(prd.to_string().as_bytes());
|
||||
|
||||
|
@ -10,7 +10,6 @@ use tsify::Tsify;
|
||||
|
||||
pub mod api;
|
||||
mod peers;
|
||||
mod process;
|
||||
mod user;
|
||||
mod wallet;
|
||||
|
||||
|
140
src/user.rs
140
src/user.rs
@ -25,6 +25,7 @@ use sdk_common::sp_client::bitcoin::secp256k1::constants::SECRET_KEY_SIZE;
|
||||
use sdk_common::sp_client::silentpayments::bitcoin_hashes::sha256;
|
||||
use sdk_common::sp_client::silentpayments::utils::{Network as SpNetwork, SilentPaymentAddress};
|
||||
use sdk_common::sp_client::spclient::{OutputList, SpWallet, SpendKey};
|
||||
use sdk_common::device::Device;
|
||||
|
||||
use crate::peers::Peer;
|
||||
use crate::wallet::generate_sp_wallet;
|
||||
@ -58,142 +59,3 @@ pub fn lock_local_device() -> Result<MutexGuard<'static, Device>> {
|
||||
.get_or_init(|| Mutex::new(Device::default()))
|
||||
.lock_anyhow()
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Default, Tsify)]
|
||||
#[tsify(into_wasm_abi, from_wasm_abi)]
|
||||
pub struct PairedDevice {
|
||||
pub address: String,
|
||||
pub outgoing_pairing_transaction: [u8; 32],
|
||||
pub revokation_index: u32,
|
||||
pub incoming_pairing_transaction: [u8; 32],
|
||||
pub current_remote_key: [u8; 32],
|
||||
pub current_session_outpoint: OutPoint, // This will be spend by remote device to notify us of next login
|
||||
pub current_session_revokation_outpoint: OutPoint, // remote device can revoke current session by spending this
|
||||
}
|
||||
|
||||
impl PairedDevice {
|
||||
pub fn new(address: SilentPaymentAddress, pairing_txid: Txid, revokation_index: u32) -> Self {
|
||||
let mut pairing_transaction_buf = [0u8; 32];
|
||||
pairing_transaction_buf.copy_from_slice(&serialize(&pairing_txid));
|
||||
|
||||
Self {
|
||||
address: address.into(),
|
||||
outgoing_pairing_transaction: pairing_transaction_buf,
|
||||
revokation_index,
|
||||
incoming_pairing_transaction: [0u8; 32],
|
||||
current_session_revokation_outpoint: OutPoint::default(),
|
||||
current_session_outpoint: OutPoint::default(),
|
||||
current_remote_key: [0u8; 32],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Default, Tsify)]
|
||||
#[tsify(into_wasm_abi, from_wasm_abi)]
|
||||
pub struct Device {
|
||||
sp_wallet: SpWallet,
|
||||
current_session_outpoint: OutPoint, // This is the notification output of incoming login tx
|
||||
current_session_key: [u8; 32],
|
||||
current_session_revokation_outpoint: OutPoint, // This is the revokation outpoint of outgoing login tx
|
||||
paired_device: Option<PairedDevice>,
|
||||
}
|
||||
|
||||
impl Device {
|
||||
pub fn new(sp_wallet: SpWallet) -> Self {
|
||||
Self {
|
||||
sp_wallet,
|
||||
current_session_outpoint: OutPoint::default(),
|
||||
current_session_key: [0u8; 32],
|
||||
current_session_revokation_outpoint: OutPoint::default(),
|
||||
paired_device: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_wallet(&self) -> &SpWallet {
|
||||
&self.sp_wallet
|
||||
}
|
||||
|
||||
pub fn get_mut_wallet(&mut self) -> &mut SpWallet {
|
||||
&mut self.sp_wallet
|
||||
}
|
||||
|
||||
pub fn is_linked(&self) -> bool {
|
||||
self.paired_device.is_some()
|
||||
}
|
||||
|
||||
pub fn is_pairing(&self) -> bool {
|
||||
self.current_session_key == [0u8; 32]
|
||||
}
|
||||
|
||||
pub fn get_paired_device_info(&self) -> Option<PairedDevice> {
|
||||
self.paired_device.clone()
|
||||
}
|
||||
|
||||
pub fn get_next_output_to_spend(&self) -> OutPoint {
|
||||
self.current_session_outpoint
|
||||
}
|
||||
|
||||
pub fn get_session_revokation_outpoint(&self) -> OutPoint {
|
||||
self.current_session_revokation_outpoint
|
||||
}
|
||||
|
||||
pub fn sign_with_current_session_key(&self) -> Result<()> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn encrypt_with_current_session_key(&self) -> Result<()> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
pub fn new_link(
|
||||
&mut self,
|
||||
link_with: SilentPaymentAddress,
|
||||
outgoing_pairing_tx: Txid,
|
||||
revokation_output: u32,
|
||||
incoming_pairing_tx: Txid,
|
||||
) -> Result<()> {
|
||||
let address_looked_for: String = link_with.into();
|
||||
if let Some(paired_device) = self.paired_device.as_ref() {
|
||||
return Err(Error::msg(format!(
|
||||
"Found an already paired device with address {} and revokable by {}:{}",
|
||||
paired_device.address,
|
||||
Txid::from_byte_array(paired_device.outgoing_pairing_transaction),
|
||||
paired_device.revokation_index
|
||||
)));
|
||||
} else {
|
||||
let mut new_device =
|
||||
PairedDevice::new(link_with, outgoing_pairing_tx, revokation_output);
|
||||
new_device.incoming_pairing_transaction = incoming_pairing_tx.to_byte_array();
|
||||
self.paired_device = Some(new_device);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// We call that when we spent to the remote device and it similarly spent to us
|
||||
pub fn update_session(
|
||||
&mut self,
|
||||
new_session_key: SecretKey,
|
||||
new_session_outpoint: OutPoint,
|
||||
new_revokation_outpoint: OutPoint,
|
||||
new_remote_key: XOnlyPublicKey,
|
||||
new_remote_session_outpoint: OutPoint,
|
||||
new_remote_revokation_outpoint: OutPoint,
|
||||
) -> Result<()> {
|
||||
if !self.is_linked() {
|
||||
return Err(Error::msg("Can't update an unpaired device"));
|
||||
}
|
||||
self.paired_device
|
||||
.as_mut()
|
||||
.map(|d| {
|
||||
d.current_remote_key = new_remote_key.serialize();
|
||||
d.current_session_outpoint = new_remote_session_outpoint;
|
||||
d.current_session_revokation_outpoint = new_remote_revokation_outpoint;
|
||||
});
|
||||
self.current_session_key = new_session_key.secret_bytes();
|
||||
self.current_session_outpoint = new_session_outpoint;
|
||||
self.current_session_revokation_outpoint = new_revokation_outpoint;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,13 @@ fn test_pairing() {
|
||||
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();
|
||||
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();
|
||||
@ -95,7 +101,7 @@ fn test_pairing() {
|
||||
assert!(bob_pairing_msg.status == CachedMessageStatus::Pairing);
|
||||
|
||||
debug!("Alice pairs device");
|
||||
pair_device(alice_msg_id, bob_pairing_tx.txid).unwrap();
|
||||
pair_device(DEFAULT_NYM.to_owned(), alice_msg_id, bob_pairing_tx.txid).unwrap();
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
|
18
tests/prd.rs
18
tests/prd.rs
@ -7,9 +7,12 @@ use sdk_client::api::{
|
||||
use sdk_common::network::{
|
||||
CachedMessage, CachedMessageStatus, Pcd
|
||||
};
|
||||
use sdk_common::sp_client::bitcoin::OutPoint;
|
||||
use sdk_common::process::{Process, Role, ValidationRules};
|
||||
use sdk_common::sp_client::bitcoin::hashes::Hash;
|
||||
use sdk_common::sp_client::bitcoin::{OutPoint, Txid};
|
||||
use sdk_common::sp_client::spclient::OwnedOutput;
|
||||
|
||||
use serde_json::Value;
|
||||
use tsify::JsValueSerdeExt;
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
@ -32,8 +35,19 @@ fn test_alice_sends_prd_message_to_bob() {
|
||||
let pcd = Pcd::new("TEST".to_owned());
|
||||
debug!("Alice notified Bob about a message it sent");
|
||||
|
||||
let empty_process = Process::new(
|
||||
"empty".to_owned(),
|
||||
vec![],
|
||||
ValidationRules::new(0.0, Role::User),
|
||||
Txid::all_zeros(),
|
||||
String::default(),
|
||||
String::default(),
|
||||
String::default(),
|
||||
Value::Null
|
||||
);
|
||||
|
||||
let notification_tx =
|
||||
create_notification_transaction(helper_get_bob_address(), pcd, 1).unwrap();
|
||||
create_notification_transaction(helper_get_bob_address(), empty_process, pcd, 1).unwrap();
|
||||
|
||||
let get_outputs_result = get_outputs().unwrap();
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user