diff --git a/nssa/core/src/account.rs b/nssa/core/src/account.rs index 9bcdcd4b..9de3df5e 100644 --- a/nssa/core/src/account.rs +++ b/nssa/core/src/account.rs @@ -14,7 +14,7 @@ pub type Nonce = u128; /// Account to be used both in public and private contexts #[derive( - Debug, Default, Clone, Eq, PartialEq, Serialize, Deserialize, BorshSerialize, BorshDeserialize, + Default, Clone, Eq, PartialEq, Serialize, Deserialize, BorshSerialize, BorshDeserialize, )] pub struct Account { pub program_owner: ProgramId, @@ -23,6 +23,23 @@ pub struct Account { pub nonce: Nonce, } +impl std::fmt::Debug for Account { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let program_owner_hex: String = self + .program_owner + .iter() + .flat_map(|n| n.to_le_bytes()) + .map(|b| format!("{b:02x}")) + .collect(); + f.debug_struct("Account") + .field("program_owner", &program_owner_hex) + .field("balance", &self.balance) + .field("data", &self.data) + .field("nonce", &self.nonce) + .finish() + } +} + #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] pub struct AccountWithMetadata { pub account: Account, @@ -42,7 +59,6 @@ impl AccountWithMetadata { } #[derive( - Debug, Default, Copy, Clone, @@ -59,6 +75,12 @@ pub struct AccountId { value: [u8; 32], } +impl std::fmt::Debug for AccountId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.value.to_base58()) + } +} + impl AccountId { pub fn new(value: [u8; 32]) -> Self { Self { value } diff --git a/nssa/core/src/commitment.rs b/nssa/core/src/commitment.rs index b08e3005..0040db03 100644 --- a/nssa/core/src/commitment.rs +++ b/nssa/core/src/commitment.rs @@ -7,10 +7,18 @@ use crate::{NullifierPublicKey, account::Account}; #[derive(Serialize, Deserialize, BorshSerialize, BorshDeserialize)] #[cfg_attr( any(feature = "host", test), - derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord) + derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord) )] pub struct Commitment(pub(super) [u8; 32]); +#[cfg(any(feature = "host", test))] +impl std::fmt::Debug for Commitment { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let hex: String = self.0.iter().map(|b| format!("{b:02x}")).collect(); + write!(f, "Commitment({hex})") + } +} + /// A commitment to all zero data. /// ```python /// from hashlib import sha256 diff --git a/nssa/core/src/encryption/mod.rs b/nssa/core/src/encryption/mod.rs index 9ccbf2c8..1499577a 100644 --- a/nssa/core/src/encryption/mod.rs +++ b/nssa/core/src/encryption/mod.rs @@ -22,9 +22,17 @@ pub struct SharedSecretKey(pub [u8; 32]); pub struct EncryptionScheme; #[derive(Serialize, Deserialize, BorshSerialize, BorshDeserialize)] -#[cfg_attr(any(feature = "host", test), derive(Debug, Clone, PartialEq, Eq))] +#[cfg_attr(any(feature = "host", test), derive(Clone, PartialEq, Eq))] pub struct Ciphertext(pub(crate) Vec); +#[cfg(any(feature = "host", test))] +impl std::fmt::Debug for Ciphertext { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let hex: String = self.0.iter().map(|b| format!("{b:02x}")).collect(); + write!(f, "Ciphertext({hex})") + } +} + impl EncryptionScheme { pub fn encrypt( account: &Account, diff --git a/nssa/core/src/encryption/shared_key_derivation.rs b/nssa/core/src/encryption/shared_key_derivation.rs index e946d5e3..6a6636b2 100644 --- a/nssa/core/src/encryption/shared_key_derivation.rs +++ b/nssa/core/src/encryption/shared_key_derivation.rs @@ -10,9 +10,16 @@ use serde::{Deserialize, Serialize}; use crate::{SharedSecretKey, encryption::Scalar}; -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)] +#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)] pub struct Secp256k1Point(pub Vec); +impl std::fmt::Debug for Secp256k1Point { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let hex: String = self.0.iter().map(|b| format!("{b:02x}")).collect(); + write!(f, "Secp256k1Point({hex})") + } +} + impl Secp256k1Point { pub fn from_scalar(value: Scalar) -> Secp256k1Point { let x_bytes: FieldBytes = value.into(); diff --git a/nssa/core/src/nullifier.rs b/nssa/core/src/nullifier.rs index c019b185..95006600 100644 --- a/nssa/core/src/nullifier.rs +++ b/nssa/core/src/nullifier.rs @@ -45,10 +45,18 @@ pub type NullifierSecretKey = [u8; 32]; #[derive(Serialize, Deserialize, BorshSerialize, BorshDeserialize)] #[cfg_attr( any(feature = "host", test), - derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash) + derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash) )] pub struct Nullifier(pub(super) [u8; 32]); +#[cfg(any(feature = "host", test))] +impl std::fmt::Debug for Nullifier { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let hex: String = self.0.iter().map(|b| format!("{b:02x}")).collect(); + write!(f, "Nullifier({hex})") + } +} + impl Nullifier { pub fn for_account_update(commitment: &Commitment, nsk: &NullifierSecretKey) -> Self { const UPDATE_PREFIX: &[u8; 32] = b"/NSSA/v0.2/Nullifier/Update/\x00\x00\x00\x00"; diff --git a/nssa/src/privacy_preserving_transaction/message.rs b/nssa/src/privacy_preserving_transaction/message.rs index 47b0aa42..6a6bdbb1 100644 --- a/nssa/src/privacy_preserving_transaction/message.rs +++ b/nssa/src/privacy_preserving_transaction/message.rs @@ -43,7 +43,7 @@ impl EncryptedAccountData { } } -#[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)] +#[derive(Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)] pub struct Message { pub public_account_ids: Vec, pub nonces: Vec, @@ -53,6 +53,30 @@ pub struct Message { pub new_nullifiers: Vec<(Nullifier, CommitmentSetDigest)>, } +impl std::fmt::Debug for Message { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + struct HexDigest<'a>(&'a [u8; 32]); + impl std::fmt::Debug for HexDigest<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", hex::encode(self.0)) + } + } + let nullifiers: Vec<_> = self + .new_nullifiers + .iter() + .map(|(n, d)| (n, HexDigest(d))) + .collect(); + f.debug_struct("Message") + .field("public_account_ids", &self.public_account_ids) + .field("nonces", &self.nonces) + .field("public_post_states", &self.public_post_states) + .field("encrypted_private_post_states", &self.encrypted_private_post_states) + .field("new_commitments", &self.new_commitments) + .field("new_nullifiers", &nullifiers) + .finish() + } +} + impl Message { pub fn try_from_circuit_output( public_account_ids: Vec, diff --git a/nssa/src/public_transaction/message.rs b/nssa/src/public_transaction/message.rs index 36a20fbb..49823631 100644 --- a/nssa/src/public_transaction/message.rs +++ b/nssa/src/public_transaction/message.rs @@ -7,7 +7,7 @@ use serde::Serialize; use crate::{AccountId, error::NssaError, program::Program}; -#[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)] +#[derive(Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)] pub struct Message { pub program_id: ProgramId, pub account_ids: Vec, @@ -15,6 +15,20 @@ pub struct Message { pub instruction_data: InstructionData, } +impl std::fmt::Debug for Message { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let program_id_hex = hex::encode( + self.program_id.iter().flat_map(|n| n.to_le_bytes()).collect::>(), + ); + f.debug_struct("Message") + .field("program_id", &program_id_hex) + .field("account_ids", &self.account_ids) + .field("nonces", &self.nonces) + .field("instruction_data", &self.instruction_data) + .finish() + } +} + impl Message { pub fn try_new( program_id: ProgramId, diff --git a/nssa/src/signature/mod.rs b/nssa/src/signature/mod.rs index f76c480a..24094c5d 100644 --- a/nssa/src/signature/mod.rs +++ b/nssa/src/signature/mod.rs @@ -6,11 +6,17 @@ pub use private_key::PrivateKey; pub use public_key::PublicKey; use rand::{RngCore, rngs::OsRng}; -#[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)] +#[derive(Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)] pub struct Signature { pub value: [u8; 64], } +impl std::fmt::Debug for Signature { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", hex::encode(self.value)) + } +} + impl Signature { pub fn new(key: &PrivateKey, message: &[u8]) -> Self { let mut aux_random = [0u8; 32]; diff --git a/nssa/src/signature/public_key.rs b/nssa/src/signature/public_key.rs index 55e55b57..83fbf0cb 100644 --- a/nssa/src/signature/public_key.rs +++ b/nssa/src/signature/public_key.rs @@ -5,9 +5,15 @@ use sha2::{Digest, Sha256}; use crate::{PrivateKey, error::NssaError}; -#[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, Serialize, Deserialize)] +#[derive(Clone, PartialEq, Eq, BorshSerialize, Serialize, Deserialize)] pub struct PublicKey([u8; 32]); +impl std::fmt::Debug for PublicKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", hex::encode(self.0)) + } +} + impl BorshDeserialize for PublicKey { fn deserialize_reader(reader: &mut R) -> std::io::Result { let mut buf = [0u8; 32]; diff --git a/wallet/src/cli/account.rs b/wallet/src/cli/account.rs index 7f936284..387a8c1c 100644 --- a/wallet/src/cli/account.rs +++ b/wallet/src/cli/account.rs @@ -165,10 +165,13 @@ fn format_account_details(account: &Account) -> (String, String) { let token_prog_id = Program::token().id(); match &account.program_owner { - o if *o == auth_tr_prog_id => ( - "Account owned by authenticated transfer program".to_string(), - serde_json::to_string(&account).unwrap(), - ), + o if *o == auth_tr_prog_id => { + let account_hr: HumanReadableAccount = account.clone().into(); + ( + "Account owned by authenticated transfer program".to_string(), + serde_json::to_string(&account_hr).unwrap(), + ) + } o if *o == token_prog_id => { if let Ok(token_def) = TokenDefinition::try_from(&account.data) { ( diff --git a/wallet/src/helperfunctions.rs b/wallet/src/helperfunctions.rs index 20c04968..f9ce7908 100644 --- a/wallet/src/helperfunctions.rs +++ b/wallet/src/helperfunctions.rs @@ -1,7 +1,6 @@ use std::{collections::HashMap, path::PathBuf, str::FromStr}; use anyhow::Result; -use base64::{Engine, engine::general_purpose::STANDARD as BASE64}; use key_protocol::key_protocol_core::NSSAUserData; use nssa::Account; use nssa_core::account::Nonce; @@ -149,19 +148,25 @@ pub(crate) fn parse_addr_with_privacy_prefix( #[derive(Serialize)] pub(crate) struct HumanReadableAccount { balance: u128, - program_owner_b64: String, - data_b64: String, + program_owner: String, + data: String, nonce: u128, } impl From for HumanReadableAccount { fn from(account: Account) -> Self { - let program_owner_b64 = BASE64.encode(bytemuck::cast_slice(&account.program_owner)); - let data_b64 = BASE64.encode(account.data); + let program_owner = hex::encode( + account + .program_owner + .iter() + .flat_map(|n| n.to_le_bytes()) + .collect::>(), + ); + let data = hex::encode(account.data); Self { balance: account.balance, - program_owner_b64, - data_b64, + program_owner, + data, nonce: account.nonce, } }