use ex3_canister_types::chain::Chain;
use std::ops;
use ex3_crypto::sha256;
use ex3_serde::bincode::{deserialize, serialize};
use ex3_serde::{bincode, cbor};
use serde::{Deserialize, Serialize};
use serde_bytes::ByteBuf;
use crate::{Nonce, PublicKey, Version, WalletRegisterId};
pub type TransactionHash = [u8; 32];
pub type r#Type = u32;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
pub struct Transaction {
pub r#type: r#Type,
pub version: Version,
pub from: WalletRegisterId,
pub nonce: Nonce,
pub payload: ByteBuf,
pub signature: ByteBuf,
}
impl Transaction {
pub fn hash(&self) -> TransactionHash {
let bytes = bincode::serialize(&self).unwrap();
sha256!(&bytes)
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(transparent)]
pub struct EncodedTransaction(pub ByteBuf);
impl From<Transaction> for EncodedTransaction {
fn from(tx: Transaction) -> Self {
let bytes = bincode::serialize(&tx).unwrap();
EncodedTransaction(ByteBuf::from(bytes))
}
}
impl From<&Transaction> for EncodedTransaction {
fn from(tx: &Transaction) -> Self {
let bytes = bincode::serialize(&tx).unwrap();
EncodedTransaction(ByteBuf::from(bytes))
}
}
impl From<EncodedTransaction> for Transaction {
fn from(tx: EncodedTransaction) -> Self {
bincode::deserialize(tx.0.as_ref()).unwrap()
}
}
impl From<&EncodedTransaction> for Transaction {
fn from(tx: &EncodedTransaction) -> Self {
bincode::deserialize(tx.0.as_ref()).unwrap()
}
}
impl ops::Deref for EncodedTransaction {
type Target = ByteBuf;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[allow(dead_code)]
pub mod transaction_type {
pub const WALLET_REGISTER: u32 = 100u32;
pub const DEPOSIT: u32 = 200u32;
pub const WITHDRAWAL: u32 = 201u32;
pub const TRANSFER: u32 = 300u32;
pub const RESET_MAIN_SECRET: u32 = 400u32;
pub const CREATE_API_SECRET: u32 = 401u32;
pub const DESTROY_API_SECRET: u32 = 402u32;
pub const CREATE_SPOT_ORDER: u32 = 500u32;
pub const CANCEL_SPOT_ORDER: u32 = 501u32;
pub const ADD_AMM_V2_LIQUIDITY: u32 = 600u32;
pub const REMOVE_AMM_V2_LIQUIDITY: u32 = 601u32;
}
#[derive(Clone, Deserialize, Serialize, Debug, Eq, PartialEq)]
pub struct WalletRegisterRequest {
pub chain: Chain,
pub network: u8,
pub pub_key: PublicKey,
}
impl WalletRegisterRequest {
pub fn encode(&self) -> Vec<u8> {
serialize(&(&self.chain, &self.network, &self.pub_key)).unwrap()
}
pub fn decode(bytes: &[u8]) -> Result<Self, String> {
let (chain, network, pub_key) = deserialize(bytes)
.map_err(|e| format!("Failed to deserialize WalletRegisterRequest: {}", e))?;
Ok(Self {
chain,
network,
pub_key,
})
}
pub fn cbor_encode(&self) -> Vec<u8> {
cbor::serialize(&(&self.chain, &self.network, &self.pub_key)).unwrap()
}
pub fn cbor_decode(bytes: &[u8]) -> Result<Self, String> {
let (chain, network, pub_key) = cbor::deserialize(bytes)
.map_err(|e| format!("Failed to deserialize WalletRegisterRequest: {}", e))?;
Ok(Self {
chain,
network,
pub_key,
})
}
}
#[derive(Clone, Deserialize, Serialize, Debug, Eq, PartialEq)]
pub struct ResetMainSecretRequest {
pub encrypted_pri_key: ByteBuf,
pub l2_pub_key: PublicKey,
}
impl ResetMainSecretRequest {
pub fn encode(&self) -> Vec<u8> {
serialize(&(&self.encrypted_pri_key, &self.l2_pub_key)).unwrap()
}
pub fn decode(bytes: &[u8]) -> Result<Self, String> {
let (encrypted_pri_key, l2_pub_key) = deserialize(bytes)
.map_err(|e| format!("Failed to deserialize ResetMainSecretRequest: {}", e))?;
Ok(Self {
encrypted_pri_key,
l2_pub_key,
})
}
pub fn cbor_encode(&self) -> Vec<u8> {
cbor::serialize(&(&self.encrypted_pri_key, &self.l2_pub_key)).unwrap()
}
pub fn cbor_decode(bytes: &[u8]) -> Result<Self, String> {
let (encrypted_pri_key, l2_pub_key) = cbor::deserialize(bytes)
.map_err(|e| format!("Failed to deserialize ResetMainSecretRequest: {}", e))?;
Ok(Self {
encrypted_pri_key,
l2_pub_key,
})
}
}