Move CachedMessage here from sdk_client

This commit is contained in:
Sosthene 2024-05-22 20:52:48 +02:00
parent 9fe3e7b499
commit 87ee8ac40c

View File

@ -1,13 +1,13 @@
use anyhow::{Error, Result};
use rand::{thread_rng, RngCore};
use serde::{Deserialize, Serialize};
use sp_client::bitcoin::hex::DisplayHex;
use sp_client::bitcoin::hex::{DisplayHex, FromHex};
use sp_client::bitcoin::key::constants::ZERO;
use sp_client::bitcoin::OutPoint;
use sp_client::silentpayments::bitcoin_hashes::{sha256t_hash_newtype, Hash, HashEngine};
use tsify::Tsify;
use crate::crypto::CipherText;
use crate::crypto::{Aes256Decryption, CipherText, Purpose};
const RAWTXTOPIC: &'static str = "rawtx";
const RAWBLOCKTOPIC: &'static str = "rawblock";
@ -238,24 +238,6 @@ pub struct AnkNetworkMsg {
pub content: String,
}
// impl TryFrom<&str> for AnkNetworkMsg {
// type Error = anyhow::Error;
// fn try_from(value: &str) -> std::prelude::v1::Result<Self, Self::Error> {
// let parsed: Value = serde_json::from_str(value)?;
// let flag = parsed
// .get("flag")
// .ok_or(Error::msg("Invalid AnkNetworkMsg"))?
// .as_str()
// .ok_or(Error::msg("Invalid AnkNetworkMsg"))?;
// let content = parsed
// .get("content")
// .ok_or(Error::msg("Invalid AnkNetworkMsg"))?
// .as_str()
// .ok_or(Error::msg("Invalid AnkNetworkMsg"))?;
// Ok(Self { flag: flag.into(), content: content.into() })
// }
// }
impl AnkNetworkMsg {
pub fn new(flag: AnkFlag, raw: &str) -> Self {
Self {
@ -264,3 +246,95 @@ impl AnkNetworkMsg {
}
}
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Tsify, Clone)]
pub enum CachedMessageStatus {
NoStatus, // Default
FaucetWaiting,
FaucetComplete,
CipherWaitingTx,
TxWaitingCipher,
SentWaitingConfirmation,
MustSpendConfirmation,
Complete,
}
impl Default for CachedMessageStatus {
fn default() -> Self {
Self::NoStatus
}
}
/// Unique struct for both 3nk messages and notification/key exchange, both rust and ts
/// 0. Faucet: commited_in with nothing else, status is NoStatus
/// 1. notification:
/// 0. sender: ciphertext, plaintext, commited_in, sender, recipient, shared_secret, key
/// 1. receiver (without tx): ciphertext
/// 2. receiver (tx without msg): commited_in, commitment, recipient, shared_secret
/// 3. receiver (receive tx after msg): plaintext, key, sender, commited_in, commitment, recipient, shared_secret
/// 4. receiver (msg after tx): ciphertext, key, plaintext, sender
/// 2. confirmation:
/// 0. receiver (spend the smallest vout that pays him in the first tx): confirmed_by
/// 1. sender (detect a transaction that pays him and spend commited_by): confirmed_by
/// 2. sender toggle status to complete when it spent confirmed_by, receiver when it detects the confirmed_by is spent
#[derive(Debug, Default, Serialize, Deserialize, Tsify, Clone)]
#[tsify(into_wasm_abi, from_wasm_abi)]
#[allow(non_camel_case_types)]
pub struct CachedMessage {
pub id: u32,
pub status: CachedMessageStatus,
pub ciphertext: Option<String>, // When we receive message we can't decrypt we only have this and commited_in_tx
pub plaintext: Option<String>, // Never None when message sent
pub commited_in: Option<OutPoint>,
pub commitment: Option<String>, // content of the op_return
pub sender: Option<String>, // Never None when message sent
pub recipient: Option<String>, // Never None when message sent
pub shared_secret: Option<String>, // Never None when message sent
pub key: Option<String>, // Never None when message sent
pub confirmed_by: Option<OutPoint>, // If this None, Sender keeps sending
pub timestamp: u64,
pub error: Option<String>,
}
impl CachedMessage {
pub fn new() -> Self {
let mut new = Self::default();
let mut buf = [0u8;4];
thread_rng().fill_bytes(&mut buf);
new.id = u32::from_be_bytes(buf);
new
}
pub fn new_error(error: String) -> Self {
let mut new = Self::default();
new.error = Some(error);
new
}
pub fn try_decrypt_cipher(&self, cipher: Vec<u8>) -> Result<Vec<u8>> {
if self.ciphertext.is_some() || self.shared_secret.is_none() {
return Err(Error::msg(
"Can't try decrypt this message, there's already a ciphertext or no shared secret"
));
}
let mut shared_secret = [0u8; 32];
shared_secret
.copy_from_slice(&Vec::from_hex(self.shared_secret.as_ref().unwrap())?);
let aes_decrypt = Aes256Decryption::new(Purpose::Arbitrary, cipher, shared_secret)?;
aes_decrypt.decrypt_with_key()
}
pub fn try_decrypt_with_shared_secret(&self, shared_secret: [u8; 32]) -> Result<Vec<u8>> {
if self.ciphertext.is_none() || self.shared_secret.is_some() {
return Err(Error::msg(
"Can't try decrypt this message, ciphertext is none or shared_secret already found"
));
}
let cipher_bin = Vec::from_hex(self.ciphertext.as_ref().unwrap())?;
let aes_decrypt =
Aes256Decryption::new(Purpose::Arbitrary, cipher_bin, shared_secret)?;
aes_decrypt.decrypt_with_key()
}
}