diff --git a/src/process.rs b/src/process.rs index 2ad347b..b785313 100644 --- a/src/process.rs +++ b/src/process.rs @@ -1,40 +1,86 @@ -use std::collections::HashMap; - -use anyhow::{Error, Result}; +use std::{collections::HashMap, sync::{Mutex, MutexGuard, OnceLock}}; use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; -use sp_client::bitcoin::OutPoint; -use tsify::Tsify; -use uuid::Uuid; -use wasm_bindgen::prelude::*; +use sp_client::{bitcoin::OutPoint, silentpayments::utils::SilentPaymentAddress}; -#[derive(Debug, Clone, Serialize, Deserialize, Tsify)] -#[tsify(into_wasm_abi, from_wasm_abi)] -pub struct Process { - pub uuid: String, - pub html: String, - pub style: String, - pub script: String, - pub init_state: Map, +use crate::{crypto::AnkSharedSecretHash, prd::Prd, signature::Proof, MutexExt}; + +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] +pub struct ProcessState { pub commited_in: OutPoint, + pub encrypted_pcd: Value, // Some fields may be clear, if the owner of the process decides so + pub keys: Map, // We may not always have all the keys + pub validation_token: Vec, // This signs the encrypted pcd +} + +/// A process is basically a succession of states +/// If a process has nothing to do with us, shared_secrets and impending_requests will be empty +#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] +pub struct Process { + states: Vec, + shared_secrets: HashMap, + impending_requests: Vec, } impl Process { - pub fn new( - html: String, - style: String, - script: String, - init_state: Map, - commited_in: OutPoint, - ) -> Self { + pub fn new(states: Vec, shared_secrets: HashMap, impending_requests: Vec) -> Self { Self { - uuid: Uuid::new_v4().to_string(), - html, - style, - script, - init_state, - commited_in, + states, + shared_secrets: shared_secrets.into_iter().map(|(k, v)| (k.to_string(), v)).collect(), + impending_requests, } } + + pub fn insert_shared_secret(&mut self, address: SilentPaymentAddress, secret: AnkSharedSecretHash) { + self.shared_secrets.insert(address.to_string(), secret); + } + + pub fn get_shared_secret_for_address(&self, address: &SilentPaymentAddress) -> Option { + self.shared_secrets.get(&address.to_string()).cloned() + } + + pub fn get_all_secrets(&self) -> HashMap { + self.shared_secrets.clone().into_iter().map(|(k, v)| (SilentPaymentAddress::try_from(k.as_str()).unwrap(), v)).collect() + } + + pub fn insert_state(&mut self, state: ProcessState) { + self.states.push(state); + } + + pub fn get_status_at(&self, index: usize) -> Option<&ProcessState> { + self.states.get(index) + } + + pub fn get_status_at_mut(&mut self, index: usize) -> Option<&mut ProcessState> { + self.states.get_mut(index) + } + + pub fn get_latest_state(&self) -> Option<&ProcessState> { + self.states.last() + } + + pub fn get_latest_state_mut(&mut self) -> Option<&mut ProcessState> { + self.states.last_mut() + } + + pub fn insert_impending_request(&mut self, request: Prd) { + self.impending_requests.push(request); + } + + pub fn get_impending_requests(&self) -> Vec<&Prd> { + self.impending_requests.iter().collect() + } + + pub fn get_impending_requests_mut(&mut self) -> Vec<&mut Prd> { + self.impending_requests.iter_mut().collect() + } +} + +pub static CACHEDPROCESSES: OnceLock>> = OnceLock::new(); + +pub fn lock_processes() -> Result>, anyhow::Error> { + CACHEDPROCESSES + .get_or_init(|| Mutex::new(HashMap::new())) + .lock_anyhow() }