This commit is contained in:
Sergio Chouhy 2025-10-03 15:59:27 -03:00
parent b6e7019588
commit 8f874a6b4f
9 changed files with 395 additions and 530 deletions

View File

@ -8,8 +8,8 @@ anyhow.workspace = true
env_logger.workspace = true env_logger.workspace = true
log.workspace = true log.workspace = true
actix.workspace = true actix.workspace = true
actix-web.workspace = true actix-web.workspace = true
base64.workspace = true
tokio.workspace = true tokio.workspace = true
hex.workspace = true hex.workspace = true
tempfile.workspace = true tempfile.workspace = true

View File

@ -1,12 +1,18 @@
use base64::{Engine, engine::general_purpose::STANDARD as BASE64};
use std::{path::PathBuf, time::Duration}; use std::{path::PathBuf, time::Duration};
use actix_web::dev::ServerHandle; use actix_web::dev::ServerHandle;
use anyhow::Result; use anyhow::Result;
use clap::Parser; use clap::Parser;
use common::sequencer_client::SequencerClient; use common::{
sequencer_client::SequencerClient,
transaction::{EncodedTransaction, NSSATransaction},
};
use log::{info, warn}; use log::{info, warn};
use nssa::program::Program; use nssa::{Address, PrivacyPreservingTransaction, program::Program};
use nssa_core::{NullifierPublicKey, encryption::shared_key_derivation::Secp256k1Point}; use nssa_core::{
Commitment, NullifierPublicKey, encryption::shared_key_derivation::Secp256k1Point,
};
use sequencer_core::config::SequencerConfig; use sequencer_core::config::SequencerConfig;
use sequencer_runner::startup_sequencer; use sequencer_runner::startup_sequencer;
use tempfile::TempDir; use tempfile::TempDir;
@ -14,7 +20,7 @@ use tokio::task::JoinHandle;
use wallet::{ use wallet::{
Command, SubcommandReturnValue, WalletCore, Command, SubcommandReturnValue, WalletCore,
config::PersistentAccountData, config::PersistentAccountData,
helperfunctions::{fetch_config, fetch_persistent_accounts, produce_account_addr_from_hex}, helperfunctions::{fetch_config, fetch_persistent_accounts},
}; };
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
@ -443,159 +449,118 @@ pub async fn test_success_token_program() {
pub async fn test_success_private_transfer_to_another_owned_account() { pub async fn test_success_private_transfer_to_another_owned_account() {
info!("test_success_private_transfer_to_another_owned_account"); info!("test_success_private_transfer_to_another_owned_account");
let from: Address = ACC_SENDER_PRIVATE.parse().unwrap();
let to: Address = ACC_RECEIVER_PRIVATE.parse().unwrap();
let command = Command::SendNativeTokenTransferPrivateOwnedAccount { let command = Command::SendNativeTokenTransferPrivateOwnedAccount {
from: ACC_SENDER_PRIVATE.to_string(), from: from.to_string(),
to: ACC_RECEIVER_PRIVATE.to_string(), to: to.to_string(),
amount: 100, amount: 100,
}; };
let from = produce_account_addr_from_hex(ACC_SENDER_PRIVATE.to_string()).unwrap(); let SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash } =
let to = produce_account_addr_from_hex(ACC_RECEIVER_PRIVATE.to_string()).unwrap(); wallet::execute_subcommand(command).await.unwrap()
else {
let wallet_config = fetch_config().unwrap(); panic!("invalid subcommand return value");
};
let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap();
let mut wallet_storage = WalletCore::start_from_config_update_chain(wallet_config).unwrap();
wallet::execute_subcommand(command).await.unwrap();
info!("Waiting for next block creation"); info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let new_commitment1 = { let command = Command::ClaimPrivateAccount {
let from_acc = wallet_storage tx_hash: tx_hash.clone(),
.storage acc_addr: from.to_string(),
.user_data ciph_id: 0,
.get_private_account_mut(&from)
.unwrap();
from_acc.1.program_owner = nssa::program::Program::authenticated_transfer_program().id();
from_acc.1.balance -= 100;
from_acc.1.nonce += 1;
nssa_core::Commitment::new(&from_acc.0.nullifer_public_key, &from_acc.1)
}; };
wallet::execute_subcommand(command).await.unwrap();
let new_commitment2 = { let command = Command::ClaimPrivateAccount {
let to_acc = wallet_storage tx_hash,
.storage acc_addr: to.to_string(),
.user_data ciph_id: 1,
.get_private_account_mut(&to)
.unwrap();
to_acc.1.program_owner = nssa::program::Program::authenticated_transfer_program().id();
to_acc.1.balance += 100;
to_acc.1.nonce += 1;
nssa_core::Commitment::new(&to_acc.0.nullifer_public_key, &to_acc.1)
}; };
wallet::execute_subcommand(command).await.unwrap();
let proof1 = seq_client let wallet_config = fetch_config().unwrap();
.get_proof_for_commitment(new_commitment1) let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap();
.await let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config).unwrap();
.unwrap()
.unwrap();
let proof2 = seq_client
.get_proof_for_commitment(new_commitment2)
.await
.unwrap()
.unwrap();
println!("New proof is {proof1:#?}"); let new_commitment1 = wallet_storage
println!("New proof is {proof2:#?}"); .get_private_account_commitment(&from)
.unwrap();
assert!(verify_commitment_is_in_state(new_commitment1, &seq_client).await);
let new_commitment2 = wallet_storage.get_private_account_commitment(&to).unwrap();
assert!(verify_commitment_is_in_state(new_commitment2, &seq_client).await);
info!("Success!"); info!("Success!");
} }
pub async fn test_success_private_transfer_to_another_foreign_account() { pub async fn test_success_private_transfer_to_another_foreign_account() {
info!("test_success_private_transfer_to_another_foreign_account"); info!("test_success_private_transfer_to_another_foreign_account");
let to_npk_orig = NullifierPublicKey([42; 32]); let from: Address = ACC_SENDER_PRIVATE.parse().unwrap();
let to_npk = hex::encode(to_npk_orig.0); let to_npk = NullifierPublicKey([42; 32]);
let to_ipk = Secp256k1Point::from_scalar(to_npk_orig.0); let to_npk_string = hex::encode(to_npk.0);
let to_ipk = Secp256k1Point::from_scalar(to_npk.0);
let command = Command::SendNativeTokenTransferPrivateForeignAccount { let command = Command::SendNativeTokenTransferPrivateForeignAccount {
from: ACC_SENDER_PRIVATE.to_string(), from: from.to_string(),
to_npk, to_npk: to_npk_string,
to_ipk: hex::encode(to_ipk.0), to_ipk: hex::encode(to_ipk.0),
amount: 100, amount: 100,
}; };
let from = produce_account_addr_from_hex(ACC_SENDER_PRIVATE.to_string()).unwrap(); let SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash } =
wallet::execute_subcommand(command).await.unwrap()
let wallet_config = fetch_config().unwrap(); else {
panic!("invalid subcommand return value");
let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap(); };
let mut wallet_storage = WalletCore::start_from_config_update_chain(wallet_config).unwrap();
let sub_ret = wallet::execute_subcommand(command).await.unwrap();
println!("SUB RET is {sub_ret:#?}");
info!("Waiting for next block creation"); info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let new_commitment1 = { let command = Command::ClaimPrivateAccount {
let from_acc = wallet_storage tx_hash: tx_hash.clone(),
.storage acc_addr: from.to_string(),
.user_data ciph_id: 0,
.get_private_account_mut(&from)
.unwrap();
from_acc.1.program_owner = nssa::program::Program::authenticated_transfer_program().id();
from_acc.1.balance -= 100;
from_acc.1.nonce += 1;
nssa_core::Commitment::new(&from_acc.0.nullifer_public_key, &from_acc.1)
}; };
wallet::execute_subcommand(command).await.unwrap();
let new_commitment2 = { let wallet_config = fetch_config().unwrap();
let to_acc = nssa_core::account::Account { let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap();
program_owner: nssa::program::Program::authenticated_transfer_program().id(), let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config).unwrap();
balance: 100,
data: vec![],
nonce: 1,
};
nssa_core::Commitment::new(&to_npk_orig, &to_acc) let new_commitment1 = wallet_storage
}; .get_private_account_commitment(&from)
let proof1 = seq_client
.get_proof_for_commitment(new_commitment1)
.await
.unwrap()
.unwrap();
let proof2 = seq_client
.get_proof_for_commitment(new_commitment2)
.await
.unwrap()
.unwrap(); .unwrap();
println!("New proof is {proof1:#?}"); let tx = fetch_privacy_preserving_tx(&seq_client, tx_hash.clone()).await;
println!("New proof is {proof2:#?}"); assert_eq!(tx.message.new_commitments[0], new_commitment1);
assert_eq!(tx.message.new_commitments.len(), 2);
for commitment in tx.message.new_commitments.into_iter() {
assert!(verify_commitment_is_in_state(commitment, &seq_client).await);
}
info!("Success!"); info!("Success!");
} }
pub async fn test_success_private_transfer_to_another_owned_account_claiming_path() { pub async fn test_success_private_transfer_to_another_owned_account_claiming_path() {
info!("test_success_private_transfer_to_another_owned_account_claiming_path"); info!("test_success_private_transfer_to_another_owned_account_claiming_path");
let from: Address = ACC_SENDER_PRIVATE.parse().unwrap();
let command = Command::RegisterAccountPrivate {}; let command = Command::RegisterAccountPrivate {};
let sub_ret = wallet::execute_subcommand(command).await.unwrap(); let sub_ret = wallet::execute_subcommand(command).await.unwrap();
let SubcommandReturnValue::RegisterAccount { addr: to_addr } = sub_ret else { let SubcommandReturnValue::RegisterAccount { addr: to_addr } = sub_ret else {
panic!("FAILED TO REGISTER ACCOUNT"); panic!("FAILED TO REGISTER ACCOUNT");
}; };
let wallet_config = fetch_config().unwrap(); let wallet_config = fetch_config().unwrap();
let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap(); let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config.clone()).unwrap();
let mut wallet_storage = let (to_keys, _) = wallet_storage
WalletCore::start_from_config_update_chain(wallet_config.clone()).unwrap();
let (to_keys, mut to_acc) = wallet_storage
.storage .storage
.user_data .user_data
.user_private_accounts .user_private_accounts
@ -604,74 +569,38 @@ pub async fn test_success_private_transfer_to_another_owned_account_claiming_pat
.unwrap(); .unwrap();
let command = Command::SendNativeTokenTransferPrivateForeignAccount { let command = Command::SendNativeTokenTransferPrivateForeignAccount {
from: ACC_SENDER_PRIVATE.to_string(), from: from.to_string(),
to_npk: hex::encode(to_keys.nullifer_public_key.0), to_npk: hex::encode(to_keys.nullifer_public_key.0),
to_ipk: hex::encode(to_keys.incoming_viewing_public_key.0), to_ipk: hex::encode(to_keys.incoming_viewing_public_key.0),
amount: 100, amount: 100,
}; };
let from = produce_account_addr_from_hex(ACC_SENDER_PRIVATE.to_string()).unwrap();
let sub_ret = wallet::execute_subcommand(command).await.unwrap(); let sub_ret = wallet::execute_subcommand(command).await.unwrap();
let SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash } = sub_ret else { let SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash } = sub_ret else {
panic!("FAILED TO SEND TX"); panic!("FAILED TO SEND TX");
}; };
info!("Waiting for next block creation"); let tx = fetch_privacy_preserving_tx(&seq_client, tx_hash.clone()).await;
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let new_commitment1 = {
let from_acc = wallet_storage
.storage
.user_data
.get_private_account_mut(&from)
.unwrap();
from_acc.1.program_owner = nssa::program::Program::authenticated_transfer_program().id();
from_acc.1.balance -= 100;
from_acc.1.nonce += 1;
nssa_core::Commitment::new(&from_acc.0.nullifer_public_key, &from_acc.1)
};
let new_commitment2 = {
to_acc.program_owner = nssa::program::Program::authenticated_transfer_program().id();
to_acc.balance = 100;
to_acc.nonce = 1;
nssa_core::Commitment::new(&to_keys.nullifer_public_key, &to_acc)
};
let proof1 = seq_client
.get_proof_for_commitment(new_commitment1)
.await
.unwrap()
.unwrap();
let proof2 = seq_client
.get_proof_for_commitment(new_commitment2)
.await
.unwrap()
.unwrap();
println!("New proof is {proof1:#?}");
println!("New proof is {proof2:#?}");
let command = Command::ClaimPrivateAccount { let command = Command::ClaimPrivateAccount {
tx_hash, tx_hash,
acc_addr: hex::encode(to_addr), acc_addr: to_addr.to_string(),
ciph_id: 1, ciph_id: 1,
}; };
wallet::execute_subcommand(command).await.unwrap(); wallet::execute_subcommand(command).await.unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config).unwrap(); let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config).unwrap();
let (_, to_res_acc) = wallet_storage let new_commitment1 = wallet_storage
.storage .get_private_account_commitment(&from)
.user_data
.get_private_account(&to_addr)
.unwrap(); .unwrap();
assert_eq!(tx.message.new_commitments[0], new_commitment1);
assert_eq!(tx.message.new_commitments.len(), 2);
for commitment in tx.message.new_commitments.into_iter() {
assert!(verify_commitment_is_in_state(commitment, &seq_client).await);
}
let to_res_acc = wallet_storage.get_account_private(&to_addr).unwrap();
assert_eq!(to_res_acc.balance, 100); assert_eq!(to_res_acc.balance, 100);
@ -680,51 +609,50 @@ pub async fn test_success_private_transfer_to_another_owned_account_claiming_pat
pub async fn test_success_deshielded_transfer_to_another_account() { pub async fn test_success_deshielded_transfer_to_another_account() {
info!("test_success_deshielded_transfer_to_another_account"); info!("test_success_deshielded_transfer_to_another_account");
let from: Address = ACC_SENDER_PRIVATE.parse().unwrap();
let to: Address = ACC_RECEIVER.parse().unwrap();
let command = Command::SendNativeTokenTransferDeshielded { let command = Command::SendNativeTokenTransferDeshielded {
from: ACC_SENDER_PRIVATE.to_string(), from: from.to_string(),
to: ACC_RECEIVER.to_string(), to: to.to_string(),
amount: 100, amount: 100,
}; };
let from = produce_account_addr_from_hex(ACC_SENDER_PRIVATE.to_string()).unwrap();
let wallet_config = fetch_config().unwrap(); let wallet_config = fetch_config().unwrap();
let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap(); let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config.clone()).unwrap();
let mut wallet_storage = WalletCore::start_from_config_update_chain(wallet_config).unwrap(); let from_acc = wallet_storage.get_account_private(&from).unwrap();
assert_eq!(from_acc.balance, 10000);
wallet::execute_subcommand(command).await.unwrap(); let SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash } =
wallet::execute_subcommand(command).await.unwrap()
else {
panic!("invalid subcommand return value");
};
info!("Waiting for next block creation"); info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let new_commitment1 = { let command = Command::ClaimPrivateAccount {
let from_acc = wallet_storage tx_hash,
.storage acc_addr: from.to_string(),
.user_data ciph_id: 0,
.get_private_account_mut(&from)
.unwrap();
from_acc.1.program_owner = nssa::program::Program::authenticated_transfer_program().id();
from_acc.1.balance -= 100;
from_acc.1.nonce += 1;
nssa_core::Commitment::new(&from_acc.0.nullifer_public_key, &from_acc.1)
}; };
wallet::execute_subcommand(command).await.unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config).unwrap();
let proof1 = seq_client let from_acc = wallet_storage.get_account_private(&from).unwrap();
.get_proof_for_commitment(new_commitment1) let new_commitment = wallet_storage
.await .get_private_account_commitment(&from)
.unwrap()
.unwrap(); .unwrap();
assert!(verify_commitment_is_in_state(new_commitment, &seq_client).await);
let acc_2_balance = seq_client let acc_2_balance = seq_client
.get_account_balance(ACC_RECEIVER.to_string()) .get_account_balance(to.to_string())
.await .await
.unwrap(); .unwrap();
println!("New proof is {proof1:#?}"); assert_eq!(from_acc.balance, 10000 - 100);
assert_eq!(acc_2_balance.balance, 20100); assert_eq!(acc_2_balance.balance, 20100);
info!("Success!"); info!("Success!");
@ -732,66 +660,59 @@ pub async fn test_success_deshielded_transfer_to_another_account() {
pub async fn test_success_shielded_transfer_to_another_owned_account() { pub async fn test_success_shielded_transfer_to_another_owned_account() {
info!("test_success_shielded_transfer_to_another_owned_account"); info!("test_success_shielded_transfer_to_another_owned_account");
let from: Address = ACC_SENDER.parse().unwrap();
let to: Address = ACC_RECEIVER_PRIVATE.parse().unwrap();
let command = Command::SendNativeTokenTransferShielded { let command = Command::SendNativeTokenTransferShielded {
from: ACC_SENDER.to_string(), from: from.to_string(),
to: ACC_RECEIVER_PRIVATE.to_string(), to: to.to_string(),
amount: 100, amount: 100,
}; };
let to = produce_account_addr_from_hex(ACC_RECEIVER_PRIVATE.to_string()).unwrap();
let wallet_config = fetch_config().unwrap(); let wallet_config = fetch_config().unwrap();
let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap(); let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap();
let mut wallet_storage = WalletCore::start_from_config_update_chain(wallet_config).unwrap(); let SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash } =
wallet::execute_subcommand(command).await.unwrap()
wallet::execute_subcommand(command).await.unwrap(); else {
panic!("invalid subcommand return value");
};
info!("Waiting for next block creation"); info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let new_commitment2 = { let command = Command::ClaimPrivateAccount {
let to_acc = wallet_storage tx_hash,
.storage acc_addr: to.to_string(),
.user_data ciph_id: 0,
.get_private_account_mut(&to)
.unwrap();
to_acc.1.program_owner = nssa::program::Program::authenticated_transfer_program().id();
to_acc.1.balance += 100;
to_acc.1.nonce += 1;
nssa_core::Commitment::new(&to_acc.0.nullifer_public_key, &to_acc.1)
}; };
wallet::execute_subcommand(command).await.unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config).unwrap();
let acc_1_balance = seq_client let acc_to = wallet_storage.get_account_private(&to).unwrap();
.get_account_balance(ACC_SENDER.to_string()) let new_commitment = wallet_storage.get_private_account_commitment(&to).unwrap();
assert!(verify_commitment_is_in_state(new_commitment, &seq_client).await);
let acc_from_balance = seq_client
.get_account_balance(from.to_string())
.await .await
.unwrap(); .unwrap();
let proof2 = seq_client assert_eq!(acc_from_balance.balance, 9900);
.get_proof_for_commitment(new_commitment2) assert_eq!(acc_to.balance, 20000 + 100);
.await
.unwrap()
.unwrap();
assert_eq!(acc_1_balance.balance, 9900);
println!("New proof is {proof2:#?}");
info!("Success!"); info!("Success!");
} }
pub async fn test_success_shielded_transfer_to_another_foreign_account() { pub async fn test_success_shielded_transfer_to_another_foreign_account() {
info!("test_success_shielded_transfer_to_another_foreign_account"); info!("test_success_shielded_transfer_to_another_foreign_account");
let to_npk_orig = NullifierPublicKey([42; 32]); let to_npk = NullifierPublicKey([42; 32]);
let to_npk = hex::encode(to_npk_orig.0); let to_npk_string = hex::encode(to_npk.0);
let to_ipk = Secp256k1Point::from_scalar(to_npk_orig.0); let to_ipk = Secp256k1Point::from_scalar(to_npk.0);
let from: Address = ACC_SENDER.parse().unwrap();
let command = Command::SendNativeTokenTransferShieldedForeignAccount { let command = Command::SendNativeTokenTransferShieldedForeignAccount {
from: ACC_SENDER.to_string(), from: from.to_string(),
to_npk, to_npk: to_npk_string,
to_ipk: hex::encode(to_ipk.0), to_ipk: hex::encode(to_ipk.0),
amount: 100, amount: 100,
}; };
@ -800,118 +721,27 @@ pub async fn test_success_shielded_transfer_to_another_foreign_account() {
let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap(); let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap();
wallet::execute_subcommand(command).await.unwrap(); let SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash } =
wallet::execute_subcommand(command).await.unwrap()
info!("Waiting for next block creation"); else {
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; panic!("invalid subcommand return value");
let new_commitment2 = {
let to_acc = nssa_core::account::Account {
program_owner: nssa::program::Program::authenticated_transfer_program().id(),
balance: 100,
data: vec![],
nonce: 1,
};
nssa_core::Commitment::new(&to_npk_orig, &to_acc)
};
let acc_1_balance = seq_client
.get_account_balance(ACC_SENDER.to_string())
.await
.unwrap();
let proof2 = seq_client
.get_proof_for_commitment(new_commitment2)
.await
.unwrap()
.unwrap();
assert_eq!(acc_1_balance.balance, 9900);
println!("New proof is {proof2:#?}");
info!("Success!");
}
pub async fn test_success_shielded_transfer_to_another_owned_account_claiming_path() {
info!("test_success_shielded_transfer_to_another_owned_account_claiming_path");
let command = Command::RegisterAccountPrivate {};
let sub_ret = wallet::execute_subcommand(command).await.unwrap();
let SubcommandReturnValue::RegisterAccount { addr: to_addr } = sub_ret else {
panic!("FAILED TO REGISTER ACCOUNT");
};
let wallet_config = fetch_config().unwrap();
let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config.clone()).unwrap();
let (to_keys, mut to_acc) = wallet_storage
.storage
.user_data
.user_private_accounts
.get(&to_addr)
.cloned()
.unwrap();
let command = Command::SendNativeTokenTransferShieldedForeignAccount {
from: ACC_SENDER.to_string(),
to_npk: hex::encode(to_keys.nullifer_public_key.0),
to_ipk: hex::encode(to_keys.incoming_viewing_public_key.0),
amount: 100,
};
let sub_ret = wallet::execute_subcommand(command).await.unwrap();
let SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash } = sub_ret else {
panic!("FAILED TO SEND TX");
}; };
info!("Waiting for next block creation"); info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await; tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let new_commitment2 = { let tx = fetch_privacy_preserving_tx(&seq_client, tx_hash).await;
to_acc.program_owner = nssa::program::Program::authenticated_transfer_program().id();
to_acc.balance = 100;
to_acc.nonce = 1;
nssa_core::Commitment::new(&to_keys.nullifer_public_key, &to_acc)
};
let acc_1_balance = seq_client let acc_1_balance = seq_client
.get_account_balance(ACC_SENDER.to_string()) .get_account_balance(from.to_string())
.await .await
.unwrap(); .unwrap();
let proof2 = seq_client assert!(
.get_proof_for_commitment(new_commitment2) verify_commitment_is_in_state(tx.message.new_commitments[0].clone(), &seq_client).await
.await );
.unwrap()
.unwrap();
assert_eq!(acc_1_balance.balance, 9900); assert_eq!(acc_1_balance.balance, 9900);
println!("New proof is {proof2:#?}");
let command = Command::ClaimPrivateAccount {
tx_hash,
acc_addr: hex::encode(to_addr),
ciph_id: 0,
};
wallet::execute_subcommand(command).await.unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config).unwrap();
let (_, to_res_acc) = wallet_storage
.storage
.user_data
.get_private_account(&to_addr)
.unwrap();
assert_eq!(to_res_acc.balance, 100);
info!("Success!"); info!("Success!");
} }
@ -1038,12 +868,6 @@ pub async fn main_tests_runner() -> Result<()> {
test_success_shielded_transfer_to_another_foreign_account test_success_shielded_transfer_to_another_foreign_account
); );
} }
"test_success_shielded_transfer_to_another_owned_account_claiming_path" => {
test_cleanup_wrap!(
home_dir,
test_success_shielded_transfer_to_another_owned_account_claiming_path
);
}
"test_pinata" => { "test_pinata" => {
test_cleanup_wrap!(home_dir, test_pinata); test_cleanup_wrap!(home_dir, test_pinata);
} }
@ -1077,11 +901,33 @@ pub async fn main_tests_runner() -> Result<()> {
home_dir, home_dir,
test_success_private_transfer_to_another_owned_account_claiming_path test_success_private_transfer_to_another_owned_account_claiming_path
); );
test_cleanup_wrap!(home_dir, test_pinata);
}
"all_private" => {
test_cleanup_wrap!( test_cleanup_wrap!(
home_dir, home_dir,
test_success_shielded_transfer_to_another_owned_account_claiming_path test_success_private_transfer_to_another_owned_account
);
test_cleanup_wrap!(
home_dir,
test_success_private_transfer_to_another_foreign_account
);
test_cleanup_wrap!(
home_dir,
test_success_deshielded_transfer_to_another_account
);
test_cleanup_wrap!(
home_dir,
test_success_shielded_transfer_to_another_owned_account
);
test_cleanup_wrap!(
home_dir,
test_success_shielded_transfer_to_another_foreign_account
);
test_cleanup_wrap!(
home_dir,
test_success_private_transfer_to_another_owned_account_claiming_path
); );
test_cleanup_wrap!(home_dir, test_pinata);
} }
_ => { _ => {
anyhow::bail!("Unknown test name"); anyhow::bail!("Unknown test name");
@ -1090,3 +936,33 @@ pub async fn main_tests_runner() -> Result<()> {
Ok(()) Ok(())
} }
async fn fetch_privacy_preserving_tx(
seq_client: &SequencerClient,
tx_hash: String,
) -> PrivacyPreservingTransaction {
let transaction_encoded = seq_client
.get_transaction_by_hash(tx_hash.clone())
.await
.unwrap()
.transaction
.unwrap();
let tx_base64_decode = BASE64.decode(transaction_encoded).unwrap();
match NSSATransaction::try_from(&EncodedTransaction::from_bytes(tx_base64_decode)).unwrap() {
NSSATransaction::PrivacyPreserving(privacy_preserving_transaction) => {
privacy_preserving_transaction
}
_ => panic!("Invalid tx type"),
}
}
async fn verify_commitment_is_in_state(
commitment: Commitment,
seq_client: &SequencerClient,
) -> bool {
match seq_client.get_proof_for_commitment(commitment).await {
Ok(Some(_)) => true,
_ => false,
}
}

View File

@ -43,6 +43,7 @@ impl WalletChainStore {
addr: nssa::Address, addr: nssa::Address,
account: nssa_core::account::Account, account: nssa_core::account::Account,
) { ) {
println!("inserting at addres {}, this account {:?}", addr, account);
self.user_data self.user_data
.user_private_accounts .user_private_accounts
.entry(addr) .entry(addr)

View File

@ -30,11 +30,6 @@ pub fn fetch_config() -> Result<WalletConfig> {
Ok(serde_json::from_reader(reader)?) Ok(serde_json::from_reader(reader)?)
} }
// ToDo: Replace with structures conversion in future
pub fn produce_account_addr_from_hex(hex_str: String) -> Result<Address> {
Ok(hex_str.parse()?)
}
/// Fetch list of accounts stored at `NSSA_WALLET_HOME_DIR/curr_accounts.json` /// Fetch list of accounts stored at `NSSA_WALLET_HOME_DIR/curr_accounts.json`
/// ///
/// If file not present, it is considered as empty list of persistent accounts /// If file not present, it is considered as empty list of persistent accounts

View File

@ -14,11 +14,12 @@ use log::info;
use nssa::{Account, Address}; use nssa::{Account, Address};
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use nssa_core::Commitment;
use crate::{ use crate::{
helperfunctions::{ helperfunctions::{
HumanReadableAccount, fetch_config, fetch_persistent_accounts, get_home, HumanReadableAccount, fetch_config, fetch_persistent_accounts, get_home,
produce_account_addr_from_hex, produce_data_for_storage, produce_data_for_storage,
}, },
poller::TxPoller, poller::TxPoller,
}; };
@ -180,11 +181,24 @@ impl WalletCore {
} }
///Get account ///Get account
pub async fn get_account(&self, addr: Address) -> Result<Account> { pub async fn get_account_public(&self, addr: Address) -> Result<Account> {
let response = self.sequencer_client.get_account(addr.to_string()).await?; let response = self.sequencer_client.get_account(addr.to_string()).await?;
Ok(response.account) Ok(response.account)
} }
pub fn get_account_private(&self, addr: &Address) -> Option<Account> {
self.storage
.user_data
.user_private_accounts
.get(addr)
.map(|value| value.1.clone())
}
pub fn get_private_account_commitment(&self, addr: &Address) -> Option<Commitment> {
let (keys, account) = self.storage.user_data.user_private_accounts.get(addr)?;
Some(Commitment::new(&keys.nullifer_public_key, account))
}
///Poll transactions ///Poll transactions
pub async fn poll_native_token_transfer(&self, hash: String) -> Result<NSSATransaction> { pub async fn poll_native_token_transfer(&self, hash: String) -> Result<NSSATransaction> {
let transaction_encoded = self.poller.poll_tx(hash).await?; let transaction_encoded = self.poller.poll_tx(hash).await?;
@ -301,6 +315,11 @@ pub enum Command {
#[arg(long)] #[arg(long)]
ciph_id: usize, ciph_id: usize,
}, },
///Get private account with `addr` from storage
GetPrivateAccount {
#[arg(short, long)]
addr: String,
},
///Register new public account ///Register new public account
RegisterAccountPublic {}, RegisterAccountPublic {},
///Register new private account ///Register new private account
@ -373,6 +392,7 @@ pub struct Args {
pub enum SubcommandReturnValue { pub enum SubcommandReturnValue {
PrivacyPreservingTransfer { tx_hash: String }, PrivacyPreservingTransfer { tx_hash: String },
RegisterAccount { addr: nssa::Address }, RegisterAccount { addr: nssa::Address },
Account(nssa::Account),
Empty, Empty,
} }
@ -382,8 +402,8 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
let subcommand_ret = match command { let subcommand_ret = match command {
Command::SendNativeTokenTransferPublic { from, to, amount } => { Command::SendNativeTokenTransferPublic { from, to, amount } => {
let from = produce_account_addr_from_hex(from)?; let from: Address = from.parse().unwrap();
let to = produce_account_addr_from_hex(to)?; let to: Address = to.parse().unwrap();
let res = wallet_core let res = wallet_core
.send_public_native_token_transfer(from, to, amount) .send_public_native_token_transfer(from, to, amount)
@ -402,8 +422,8 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
SubcommandReturnValue::Empty SubcommandReturnValue::Empty
} }
Command::SendNativeTokenTransferPrivateOwnedAccount { from, to, amount } => { Command::SendNativeTokenTransferPrivateOwnedAccount { from, to, amount } => {
let from = produce_account_addr_from_hex(from)?; let from: Address = from.parse().unwrap();
let to = produce_account_addr_from_hex(to)?; let to: Address = to.parse().unwrap();
let (res, [secret_from, secret_to]) = wallet_core let (res, [secret_from, secret_to]) = wallet_core
.send_private_native_token_transfer_owned_account(from, to, amount) .send_private_native_token_transfer_owned_account(from, to, amount)
@ -464,7 +484,7 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
to_ipk, to_ipk,
amount, amount,
} => { } => {
let from = produce_account_addr_from_hex(from)?; let from: Address = from.parse().unwrap();
let to_npk_res = hex::decode(to_npk)?; let to_npk_res = hex::decode(to_npk)?;
let mut to_npk = [0; 32]; let mut to_npk = [0; 32];
to_npk.copy_from_slice(&to_npk_res); to_npk.copy_from_slice(&to_npk_res);
@ -527,8 +547,8 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash } SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash }
} }
Command::SendNativeTokenTransferDeshielded { from, to, amount } => { Command::SendNativeTokenTransferDeshielded { from, to, amount } => {
let from = produce_account_addr_from_hex(from)?; let from: Address = from.parse().unwrap();
let to = produce_account_addr_from_hex(to)?; let to: Address = to.parse().unwrap();
let (res, secret) = wallet_core let (res, secret) = wallet_core
.send_deshielded_native_token_transfer(from, to, amount) .send_deshielded_native_token_transfer(from, to, amount)
@ -569,8 +589,8 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash } SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash }
} }
Command::SendNativeTokenTransferShielded { from, to, amount } => { Command::SendNativeTokenTransferShielded { from, to, amount } => {
let from = produce_account_addr_from_hex(from)?; let from: Address = from.parse().unwrap();
let to = produce_account_addr_from_hex(to)?; let to: Address = to.parse().unwrap();
let (res, secret) = wallet_core let (res, secret) = wallet_core
.send_shielded_native_token_transfer(from, to, amount) .send_shielded_native_token_transfer(from, to, amount)
@ -608,7 +628,7 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
to_ipk, to_ipk,
amount, amount,
} => { } => {
let from = produce_account_addr_from_hex(from)?; let from: Address = from.parse().unwrap();
let to_npk_res = hex::decode(to_npk)?; let to_npk_res = hex::decode(to_npk)?;
let mut to_npk = [0; 32]; let mut to_npk = [0; 32];
@ -656,7 +676,7 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
acc_addr, acc_addr,
ciph_id, ciph_id,
} => { } => {
let acc_addr = produce_account_addr_from_hex(acc_addr)?; let acc_addr: Address = acc_addr.parse().unwrap();
let account_key_chain = wallet_core let account_key_chain = wallet_core
.storage .storage
@ -759,9 +779,19 @@ pub async fn execute_subcommand(command: Command) -> Result<SubcommandReturnValu
} }
Command::GetAccount { addr } => { Command::GetAccount { addr } => {
let addr: Address = addr.parse()?; let addr: Address = addr.parse()?;
let account: HumanReadableAccount = wallet_core.get_account(addr).await?.into(); let account = wallet_core.get_account_public(addr).await?;
println!("{}", serde_json::to_string(&account).unwrap()); let account_hr: HumanReadableAccount = account.clone().into();
println!("{}", serde_json::to_string(&account_hr).unwrap());
SubcommandReturnValue::Account(account)
}
Command::GetPrivateAccount { addr } => {
let addr: Address = addr.parse()?;
if let Some(account) = wallet_core.get_account_private(&addr) {
println!("{}", serde_json::to_string(&account).unwrap());
} else {
println!("Private account not found.");
}
SubcommandReturnValue::Empty SubcommandReturnValue::Empty
} }
Command::CreateNewToken { Command::CreateNewToken {

View File

@ -1,7 +1,11 @@
use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse}; use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse};
use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder; use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder;
use nssa::Address; use nssa::{
use nssa_core::account::AccountWithMetadata; Address, PrivacyPreservingTransaction,
privacy_preserving_transaction::{circuit, message::Message, witness_set::WitnessSet},
program::Program,
};
use nssa_core::{Commitment, account::AccountWithMetadata};
use crate::{WalletCore, helperfunctions::produce_random_nonces}; use crate::{WalletCore, helperfunctions::produce_random_nonces};
@ -18,17 +22,17 @@ impl WalletCore {
return Err(ExecutionFailureKind::KeyNotFoundError); return Err(ExecutionFailureKind::KeyNotFoundError);
}; };
let Ok(to_acc) = self.get_account(to).await else { let Ok(to_acc) = self.get_account_public(to).await else {
return Err(ExecutionFailureKind::KeyNotFoundError); return Err(ExecutionFailureKind::KeyNotFoundError);
}; };
if from_acc.balance >= balance_to_move { if from_acc.balance >= balance_to_move {
let program = nssa::program::Program::authenticated_transfer_program(); let program = Program::authenticated_transfer_program();
let npk_from = from_keys.nullifer_public_key; let npk_from = from_keys.nullifer_public_key;
let ipk_from = from_keys.incoming_viewing_public_key; let ipk_from = from_keys.incoming_viewing_public_key;
let sender_commitment = nssa_core::Commitment::new(&npk_from, &from_acc); let sender_commitment = Commitment::new(&npk_from, &from_acc);
let sender_pre = AccountWithMetadata::new(from_acc.clone(), true, &npk_from); let sender_pre = AccountWithMetadata::new(from_acc.clone(), true, &npk_from);
let recipient_pre = AccountWithMetadata::new(to_acc.clone(), false, to); let recipient_pre = AccountWithMetadata::new(to_acc.clone(), false, to);
@ -36,9 +40,9 @@ impl WalletCore {
let eph_holder = EphemeralKeyHolder::new(&npk_from); let eph_holder = EphemeralKeyHolder::new(&npk_from);
let shared_secret = eph_holder.calculate_shared_secret_sender(&ipk_from); let shared_secret = eph_holder.calculate_shared_secret_sender(&ipk_from);
let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove( let (output, proof) = circuit::execute_and_prove(
&[sender_pre, recipient_pre], &[sender_pre, recipient_pre],
&nssa::program::Program::serialize_instruction(balance_to_move).unwrap(), &Program::serialize_instruction(balance_to_move).unwrap(),
&[1, 0], &[1, 0],
&produce_random_nonces(1), &produce_random_nonces(1),
&[(npk_from.clone(), shared_secret.clone())], &[(npk_from.clone(), shared_secret.clone())],
@ -54,30 +58,21 @@ impl WalletCore {
) )
.unwrap(); .unwrap();
let message = let message = Message::try_from_circuit_output(
nssa::privacy_preserving_transaction::message::Message::try_from_circuit_output( vec![to],
vec![to], vec![],
vec![], vec![(
vec![( npk_from.clone(),
npk_from.clone(), ipk_from.clone(),
ipk_from.clone(), eph_holder.generate_ephemeral_public_key(),
eph_holder.generate_ephemeral_public_key(), )],
)], output,
output, )
) .unwrap();
.unwrap();
let witness_set = let witness_set = WitnessSet::for_message(&message, proof, &[]);
nssa::privacy_preserving_transaction::witness_set::WitnessSet::for_message(
&message,
proof,
&[],
);
let tx = nssa::privacy_preserving_transaction::PrivacyPreservingTransaction::new( let tx = PrivacyPreservingTransaction::new(message, witness_set);
message,
witness_set,
);
Ok(( Ok((
self.sequencer_client.send_tx_private(tx).await?, self.sequencer_client.send_tx_private(tx).await?,

View File

@ -1,7 +1,14 @@
use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse}; use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse};
use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder; use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder;
use nssa::Address; use nssa::{
use nssa_core::account::AccountWithMetadata; Address, PrivacyPreservingTransaction,
privacy_preserving_transaction::{circuit, message::Message, witness_set::WitnessSet},
program::Program,
};
use nssa_core::{
Commitment, NullifierPublicKey, SharedSecretKey, account::AccountWithMetadata,
encryption::IncomingViewingPublicKey,
};
use crate::{WalletCore, helperfunctions::produce_random_nonces}; use crate::{WalletCore, helperfunctions::produce_random_nonces};
@ -9,10 +16,10 @@ impl WalletCore {
pub async fn send_private_native_token_transfer_outer_account( pub async fn send_private_native_token_transfer_outer_account(
&self, &self,
from: Address, from: Address,
to_npk: nssa_core::NullifierPublicKey, to_npk: NullifierPublicKey,
to_ipk: nssa_core::encryption::IncomingViewingPublicKey, to_ipk: IncomingViewingPublicKey,
balance_to_move: u128, balance_to_move: u128,
) -> Result<(SendTxResponse, [nssa_core::SharedSecretKey; 2]), ExecutionFailureKind> { ) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
let Some((from_keys, from_acc)) = let Some((from_keys, from_acc)) =
self.storage.user_data.get_private_account(&from).cloned() self.storage.user_data.get_private_account(&from).cloned()
else { else {
@ -22,27 +29,25 @@ impl WalletCore {
let to_acc = nssa_core::account::Account::default(); let to_acc = nssa_core::account::Account::default();
if from_acc.balance >= balance_to_move { if from_acc.balance >= balance_to_move {
let program = nssa::program::Program::authenticated_transfer_program(); let program = Program::authenticated_transfer_program();
let from_npk = from_keys.nullifer_public_key; let from_npk = from_keys.nullifer_public_key;
let from_ipk = from_keys.incoming_viewing_public_key; let from_ipk = from_keys.incoming_viewing_public_key;
let sender_commitment = nssa_core::Commitment::new(&from_npk, &from_acc); let sender_commitment = Commitment::new(&from_npk, &from_acc);
let sender_pre = let sender_pre = AccountWithMetadata::new(from_acc.clone(), true, &from_npk);
nssa_core::account::AccountWithMetadata::new(from_acc.clone(), true, &from_npk);
let recipient_pre = let recipient_pre = AccountWithMetadata::new(to_acc.clone(), false, &to_npk);
nssa_core::account::AccountWithMetadata::new(to_acc.clone(), false, &to_npk);
let eph_holder = EphemeralKeyHolder::new(&to_npk); let eph_holder = EphemeralKeyHolder::new(&to_npk);
let shared_secret_from = eph_holder.calculate_shared_secret_sender(&from_ipk); let shared_secret_from = eph_holder.calculate_shared_secret_sender(&from_ipk);
let shared_secret_to = eph_holder.calculate_shared_secret_sender(&to_ipk); let shared_secret_to = eph_holder.calculate_shared_secret_sender(&to_ipk);
let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove( let (output, proof) = circuit::execute_and_prove(
&[sender_pre, recipient_pre], &[sender_pre, recipient_pre],
&nssa::program::Program::serialize_instruction(balance_to_move).unwrap(), &Program::serialize_instruction(balance_to_move).unwrap(),
&[1, 2], &[1, 2],
&produce_random_nonces(2), &produce_random_nonces(2),
&[ &[
@ -61,37 +66,28 @@ impl WalletCore {
) )
.unwrap(); .unwrap();
let message = let message = Message::try_from_circuit_output(
nssa::privacy_preserving_transaction::message::Message::try_from_circuit_output( vec![],
vec![], vec![],
vec![], vec![
vec![ (
( from_npk.clone(),
from_npk.clone(), from_ipk.clone(),
from_ipk.clone(), eph_holder.generate_ephemeral_public_key(),
eph_holder.generate_ephemeral_public_key(), ),
), (
( to_npk.clone(),
to_npk.clone(), to_ipk.clone(),
to_ipk.clone(), eph_holder.generate_ephemeral_public_key(),
eph_holder.generate_ephemeral_public_key(), ),
), ],
], output,
output, )
) .unwrap();
.unwrap();
let witness_set = let witness_set = WitnessSet::for_message(&message, proof, &[]);
nssa::privacy_preserving_transaction::witness_set::WitnessSet::for_message(
&message,
proof,
&[],
);
let tx = nssa::privacy_preserving_transaction::PrivacyPreservingTransaction::new( let tx = PrivacyPreservingTransaction::new(message, witness_set);
message,
witness_set,
);
Ok(( Ok((
self.sequencer_client.send_tx_private(tx).await?, self.sequencer_client.send_tx_private(tx).await?,
@ -107,7 +103,7 @@ impl WalletCore {
from: Address, from: Address,
to: Address, to: Address,
balance_to_move: u128, balance_to_move: u128,
) -> Result<(SendTxResponse, [nssa_core::SharedSecretKey; 2]), ExecutionFailureKind> { ) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
let Some((from_keys, from_acc)) = let Some((from_keys, from_acc)) =
self.storage.user_data.get_private_account(&from).cloned() self.storage.user_data.get_private_account(&from).cloned()
else { else {
@ -125,10 +121,10 @@ impl WalletCore {
let to_ipk = to_keys.incoming_viewing_public_key.clone(); let to_ipk = to_keys.incoming_viewing_public_key.clone();
if from_acc.balance >= balance_to_move { if from_acc.balance >= balance_to_move {
let program = nssa::program::Program::authenticated_transfer_program(); let program = Program::authenticated_transfer_program();
let sender_commitment = nssa_core::Commitment::new(&from_npk, &from_acc); let sender_commitment = Commitment::new(&from_npk, &from_acc);
let receiver_commitment = nssa_core::Commitment::new(&to_npk, &to_acc); let receiver_commitment = Commitment::new(&to_npk, &to_acc);
let sender_pre = AccountWithMetadata::new(from_acc.clone(), true, &from_npk); let sender_pre = AccountWithMetadata::new(from_acc.clone(), true, &from_npk);
let recipient_pre = AccountWithMetadata::new(to_acc.clone(), true, &to_npk); let recipient_pre = AccountWithMetadata::new(to_acc.clone(), true, &to_npk);
@ -139,9 +135,9 @@ impl WalletCore {
let eph_holder_to = EphemeralKeyHolder::new(&to_npk); let eph_holder_to = EphemeralKeyHolder::new(&to_npk);
let shared_secret_to = eph_holder_to.calculate_shared_secret_sender(&to_ipk); let shared_secret_to = eph_holder_to.calculate_shared_secret_sender(&to_ipk);
let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove( let (output, proof) = circuit::execute_and_prove(
&[sender_pre, recipient_pre], &[sender_pre, recipient_pre],
&nssa::program::Program::serialize_instruction(balance_to_move).unwrap(), &Program::serialize_instruction(balance_to_move).unwrap(),
&[1, 1], &[1, 1],
&produce_random_nonces(2), &produce_random_nonces(2),
&[ &[
@ -170,37 +166,27 @@ impl WalletCore {
) )
.unwrap(); .unwrap();
let message = let message = Message::try_from_circuit_output(
nssa::privacy_preserving_transaction::message::Message::try_from_circuit_output( vec![],
vec![], vec![],
vec![], vec![
vec![ (
( from_npk.clone(),
from_npk.clone(), from_ipk.clone(),
from_ipk.clone(), eph_holder_from.generate_ephemeral_public_key(),
eph_holder_from.generate_ephemeral_public_key(), ),
), (
( to_npk.clone(),
to_npk.clone(), to_ipk.clone(),
to_ipk.clone(), eph_holder_to.generate_ephemeral_public_key(),
eph_holder_to.generate_ephemeral_public_key(), ),
), ],
], output,
output, )
) .unwrap();
.unwrap();
let witness_set = let witness_set = WitnessSet::for_message(&message, proof, &[]);
nssa::privacy_preserving_transaction::witness_set::WitnessSet::for_message( let tx = PrivacyPreservingTransaction::new(message, witness_set);
&message,
proof,
&[],
);
let tx = nssa::privacy_preserving_transaction::PrivacyPreservingTransaction::new(
message,
witness_set,
);
Ok(( Ok((
self.sequencer_client.send_tx_private(tx).await?, self.sequencer_client.send_tx_private(tx).await?,

View File

@ -1,5 +1,9 @@
use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse}; use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse};
use nssa::Address; use nssa::{
Address, PublicTransaction,
program::Program,
public_transaction::{Message, WitnessSet},
};
use crate::WalletCore; use crate::WalletCore;
@ -20,14 +24,8 @@ impl WalletCore {
}; };
let addresses = vec![from, to]; let addresses = vec![from, to];
let program_id = nssa::program::Program::authenticated_transfer_program().id(); let program_id = Program::authenticated_transfer_program().id();
let message = nssa::public_transaction::Message::try_new( let message = Message::try_new(program_id, addresses, nonces, balance_to_move).unwrap();
program_id,
addresses,
nonces,
balance_to_move,
)
.unwrap();
let signing_key = self.storage.user_data.get_pub_account_signing_key(&from); let signing_key = self.storage.user_data.get_pub_account_signing_key(&from);
@ -35,10 +33,9 @@ impl WalletCore {
return Err(ExecutionFailureKind::KeyNotFoundError); return Err(ExecutionFailureKind::KeyNotFoundError);
}; };
let witness_set = let witness_set = WitnessSet::for_message(&message, &[signing_key]);
nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]);
let tx = nssa::PublicTransaction::new(message, witness_set); let tx = PublicTransaction::new(message, witness_set);
Ok(self.sequencer_client.send_tx_public(tx).await?) Ok(self.sequencer_client.send_tx_public(tx).await?)
} else { } else {

View File

@ -1,7 +1,14 @@
use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse}; use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse};
use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder; use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder;
use nssa::Address; use nssa::{
use nssa_core::account::AccountWithMetadata; Account, Address, PrivacyPreservingTransaction,
privacy_preserving_transaction::{circuit, message::Message, witness_set::WitnessSet},
program::Program,
};
use nssa_core::{
Commitment, NullifierPublicKey, SharedSecretKey, account::AccountWithMetadata,
encryption::IncomingViewingPublicKey,
};
use crate::{WalletCore, helperfunctions::produce_random_nonces}; use crate::{WalletCore, helperfunctions::produce_random_nonces};
@ -11,8 +18,8 @@ impl WalletCore {
from: Address, from: Address,
to: Address, to: Address,
balance_to_move: u128, balance_to_move: u128,
) -> Result<(SendTxResponse, nssa_core::SharedSecretKey), ExecutionFailureKind> { ) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
let Ok(from_acc) = self.get_account(from).await else { let Ok(from_acc) = self.get_account_public(from).await else {
return Err(ExecutionFailureKind::KeyNotFoundError); return Err(ExecutionFailureKind::KeyNotFoundError);
}; };
@ -25,20 +32,17 @@ impl WalletCore {
let to_ipk = to_keys.incoming_viewing_public_key.clone(); let to_ipk = to_keys.incoming_viewing_public_key.clone();
if from_acc.balance >= balance_to_move { if from_acc.balance >= balance_to_move {
let program = nssa::program::Program::authenticated_transfer_program(); let program = Program::authenticated_transfer_program();
let receiver_commitment = let receiver_commitment = Commitment::new(&to_npk, &to_acc);
nssa_core::Commitment::new(&to_keys.nullifer_public_key, &to_acc);
let sender_pre = let sender_pre = AccountWithMetadata::new(from_acc.clone(), true, from);
nssa_core::account::AccountWithMetadata::new(from_acc.clone(), true, from); let recipient_pre = AccountWithMetadata::new(to_acc.clone(), true, &to_npk);
let recipient_pre =
nssa_core::account::AccountWithMetadata::new(to_acc.clone(), true, &to_npk);
let eph_holder = EphemeralKeyHolder::new(&to_npk); let eph_holder = EphemeralKeyHolder::new(&to_npk);
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_ipk); let shared_secret = eph_holder.calculate_shared_secret_sender(&to_ipk);
let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove( let (output, proof) = circuit::execute_and_prove(
&[sender_pre, recipient_pre], &[sender_pre, recipient_pre],
&nssa::program::Program::serialize_instruction(balance_to_move).unwrap(), &nssa::program::Program::serialize_instruction(balance_to_move).unwrap(),
&[0, 1], &[0, 1],
@ -56,18 +60,17 @@ impl WalletCore {
) )
.unwrap(); .unwrap();
let message = let message = Message::try_from_circuit_output(
nssa::privacy_preserving_transaction::message::Message::try_from_circuit_output( vec![from],
vec![from], vec![from_acc.nonce],
vec![from_acc.nonce], vec![(
vec![( to_npk.clone(),
to_npk.clone(), to_ipk.clone(),
to_ipk.clone(), eph_holder.generate_ephemeral_public_key(),
eph_holder.generate_ephemeral_public_key(), )],
)], output,
output, )
) .unwrap();
.unwrap();
let signing_key = self.storage.user_data.get_pub_account_signing_key(&from); let signing_key = self.storage.user_data.get_pub_account_signing_key(&from);
@ -75,17 +78,9 @@ impl WalletCore {
return Err(ExecutionFailureKind::KeyNotFoundError); return Err(ExecutionFailureKind::KeyNotFoundError);
}; };
let witness_set = let witness_set = WitnessSet::for_message(&message, proof, &[signing_key]);
nssa::privacy_preserving_transaction::witness_set::WitnessSet::for_message(
&message,
proof,
&[signing_key],
);
let tx = nssa::privacy_preserving_transaction::PrivacyPreservingTransaction::new( let tx = PrivacyPreservingTransaction::new(message, witness_set);
message,
witness_set,
);
Ok(( Ok((
self.sequencer_client.send_tx_private(tx).await?, self.sequencer_client.send_tx_private(tx).await?,
@ -99,18 +94,18 @@ impl WalletCore {
pub async fn send_shielded_native_token_transfer_outer_account( pub async fn send_shielded_native_token_transfer_outer_account(
&self, &self,
from: Address, from: Address,
to_npk: nssa_core::NullifierPublicKey, to_npk: NullifierPublicKey,
to_ipk: nssa_core::encryption::IncomingViewingPublicKey, to_ipk: IncomingViewingPublicKey,
balance_to_move: u128, balance_to_move: u128,
) -> Result<(SendTxResponse, nssa_core::SharedSecretKey), ExecutionFailureKind> { ) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
let Ok(from_acc) = self.get_account(from).await else { let Ok(from_acc) = self.get_account_public(from).await else {
return Err(ExecutionFailureKind::KeyNotFoundError); return Err(ExecutionFailureKind::KeyNotFoundError);
}; };
let to_acc = nssa_core::account::Account::default(); let to_acc = Account::default();
if from_acc.balance >= balance_to_move { if from_acc.balance >= balance_to_move {
let program = nssa::program::Program::authenticated_transfer_program(); let program = Program::authenticated_transfer_program();
let sender_pre = AccountWithMetadata::new(from_acc.clone(), true, from); let sender_pre = AccountWithMetadata::new(from_acc.clone(), true, from);
let recipient_pre = AccountWithMetadata::new(to_acc.clone(), false, &to_npk); let recipient_pre = AccountWithMetadata::new(to_acc.clone(), false, &to_npk);
@ -118,9 +113,9 @@ impl WalletCore {
let eph_holder = EphemeralKeyHolder::new(&to_npk); let eph_holder = EphemeralKeyHolder::new(&to_npk);
let shared_secret = eph_holder.calculate_shared_secret_sender(&to_ipk); let shared_secret = eph_holder.calculate_shared_secret_sender(&to_ipk);
let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove( let (output, proof) = circuit::execute_and_prove(
&[sender_pre, recipient_pre], &[sender_pre, recipient_pre],
&nssa::program::Program::serialize_instruction(balance_to_move).unwrap(), &Program::serialize_instruction(balance_to_move).unwrap(),
&[0, 2], &[0, 2],
&produce_random_nonces(1), &produce_random_nonces(1),
&[(to_npk.clone(), shared_secret.clone())], &[(to_npk.clone(), shared_secret.clone())],
@ -129,18 +124,17 @@ impl WalletCore {
) )
.unwrap(); .unwrap();
let message = let message = Message::try_from_circuit_output(
nssa::privacy_preserving_transaction::message::Message::try_from_circuit_output( vec![from],
vec![from], vec![from_acc.nonce],
vec![from_acc.nonce], vec![(
vec![( to_npk.clone(),
to_npk.clone(), to_ipk.clone(),
to_ipk.clone(), eph_holder.generate_ephemeral_public_key(),
eph_holder.generate_ephemeral_public_key(), )],
)], output,
output, )
) .unwrap();
.unwrap();
let signing_key = self.storage.user_data.get_pub_account_signing_key(&from); let signing_key = self.storage.user_data.get_pub_account_signing_key(&from);
@ -148,17 +142,8 @@ impl WalletCore {
return Err(ExecutionFailureKind::KeyNotFoundError); return Err(ExecutionFailureKind::KeyNotFoundError);
}; };
let witness_set = let witness_set = WitnessSet::for_message(&message, proof, &[signing_key]);
nssa::privacy_preserving_transaction::witness_set::WitnessSet::for_message( let tx = PrivacyPreservingTransaction::new(message, witness_set);
&message,
proof,
&[signing_key],
);
let tx = nssa::privacy_preserving_transaction::PrivacyPreservingTransaction::new(
message,
witness_set,
);
Ok(( Ok((
self.sequencer_client.send_tx_private(tx).await?, self.sequencer_client.send_tx_private(tx).await?,