fix: structured subcommand approach

This commit is contained in:
Oleksandr Pravdyvyi 2025-10-13 17:25:36 +03:00
parent 577171bc5c
commit 898c5e9bcf
No known key found for this signature in database
GPG Key ID: 9F8955C63C443871
4 changed files with 420 additions and 365 deletions

View File

@ -19,6 +19,7 @@ use tempfile::TempDir;
use tokio::task::JoinHandle;
use wallet::{
Command, SubcommandReturnValue, WalletCore,
cli::token_program::TokenProgramSubcommand,
config::PersistentAccountData,
helperfunctions::{fetch_config, fetch_persistent_accounts},
};
@ -350,13 +351,15 @@ pub async fn test_success_token_program() {
.expect("Failed to produce new account, not present in persistent accounts");
// Create new token
let command = Command::CreateNewToken {
let subcommand = TokenProgramSubcommand::CreateNewToken {
definition_addr: definition_addr.to_string(),
supply_addr: supply_addr.to_string(),
name: "A NAME".to_string(),
total_supply: 37,
};
wallet::execute_subcommand(command).await.unwrap();
wallet::execute_subcommand(Command::TokenProgram(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
@ -402,12 +405,14 @@ pub async fn test_success_token_program() {
);
// Transfer 7 tokens from `supply_acc` to the account at address `recipient_addr`
let command = Command::TransferToken {
let subcommand = TokenProgramSubcommand::TransferToken {
sender_addr: supply_addr.to_string(),
recipient_addr: recipient_addr.to_string(),
balance_to_move: 7,
};
wallet::execute_subcommand(command).await.unwrap();
wallet::execute_subcommand(Command::TokenProgram(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
@ -480,14 +485,16 @@ pub async fn test_success_token_program_private_owned() {
};
// Create new token
let command = Command::CreateNewTokenPrivateOwned {
let subcommand = TokenProgramSubcommand::CreateNewTokenPrivateOwned {
definition_addr: definition_addr.to_string(),
supply_addr: supply_addr.to_string(),
name: "A NAME".to_string(),
total_supply: 37,
};
wallet::execute_subcommand(command).await.unwrap();
wallet::execute_subcommand(Command::TokenProgram(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
@ -520,13 +527,15 @@ pub async fn test_success_token_program_private_owned() {
assert!(verify_commitment_is_in_state(new_commitment1, &seq_client).await);
// Transfer 7 tokens from `supply_acc` to the account at address `recipient_addr`
let command = Command::TransferTokenPrivateOwnedNotInitialized {
let subcommand = TokenProgramSubcommand::TransferTokenPrivateOwnedNotInitialized {
sender_addr: supply_addr.to_string(),
recipient_addr: recipient_addr.to_string(),
balance_to_move: 7,
};
wallet::execute_subcommand(command).await.unwrap();
wallet::execute_subcommand(Command::TokenProgram(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
@ -545,13 +554,15 @@ pub async fn test_success_token_program_private_owned() {
assert!(verify_commitment_is_in_state(new_commitment2, &seq_client).await);
// Transfer additional 7 tokens from `supply_acc` to the account at address `recipient_addr`
let command = Command::TransferTokenPrivateOwnedAlreadyInitialized {
let subcommand = TokenProgramSubcommand::TransferTokenPrivateOwnedAlreadyInitialized {
sender_addr: supply_addr.to_string(),
recipient_addr: recipient_addr.to_string(),
balance_to_move: 7,
};
wallet::execute_subcommand(command).await.unwrap();
wallet::execute_subcommand(Command::TokenProgram(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
@ -603,14 +614,16 @@ pub async fn test_success_token_program_private_claiming_path() {
};
// Create new token
let command = Command::CreateNewTokenPrivateOwned {
let subcommand = TokenProgramSubcommand::CreateNewTokenPrivateOwned {
definition_addr: definition_addr.to_string(),
supply_addr: supply_addr.to_string(),
name: "A NAME".to_string(),
total_supply: 37,
};
wallet::execute_subcommand(command).await.unwrap();
wallet::execute_subcommand(Command::TokenProgram(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
@ -649,7 +662,7 @@ pub async fn test_success_token_program_private_claiming_path() {
.unwrap();
// Transfer 7 tokens from `supply_acc` to the account at address `recipient_addr`
let command = Command::TransferTokenPrivateForeign {
let subcommand = TokenProgramSubcommand::TransferTokenPrivateForeign {
sender_addr: supply_addr.to_string(),
recipient_npk: hex::encode(recipient_keys.nullifer_public_key.0),
recipient_ipk: hex::encode(recipient_keys.incoming_viewing_public_key.0.clone()),
@ -657,7 +670,9 @@ pub async fn test_success_token_program_private_claiming_path() {
};
let SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash } =
wallet::execute_subcommand(command).await.unwrap()
wallet::execute_subcommand(Command::TokenProgram(subcommand))
.await
.unwrap()
else {
panic!("invalid subcommand return value");
};

10
wallet/src/cli/mod.rs Normal file
View File

@ -0,0 +1,10 @@
use anyhow::Result;
use crate::{SubcommandReturnValue, WalletCore};
pub mod token_program;
pub(crate) trait WalletSubcommand {
async fn handle_subcommand(self, wallet_core: &mut WalletCore)
-> Result<SubcommandReturnValue>;
}

View File

@ -0,0 +1,372 @@
use anyhow::Result;
use clap::Subcommand;
use common::transaction::NSSATransaction;
use nssa::Address;
use crate::{SubcommandReturnValue, WalletCore, cli::WalletSubcommand};
///Represents CLI subcommand for a wallet working with token_program
#[derive(Subcommand, Debug, Clone)]
pub enum TokenProgramSubcommand {
//Create a new token using the token program
CreateNewToken {
#[arg(short, long)]
definition_addr: String,
#[arg(short, long)]
supply_addr: String,
#[arg(short, long)]
name: String,
#[arg(short, long)]
total_supply: u128,
},
//Transfer tokens using the token program
TransferToken {
#[arg(short, long)]
sender_addr: String,
#[arg(short, long)]
recipient_addr: String,
#[arg(short, long)]
balance_to_move: u128,
},
//Create a new token using the token program
CreateNewTokenPrivateOwned {
#[arg(short, long)]
definition_addr: String,
#[arg(short, long)]
supply_addr: String,
#[arg(short, long)]
name: String,
#[arg(short, long)]
total_supply: u128,
},
//Transfer tokens using the token program
TransferTokenPrivateOwnedAlreadyInitialized {
#[arg(short, long)]
sender_addr: String,
#[arg(short, long)]
recipient_addr: String,
#[arg(short, long)]
balance_to_move: u128,
},
//Transfer tokens using the token program
TransferTokenPrivateOwnedNotInitialized {
#[arg(short, long)]
sender_addr: String,
#[arg(short, long)]
recipient_addr: String,
#[arg(short, long)]
balance_to_move: u128,
},
//Transfer tokens using the token program
TransferTokenPrivateForeign {
#[arg(short, long)]
sender_addr: String,
///recipient_npk - valid 32 byte hex string
#[arg(long)]
recipient_npk: String,
///recipient_ipk - valid 33 byte hex string
#[arg(long)]
recipient_ipk: String,
#[arg(short, long)]
balance_to_move: u128,
},
}
impl WalletSubcommand for TokenProgramSubcommand {
async fn handle_subcommand(
self,
wallet_core: &mut WalletCore,
) -> Result<SubcommandReturnValue> {
match self {
TokenProgramSubcommand::CreateNewToken {
definition_addr,
supply_addr,
name,
total_supply,
} => {
let name = name.as_bytes();
if name.len() > 6 {
// TODO: return error
panic!();
}
let mut name_bytes = [0; 6];
name_bytes[..name.len()].copy_from_slice(name);
wallet_core
.send_new_token_definition(
definition_addr.parse().unwrap(),
supply_addr.parse().unwrap(),
name_bytes,
total_supply,
)
.await?;
Ok(SubcommandReturnValue::Empty)
}
TokenProgramSubcommand::CreateNewTokenPrivateOwned {
definition_addr,
supply_addr,
name,
total_supply,
} => {
let name = name.as_bytes();
if name.len() > 6 {
// TODO: return error
panic!("Name length mismatch");
}
let mut name_bytes = [0; 6];
name_bytes[..name.len()].copy_from_slice(name);
let definition_addr: Address = definition_addr.parse().unwrap();
let supply_addr: Address = supply_addr.parse().unwrap();
let (res, [secret_supply]) = wallet_core
.send_new_token_definition_private_owned(
definition_addr,
supply_addr,
name_bytes,
total_supply,
)
.await?;
println!("Results of tx send is {res:#?}");
let tx_hash = res.tx_hash;
let transfer_tx = wallet_core
.poll_native_token_transfer(tx_hash.clone())
.await?;
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let supply_ebc = tx.message.encrypted_private_post_states[0].clone();
let supply_comm = tx.message.new_commitments[0].clone();
let res_acc_supply = nssa_core::EncryptionScheme::decrypt(
&supply_ebc.ciphertext,
&secret_supply,
&supply_comm,
0,
)
.unwrap();
println!("Received new to acc {res_acc_supply:#?}");
println!("Transaction data is {:?}", tx.message);
wallet_core
.storage
.insert_private_account_data(supply_addr, res_acc_supply);
}
let path = wallet_core.store_persistent_accounts()?;
println!("Stored persistent accounts at {path:#?}");
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
TokenProgramSubcommand::TransferToken {
sender_addr,
recipient_addr,
balance_to_move,
} => {
wallet_core
.send_transfer_token_transaction(
sender_addr.parse().unwrap(),
recipient_addr.parse().unwrap(),
balance_to_move,
)
.await?;
Ok(SubcommandReturnValue::Empty)
}
TokenProgramSubcommand::TransferTokenPrivateOwnedAlreadyInitialized {
sender_addr,
recipient_addr,
balance_to_move,
} => {
let sender_addr: Address = sender_addr.parse().unwrap();
let recipient_addr: Address = recipient_addr.parse().unwrap();
let (res, [secret_sender, secret_recipient]) = wallet_core
.send_transfer_token_transaction_private_owned_account_already_initialized(
sender_addr,
recipient_addr,
balance_to_move,
)
.await?;
println!("Results of tx send is {res:#?}");
let tx_hash = res.tx_hash;
let transfer_tx = wallet_core
.poll_native_token_transfer(tx_hash.clone())
.await?;
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let sender_ebc = tx.message.encrypted_private_post_states[0].clone();
let sender_comm = tx.message.new_commitments[0].clone();
let recipient_ebc = tx.message.encrypted_private_post_states[1].clone();
let recipient_comm = tx.message.new_commitments[1].clone();
let res_acc_sender = nssa_core::EncryptionScheme::decrypt(
&sender_ebc.ciphertext,
&secret_sender,
&sender_comm,
0,
)
.unwrap();
let res_acc_recipient = nssa_core::EncryptionScheme::decrypt(
&recipient_ebc.ciphertext,
&secret_recipient,
&recipient_comm,
1,
)
.unwrap();
println!("Received new sender acc {res_acc_sender:#?}");
println!("Received new recipient acc {res_acc_recipient:#?}");
println!("Transaction data is {:?}", tx.message);
wallet_core
.storage
.insert_private_account_data(sender_addr, res_acc_sender);
wallet_core
.storage
.insert_private_account_data(recipient_addr, res_acc_recipient);
}
let path = wallet_core.store_persistent_accounts()?;
println!("Stored persistent accounts at {path:#?}");
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
TokenProgramSubcommand::TransferTokenPrivateOwnedNotInitialized {
sender_addr,
recipient_addr,
balance_to_move,
} => {
let sender_addr: Address = sender_addr.parse().unwrap();
let recipient_addr: Address = recipient_addr.parse().unwrap();
let (res, [secret_sender, secret_recipient]) = wallet_core
.send_transfer_token_transaction_private_owned_account_not_initialized(
sender_addr,
recipient_addr,
balance_to_move,
)
.await?;
println!("Results of tx send is {res:#?}");
let tx_hash = res.tx_hash;
let transfer_tx = wallet_core
.poll_native_token_transfer(tx_hash.clone())
.await?;
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let sender_ebc = tx.message.encrypted_private_post_states[0].clone();
let sender_comm = tx.message.new_commitments[0].clone();
let recipient_ebc = tx.message.encrypted_private_post_states[1].clone();
let recipient_comm = tx.message.new_commitments[1].clone();
let res_acc_sender = nssa_core::EncryptionScheme::decrypt(
&sender_ebc.ciphertext,
&secret_sender,
&sender_comm,
0,
)
.unwrap();
let res_acc_recipient = nssa_core::EncryptionScheme::decrypt(
&recipient_ebc.ciphertext,
&secret_recipient,
&recipient_comm,
1,
)
.unwrap();
println!("Received new sender acc {res_acc_sender:#?}");
println!("Received new recipient acc {res_acc_recipient:#?}");
println!("Transaction data is {:?}", tx.message);
wallet_core
.storage
.insert_private_account_data(sender_addr, res_acc_sender);
wallet_core
.storage
.insert_private_account_data(recipient_addr, res_acc_recipient);
}
let path = wallet_core.store_persistent_accounts()?;
println!("Stored persistent accounts at {path:#?}");
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
TokenProgramSubcommand::TransferTokenPrivateForeign {
sender_addr,
recipient_npk,
recipient_ipk,
balance_to_move,
} => {
let sender_addr: Address = sender_addr.parse().unwrap();
let recipient_npk_res = hex::decode(recipient_npk)?;
let mut recipient_npk = [0; 32];
recipient_npk.copy_from_slice(&recipient_npk_res);
let recipient_npk = nssa_core::NullifierPublicKey(recipient_npk);
let recipient_ipk_res = hex::decode(recipient_ipk)?;
let mut recipient_ipk = [0u8; 33];
recipient_ipk.copy_from_slice(&recipient_ipk_res);
let recipient_ipk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
recipient_ipk.to_vec(),
);
let (res, [secret_sender, _]) = wallet_core
.send_transfer_token_transaction_private_foreign_account(
sender_addr,
recipient_npk,
recipient_ipk,
balance_to_move,
)
.await?;
println!("Results of tx send is {res:#?}");
let tx_hash = res.tx_hash;
let transfer_tx = wallet_core
.poll_native_token_transfer(tx_hash.clone())
.await?;
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let sender_ebc = tx.message.encrypted_private_post_states[0].clone();
let sender_comm = tx.message.new_commitments[0].clone();
let res_acc_sender = nssa_core::EncryptionScheme::decrypt(
&sender_ebc.ciphertext,
&secret_sender,
&sender_comm,
0,
)
.unwrap();
println!("Received new sender acc {res_acc_sender:#?}");
println!("Transaction data is {:?}", tx.message);
wallet_core
.storage
.insert_private_account_data(sender_addr, res_acc_sender);
}
let path = wallet_core.store_persistent_accounts()?;
println!("Stored persistent accounts at {path:#?}");
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
}
}
}

View File

@ -15,7 +15,9 @@ use nssa::{Account, Address};
use clap::{Parser, Subcommand};
use nssa_core::Commitment;
use crate::cli::WalletSubcommand;
use crate::{
cli::token_program::TokenProgramSubcommand,
helperfunctions::{
HumanReadableAccount, fetch_config, fetch_persistent_accounts, get_home,
produce_data_for_storage,
@ -28,6 +30,7 @@ use crate::{
pub const HOME_DIR_ENV_VAR: &str = "NSSA_WALLET_HOME_DIR";
pub mod chain_storage;
pub mod cli;
pub mod config;
pub mod helperfunctions;
pub mod pinata_interactions;
@ -270,26 +273,6 @@ pub enum Command {
#[arg(short, long)]
addr: String,
},
//Create a new token using the token program
CreateNewToken {
#[arg(short, long)]
definition_addr: String,
#[arg(short, long)]
supply_addr: String,
#[arg(short, long)]
name: String,
#[arg(short, long)]
total_supply: u128,
},
//Transfer tokens using the token program
TransferToken {
#[arg(short, long)]
sender_addr: String,
#[arg(short, long)]
recipient_addr: String,
#[arg(short, long)]
balance_to_move: u128,
},
// TODO: Testnet only. Refactor to prevent compilation on mainnet.
// Claim piñata prize
ClaimPinata {
@ -316,48 +299,9 @@ pub enum Command {
#[arg(long)]
solution: u128,
},
//Create a new token using the token program
CreateNewTokenPrivateOwned {
#[arg(short, long)]
definition_addr: String,
#[arg(short, long)]
supply_addr: String,
#[arg(short, long)]
name: String,
#[arg(short, long)]
total_supply: u128,
},
//Transfer tokens using the token program
TransferTokenPrivateOwnedAlreadyInitialized {
#[arg(short, long)]
sender_addr: String,
#[arg(short, long)]
recipient_addr: String,
#[arg(short, long)]
balance_to_move: u128,
},
//Transfer tokens using the token program
TransferTokenPrivateOwnedNotInitialized {
#[arg(short, long)]
sender_addr: String,
#[arg(short, long)]
recipient_addr: String,
#[arg(short, long)]
balance_to_move: u128,
},
//Transfer tokens using the token program
TransferTokenPrivateForeign {
#[arg(short, long)]
sender_addr: String,
///recipient_npk - valid 32 byte hex string
#[arg(long)]
recipient_npk: String,
///recipient_ipk - valid 33 byte hex string
#[arg(long)]
recipient_ipk: String,
#[arg(short, long)]
balance_to_move: u128,
},
///Test command
#[command(subcommand)]
TokenProgram(TokenProgramSubcommand),
}
///To execute commands, env var NSSA_WALLET_HOME_DIR must be set into directory with config
@ -775,295 +719,6 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
}
SubcommandReturnValue::Empty
}
Command::CreateNewToken {
definition_addr,
supply_addr,
name,
total_supply,
} => {
let name = name.as_bytes();
if name.len() > 6 {
// TODO: return error
panic!();
}
let mut name_bytes = [0; 6];
name_bytes[..name.len()].copy_from_slice(name);
wallet_core
.send_new_token_definition(
definition_addr.parse().unwrap(),
supply_addr.parse().unwrap(),
name_bytes,
total_supply,
)
.await?;
SubcommandReturnValue::Empty
}
Command::CreateNewTokenPrivateOwned {
definition_addr,
supply_addr,
name,
total_supply,
} => {
let name = name.as_bytes();
if name.len() > 6 {
// TODO: return error
panic!("Name length mismatch");
}
let mut name_bytes = [0; 6];
name_bytes[..name.len()].copy_from_slice(name);
let definition_addr: Address = definition_addr.parse().unwrap();
let supply_addr: Address = supply_addr.parse().unwrap();
let (res, [secret_supply]) = wallet_core
.send_new_token_definition_private_owned(
definition_addr,
supply_addr,
name_bytes,
total_supply,
)
.await?;
println!("Results of tx send is {res:#?}");
let tx_hash = res.tx_hash;
let transfer_tx = wallet_core
.poll_native_token_transfer(tx_hash.clone())
.await?;
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let supply_ebc = tx.message.encrypted_private_post_states[0].clone();
let supply_comm = tx.message.new_commitments[0].clone();
let res_acc_supply = nssa_core::EncryptionScheme::decrypt(
&supply_ebc.ciphertext,
&secret_supply,
&supply_comm,
0,
)
.unwrap();
println!("Received new to acc {res_acc_supply:#?}");
println!("Transaction data is {:?}", tx.message);
wallet_core
.storage
.insert_private_account_data(supply_addr, res_acc_supply);
}
let path = wallet_core.store_persistent_accounts()?;
println!("Stored persistent accounts at {path:#?}");
SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash }
}
Command::TransferToken {
sender_addr,
recipient_addr,
balance_to_move,
} => {
wallet_core
.send_transfer_token_transaction(
sender_addr.parse().unwrap(),
recipient_addr.parse().unwrap(),
balance_to_move,
)
.await?;
SubcommandReturnValue::Empty
}
Command::TransferTokenPrivateOwnedAlreadyInitialized {
sender_addr,
recipient_addr,
balance_to_move,
} => {
let sender_addr: Address = sender_addr.parse().unwrap();
let recipient_addr: Address = recipient_addr.parse().unwrap();
let (res, [secret_sender, secret_recipient]) = wallet_core
.send_transfer_token_transaction_private_owned_account_already_initialized(
sender_addr,
recipient_addr,
balance_to_move,
)
.await?;
println!("Results of tx send is {res:#?}");
let tx_hash = res.tx_hash;
let transfer_tx = wallet_core
.poll_native_token_transfer(tx_hash.clone())
.await?;
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let sender_ebc = tx.message.encrypted_private_post_states[0].clone();
let sender_comm = tx.message.new_commitments[0].clone();
let recipient_ebc = tx.message.encrypted_private_post_states[1].clone();
let recipient_comm = tx.message.new_commitments[1].clone();
let res_acc_sender = nssa_core::EncryptionScheme::decrypt(
&sender_ebc.ciphertext,
&secret_sender,
&sender_comm,
0,
)
.unwrap();
let res_acc_recipient = nssa_core::EncryptionScheme::decrypt(
&recipient_ebc.ciphertext,
&secret_recipient,
&recipient_comm,
1,
)
.unwrap();
println!("Received new sender acc {res_acc_sender:#?}");
println!("Received new recipient acc {res_acc_recipient:#?}");
println!("Transaction data is {:?}", tx.message);
wallet_core
.storage
.insert_private_account_data(sender_addr, res_acc_sender);
wallet_core
.storage
.insert_private_account_data(recipient_addr, res_acc_recipient);
}
let path = wallet_core.store_persistent_accounts()?;
println!("Stored persistent accounts at {path:#?}");
SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash }
}
Command::TransferTokenPrivateOwnedNotInitialized {
sender_addr,
recipient_addr,
balance_to_move,
} => {
let sender_addr: Address = sender_addr.parse().unwrap();
let recipient_addr: Address = recipient_addr.parse().unwrap();
let (res, [secret_sender, secret_recipient]) = wallet_core
.send_transfer_token_transaction_private_owned_account_not_initialized(
sender_addr,
recipient_addr,
balance_to_move,
)
.await?;
println!("Results of tx send is {res:#?}");
let tx_hash = res.tx_hash;
let transfer_tx = wallet_core
.poll_native_token_transfer(tx_hash.clone())
.await?;
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let sender_ebc = tx.message.encrypted_private_post_states[0].clone();
let sender_comm = tx.message.new_commitments[0].clone();
let recipient_ebc = tx.message.encrypted_private_post_states[1].clone();
let recipient_comm = tx.message.new_commitments[1].clone();
let res_acc_sender = nssa_core::EncryptionScheme::decrypt(
&sender_ebc.ciphertext,
&secret_sender,
&sender_comm,
0,
)
.unwrap();
let res_acc_recipient = nssa_core::EncryptionScheme::decrypt(
&recipient_ebc.ciphertext,
&secret_recipient,
&recipient_comm,
1,
)
.unwrap();
println!("Received new sender acc {res_acc_sender:#?}");
println!("Received new recipient acc {res_acc_recipient:#?}");
println!("Transaction data is {:?}", tx.message);
wallet_core
.storage
.insert_private_account_data(sender_addr, res_acc_sender);
wallet_core
.storage
.insert_private_account_data(recipient_addr, res_acc_recipient);
}
let path = wallet_core.store_persistent_accounts()?;
println!("Stored persistent accounts at {path:#?}");
SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash }
}
Command::TransferTokenPrivateForeign {
sender_addr,
recipient_npk,
recipient_ipk,
balance_to_move,
} => {
let sender_addr: Address = sender_addr.parse().unwrap();
let recipient_npk_res = hex::decode(recipient_npk)?;
let mut recipient_npk = [0; 32];
recipient_npk.copy_from_slice(&recipient_npk_res);
let recipient_npk = nssa_core::NullifierPublicKey(recipient_npk);
let recipient_ipk_res = hex::decode(recipient_ipk)?;
let mut recipient_ipk = [0u8; 33];
recipient_ipk.copy_from_slice(&recipient_ipk_res);
let recipient_ipk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
recipient_ipk.to_vec(),
);
let (res, [secret_sender, _]) = wallet_core
.send_transfer_token_transaction_private_foreign_account(
sender_addr,
recipient_npk,
recipient_ipk,
balance_to_move,
)
.await?;
println!("Results of tx send is {res:#?}");
let tx_hash = res.tx_hash;
let transfer_tx = wallet_core
.poll_native_token_transfer(tx_hash.clone())
.await?;
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let sender_ebc = tx.message.encrypted_private_post_states[0].clone();
let sender_comm = tx.message.new_commitments[0].clone();
let res_acc_sender = nssa_core::EncryptionScheme::decrypt(
&sender_ebc.ciphertext,
&secret_sender,
&sender_comm,
0,
)
.unwrap();
println!("Received new sender acc {res_acc_sender:#?}");
println!("Transaction data is {:?}", tx.message);
wallet_core
.storage
.insert_private_account_data(sender_addr, res_acc_sender);
}
let path = wallet_core.store_persistent_accounts()?;
println!("Stored persistent accounts at {path:#?}");
SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash }
}
Command::ClaimPinata {
pinata_addr,
winner_addr,
@ -1125,6 +780,9 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash }
}
Command::TokenProgram(token_subcommand) => {
token_subcommand.handle_subcommand(&mut wallet_core).await?
}
};
Ok(subcommand_ret)