diff --git a/.deny.toml b/.deny.toml index 320a9eda..fb1ce3cf 100644 --- a/.deny.toml +++ b/.deny.toml @@ -16,7 +16,6 @@ ignore = [ { id = "RUSTSEC-2026-0097", reason = "`rand` v0.8.5 is present transitively from logos crates, modification may break integration" }, { id = "RUSTSEC-2026-0118", reason = "`hickory-proto` v0.25.0-alpha.5 is present transitively from logos crates, modification may break integration" }, { id = "RUSTSEC-2026-0119", reason = "`hickory-proto` v0.25.0-alpha.5 is present transitively from logos crates, modification may break integration" }, - { id = "RUSTSEC-2026-0145", reason = "`astral-tokio-tar` v0.6.1 is pulled transitively via testcontainers (integration_tests dev/test path); waiting on upstream fix" }, ] yanked = "deny" unused-ignored-advisory = "deny" diff --git a/Cargo.lock b/Cargo.lock index 416dd653..e81f6326 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -674,9 +674,9 @@ checksum = "4858a9d740c5007a9069007c3b4e91152d0506f13c1b31dd49051fd537656156" [[package]] name = "astral-tokio-tar" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ce73b17c62717c4b6a9af10b43e87c578b0cac27e00666d48304d3b7d2c0693" +checksum = "cb50a7aae84a03bf55b067832bc376f4961b790c97e64d3eacee97d389b90277" dependencies = [ "filetime", "futures-core", @@ -2262,7 +2262,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -2582,7 +2582,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3561,7 +3561,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.3", + "socket2 0.5.10", "tokio", "tower-service", "tracing", @@ -6381,7 +6381,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -7235,7 +7235,7 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls", - "socket2 0.6.3", + "socket2 0.5.10", "thiserror 2.0.18", "tokio", "tracing", @@ -7272,9 +7272,9 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.3", + "socket2 0.5.10", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -8167,7 +8167,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -8225,7 +8225,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs 0.26.11", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -9138,7 +9138,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -10469,7 +10469,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -10608,15 +10608,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.61.2" diff --git a/examples/program_deployment/README.md b/examples/program_deployment/README.md index 61e530e3..11952c35 100644 --- a/examples/program_deployment/README.md +++ b/examples/program_deployment/README.md @@ -332,7 +332,7 @@ Unlike the public version, `run_hello_world_private.rs` must: Luckily all that complexity is hidden behind the `wallet_core.send_privacy_preserving_tx` function: ```rust - let accounts = vec![PrivacyPreservingAccount::PrivateOwned(account_id)]; + let accounts = vec![AccountIdentity::PrivateOwned(account_id)]; // Construct and submit the privacy-preserving transaction wallet_core diff --git a/examples/program_deployment/src/bin/run_hello_world_private.rs b/examples/program_deployment/src/bin/run_hello_world_private.rs index 27ac2079..725019f1 100644 --- a/examples/program_deployment/src/bin/run_hello_world_private.rs +++ b/examples/program_deployment/src/bin/run_hello_world_private.rs @@ -1,5 +1,5 @@ use nssa::{AccountId, program::Program}; -use wallet::{PrivacyPreservingAccount, WalletCore}; +use wallet::{AccountIdentity, WalletCore}; // Before running this example, compile the `hello_world.rs` guest program with: // @@ -44,7 +44,7 @@ async fn main() { // Define the desired greeting in ASCII let greeting: Vec = vec![72, 111, 108, 97, 32, 109, 117, 110, 100, 111, 33]; - let accounts = vec![PrivacyPreservingAccount::PrivateOwned(account_id)]; + let accounts = vec![AccountIdentity::PrivateOwned(account_id)]; // Construct and submit the privacy-preserving transaction wallet_core diff --git a/examples/program_deployment/src/bin/run_hello_world_through_tail_call_private.rs b/examples/program_deployment/src/bin/run_hello_world_through_tail_call_private.rs index 4fac3eec..d68e99dc 100644 --- a/examples/program_deployment/src/bin/run_hello_world_through_tail_call_private.rs +++ b/examples/program_deployment/src/bin/run_hello_world_through_tail_call_private.rs @@ -4,7 +4,7 @@ use nssa::{ AccountId, ProgramId, privacy_preserving_transaction::circuit::ProgramWithDependencies, program::Program, }; -use wallet::{PrivacyPreservingAccount, WalletCore}; +use wallet::{AccountIdentity, WalletCore}; // Before running this example, compile the `simple_tail_call.rs` guest program with: // @@ -51,7 +51,7 @@ async fn main() { std::iter::once((hello_world.id(), hello_world)).collect(); let program_with_dependencies = ProgramWithDependencies::new(simple_tail_call, dependencies); - let accounts = vec![PrivacyPreservingAccount::PrivateOwned(account_id)]; + let accounts = vec![AccountIdentity::PrivateOwned(account_id)]; // Construct and submit the privacy-preserving transaction let instruction = (); diff --git a/examples/program_deployment/src/bin/run_hello_world_with_move_function.rs b/examples/program_deployment/src/bin/run_hello_world_with_move_function.rs index a1c2517e..e6f667a6 100644 --- a/examples/program_deployment/src/bin/run_hello_world_with_move_function.rs +++ b/examples/program_deployment/src/bin/run_hello_world_with_move_function.rs @@ -2,7 +2,7 @@ use clap::{Parser, Subcommand}; use common::transaction::NSSATransaction; use nssa::{PublicTransaction, program::Program, public_transaction}; use sequencer_service_rpc::RpcClient as _; -use wallet::{PrivacyPreservingAccount, WalletCore}; +use wallet::{AccountIdentity, WalletCore}; // Before running this example, compile the `hello_world_with_move_function.rs` guest program with: // @@ -99,7 +99,7 @@ async fn main() { } => { let instruction: Instruction = (WRITE_FUNCTION_ID, greeting.into_bytes()); let account_id = account_id.parse().unwrap(); - let accounts = vec![PrivacyPreservingAccount::PrivateOwned(account_id)]; + let accounts = vec![AccountIdentity::PrivateOwned(account_id)]; wallet_core .send_privacy_preserving_tx( @@ -138,8 +138,8 @@ async fn main() { let to = to.parse().unwrap(); let accounts = vec![ - PrivacyPreservingAccount::Public(from), - PrivacyPreservingAccount::PrivateOwned(to), + AccountIdentity::Public(from), + AccountIdentity::PrivateOwned(to), ]; wallet_core diff --git a/integration_tests/tests/private_pda.rs b/integration_tests/tests/private_pda.rs index f9969d98..0f8d7b8d 100644 --- a/integration_tests/tests/private_pda.rs +++ b/integration_tests/tests/private_pda.rs @@ -18,7 +18,7 @@ use nssa::{ use nssa_core::{NullifierPublicKey, encryption::ViewingPublicKey, program::PdaSeed}; use tokio::test; use wallet::{ - PrivacyPreservingAccount, WalletCore, + AccountIdentity, WalletCore, cli::{Command, account::AccountSubcommand}, }; @@ -46,8 +46,8 @@ async fn fund_private_pda( wallet .send_privacy_preserving_tx( vec![ - PrivacyPreservingAccount::Public(sender), - PrivacyPreservingAccount::PrivatePdaForeign { + AccountIdentity::Public(sender), + AccountIdentity::PrivatePdaForeign { account_id: pda_account_id, npk, vpk, @@ -83,8 +83,8 @@ async fn spend_private_pda( wallet .send_privacy_preserving_tx( vec![ - PrivacyPreservingAccount::PrivatePdaOwned(pda_account_id), - PrivacyPreservingAccount::PrivateForeign { + AccountIdentity::PrivatePdaOwned(pda_account_id), + AccountIdentity::PrivateForeign { npk: recipient_npk, vpk: recipient_vpk, identifier: 0, diff --git a/test_fixtures/src/setup.rs b/test_fixtures/src/setup.rs index c43590d0..5d7377b1 100644 --- a/test_fixtures/src/setup.rs +++ b/test_fixtures/src/setup.rs @@ -9,9 +9,7 @@ use sequencer_service::{GenesisAction, SequencerHandle}; use sequencer_service_rpc::RpcClient as _; use tempfile::TempDir; use testcontainers::compose::DockerCompose; -use wallet::{ - AccDecodeData::Decode, PrivacyPreservingAccount, WalletCore, config::WalletConfigOverrides, -}; +use wallet::{AccDecodeData::Decode, AccountIdentity, WalletCore, config::WalletConfigOverrides}; use crate::{ BEDROCK_SERVICE_PORT, BEDROCK_SERVICE_WITH_OPEN_PORT, @@ -293,8 +291,8 @@ async fn claim_funds_from_vault_to_private( let (tx_hash, mut secrets) = wallet .send_privacy_preserving_tx( vec![ - PrivacyPreservingAccount::PrivateOwned(owner_id), - PrivacyPreservingAccount::Public(owner_vault_id), + AccountIdentity::PrivateOwned(owner_id), + AccountIdentity::Public(owner_vault_id), ], instruction_data, &program_with_dependencies, diff --git a/wallet/src/privacy_preserving_tx.rs b/wallet/src/account_manager.rs similarity index 91% rename from wallet/src/privacy_preserving_tx.rs rename to wallet/src/account_manager.rs index 005eaf75..2d1127c5 100644 --- a/wallet/src/privacy_preserving_tx.rs +++ b/wallet/src/account_manager.rs @@ -11,8 +11,10 @@ use nssa_core::{ use crate::{ExecutionFailureKind, WalletCore}; #[derive(Clone)] -pub enum PrivacyPreservingAccount { +pub enum AccountIdentity { Public(AccountId), + /// A public account without signing. Would not try to sign, even if account is owned. + PublicNoSign(AccountId), PrivateOwned(AccountId), PrivateForeign { npk: NullifierPublicKey, @@ -50,10 +52,12 @@ pub enum PrivacyPreservingAccount { }, } -impl PrivacyPreservingAccount { +impl AccountIdentity { #[must_use] + /// Note: `PublicNoSign` still counts as public, the variant just suppresses the signing-key + /// lookup. pub const fn is_public(&self) -> bool { - matches!(&self, Self::Public(_)) + matches!(&self, Self::Public(_) | Self::PublicNoSign(_)) } #[must_use] @@ -92,13 +96,13 @@ pub struct AccountManager { impl AccountManager { pub async fn new( wallet: &WalletCore, - accounts: Vec, + accounts: Vec, ) -> Result { let mut states = Vec::with_capacity(accounts.len()); for account in accounts { let state = match account { - PrivacyPreservingAccount::Public(account_id) => { + AccountIdentity::Public(account_id) => { let acc = wallet .get_account_public(account_id) .await @@ -109,12 +113,23 @@ impl AccountManager { State::Public { account, sk } } - PrivacyPreservingAccount::PrivateOwned(account_id) => { + AccountIdentity::PublicNoSign(account_id) => { + let acc = wallet + .get_account_public(account_id) + .await + .map_err(ExecutionFailureKind::SequencerError)?; + + let sk = None; + let account = AccountWithMetadata::new(acc.clone(), sk.is_some(), account_id); + + State::Public { account, sk } + } + AccountIdentity::PrivateOwned(account_id) => { let pre = private_key_tree_acc_preparation(wallet, account_id, false).await?; State::Private(pre) } - PrivacyPreservingAccount::PrivateForeign { + AccountIdentity::PrivateForeign { npk, vpk, identifier, @@ -138,11 +153,11 @@ impl AccountManager { State::Private(pre) } - PrivacyPreservingAccount::PrivatePdaOwned(account_id) => { + AccountIdentity::PrivatePdaOwned(account_id) => { let pre = private_key_tree_acc_preparation(wallet, account_id, true).await?; State::Private(pre) } - PrivacyPreservingAccount::PrivatePdaForeign { + AccountIdentity::PrivatePdaForeign { account_id, npk, vpk, @@ -166,7 +181,7 @@ impl AccountManager { }; State::Private(pre) } - PrivacyPreservingAccount::PrivateShared { + AccountIdentity::PrivateShared { nsk, npk, vpk, @@ -180,7 +195,7 @@ impl AccountManager { State::Private(pre) } - PrivacyPreservingAccount::PrivatePdaShared { + AccountIdentity::PrivatePdaShared { account_id, nsk, npk, @@ -410,7 +425,7 @@ mod tests { #[test] fn private_shared_is_private() { - let acc = PrivacyPreservingAccount::PrivateShared { + let acc = AccountIdentity::PrivateShared { nsk: [0; 32], npk: NullifierPublicKey([1; 32]), vpk: ViewingPublicKey::from_scalar([2; 32]), diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index bfbe7145..ba368355 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -9,6 +9,7 @@ use std::path::PathBuf; +pub use account_manager::AccountIdentity; use anyhow::{Context as _, Result}; use bip39::Mnemonic; use common::{HashType, transaction::NSSATransaction}; @@ -24,7 +25,6 @@ use nssa::{ use nssa_core::{ Commitment, MembershipProof, SharedSecretKey, account::Nonce, program::InstructionData, }; -pub use privacy_preserving_tx::PrivacyPreservingAccount; use sequencer_service_rpc::{RpcClient as _, SequencerClient, SequencerClientBuilder}; use storage::Storage; use tokio::io::AsyncWriteExt as _; @@ -37,11 +37,11 @@ use crate::{ }; pub mod account; +mod account_manager; pub mod cli; pub mod config; pub mod helperfunctions; pub mod poller; -mod privacy_preserving_tx; pub mod program_facades; pub mod storage; @@ -270,13 +270,10 @@ impl WalletCore { self.storage.key_chain_mut().set_sealing_secret_key(key); } - /// Resolve an `AccountId` to the appropriate `PrivacyPreservingAccount` variant. + /// Resolve an `AccountId` to the appropriate `AccountIdentity` variant. /// Checks the key tree first, then shared private accounts. #[must_use] - pub fn resolve_private_account( - &self, - account_id: nssa::AccountId, - ) -> Option { + pub fn resolve_private_account(&self, account_id: nssa::AccountId) -> Option { // Check key tree first if self .storage @@ -284,7 +281,7 @@ impl WalletCore { .private_account(account_id) .is_some() { - return Some(PrivacyPreservingAccount::PrivateOwned(account_id)); + return Some(AccountIdentity::PrivateOwned(account_id)); } // Check shared private accounts @@ -299,7 +296,7 @@ impl WalletCore { if let (Some(pda_seed), Some(program_id)) = (entry.pda_seed, entry.pda_program_id) { let keys = holder.derive_keys_for_pda(&program_id, &pda_seed); - Some(PrivacyPreservingAccount::PrivatePdaShared { + Some(AccountIdentity::PrivatePdaShared { account_id, nsk: keys.nullifier_secret_key, npk: keys.generate_nullifier_public_key(), @@ -316,7 +313,7 @@ impl WalletCore { result }; let keys = holder.derive_keys_for_shared_account(&derivation_seed); - Some(PrivacyPreservingAccount::PrivateShared { + Some(AccountIdentity::PrivateShared { nsk: keys.nullifier_secret_key, npk: keys.generate_nullifier_public_key(), vpk: keys.generate_viewing_public_key(), @@ -541,7 +538,7 @@ impl WalletCore { pub async fn send_privacy_preserving_tx( &self, - accounts: Vec, + accounts: Vec, instruction_data: InstructionData, program: &ProgramWithDependencies, ) -> Result<(HashType, Vec), ExecutionFailureKind> { @@ -553,12 +550,12 @@ impl WalletCore { pub async fn send_privacy_preserving_tx_with_pre_check( &self, - accounts: Vec, + accounts: Vec, instruction_data: InstructionData, program: &ProgramWithDependencies, tx_pre_check: impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>, ) -> Result<(HashType, Vec), ExecutionFailureKind> { - let acc_manager = privacy_preserving_tx::AccountManager::new(self, accounts).await?; + let acc_manager = account_manager::AccountManager::new(self, accounts).await?; let pre_states = acc_manager.pre_states(); tx_pre_check( @@ -610,6 +607,65 @@ impl WalletCore { )) } + pub async fn send_pub_tx( + &self, + accounts: Vec, + instruction_data: InstructionData, + program: &ProgramWithDependencies, + ) -> Result { + self.send_pub_tx_with_pre_check(accounts, instruction_data, program, |_| Ok(())) + .await + } + + pub async fn send_pub_tx_with_pre_check( + &self, + accounts: Vec, + instruction_data: InstructionData, + program: &ProgramWithDependencies, + tx_pre_check: impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>, + ) -> Result { + // Public transaction, all accounts must be public + if accounts.iter().any(AccountIdentity::is_private) { + return Err(ExecutionFailureKind::TransactionBuildError( + nssa::error::NssaError::InvalidInput( + "Private accounts are not allowed in public transactions".to_owned(), + ), + )); + } + + let acc_manager = account_manager::AccountManager::new(self, accounts).await?; + + let pre_states = acc_manager.pre_states(); + tx_pre_check( + &pre_states + .iter() + .map(|pre| &pre.account) + .collect::>(), + )?; + + let account_ids = acc_manager.public_account_ids(); + let program_id = program.program.id(); + let nonces = acc_manager.public_account_nonces(); + let private_keys = acc_manager.public_account_auth(); + + let message = nssa::public_transaction::Message::new_preserialized( + program_id, + account_ids, + nonces, + instruction_data, + ); + + let witness_set = + nssa::public_transaction::WitnessSet::for_message(&message, &private_keys); + + let tx = nssa::public_transaction::PublicTransaction::new(message, witness_set); + + Ok(self + .sequencer_client + .send_transaction(NSSATransaction::Public(tx)) + .await?) + } + pub async fn sync_to_latest_block(&mut self) -> Result { let latest_block_id = self.sequencer_client.get_last_block_id().await?; println!("Latest block is {latest_block_id}"); diff --git a/wallet/src/program_facades/amm.rs b/wallet/src/program_facades/amm.rs index 2ac2ab79..b84cb5d0 100644 --- a/wallet/src/program_facades/amm.rs +++ b/wallet/src/program_facades/amm.rs @@ -1,10 +1,9 @@ use amm_core::{compute_liquidity_token_pda, compute_pool_pda, compute_vault_pda}; -use common::{HashType, transaction::NSSATransaction}; +use common::HashType; use nssa::{AccountId, program::Program}; -use sequencer_service_rpc::RpcClient as _; use token_core::TokenHolding; -use crate::{ExecutionFailureKind, WalletCore}; +use crate::{AccountIdentity, ExecutionFailureKind, WalletCore}; pub struct Amm<'wallet>(pub &'wallet WalletCore); impl Amm<'_> { @@ -18,12 +17,6 @@ impl Amm<'_> { ) -> Result { let program = Program::amm(); let amm_program_id = Program::amm().id(); - let instruction = amm_core::Instruction::NewDefinition { - token_a_amount: balance_a, - token_b_amount: balance_b, - amm_program_id, - }; - let user_a_acc = self .0 .get_account_public(user_holding_a) @@ -47,78 +40,29 @@ impl Amm<'_> { let vault_holding_a = compute_vault_pda(amm_program_id, amm_pool, definition_token_a_id); let vault_holding_b = compute_vault_pda(amm_program_id, amm_pool, definition_token_b_id); let pool_lp = compute_liquidity_token_pda(amm_program_id, amm_pool); + let instruction = amm_core::Instruction::NewDefinition { + token_a_amount: balance_a, + token_b_amount: balance_b, + amm_program_id, + }; + let instruction_data = + Program::serialize_instruction(instruction).expect("Instruction should serialize"); - let account_ids = vec![ - amm_pool, - vault_holding_a, - vault_holding_b, - pool_lp, - user_holding_a, - user_holding_b, - user_holding_lp, - ]; - - let mut nonces = self - .0 - .get_accounts_nonces(vec![user_holding_a, user_holding_b]) + self.0 + .send_pub_tx( + vec![ + AccountIdentity::PublicNoSign(amm_pool), + AccountIdentity::PublicNoSign(vault_holding_a), + AccountIdentity::PublicNoSign(vault_holding_b), + AccountIdentity::PublicNoSign(pool_lp), + AccountIdentity::Public(user_holding_a), + AccountIdentity::Public(user_holding_b), + AccountIdentity::Public(user_holding_lp), + ], + instruction_data, + &program.into(), + ) .await - .map_err(ExecutionFailureKind::SequencerError)?; - - let mut private_keys = Vec::new(); - - let signing_key_a = self - .0 - .storage - .key_chain() - .pub_account_signing_key(user_holding_a) - .ok_or(ExecutionFailureKind::KeyNotFoundError)?; - private_keys.push(signing_key_a); - - let signing_key_b = self - .0 - .storage - .key_chain() - .pub_account_signing_key(user_holding_b) - .ok_or(ExecutionFailureKind::KeyNotFoundError)?; - private_keys.push(signing_key_b); - - if let Some(signing_key_lp) = self - .0 - .storage - .key_chain() - .pub_account_signing_key(user_holding_lp) - { - private_keys.push(signing_key_lp); - let lp_nonces = self - .0 - .get_accounts_nonces(vec![user_holding_lp]) - .await - .map_err(ExecutionFailureKind::SequencerError)?; - nonces.extend(lp_nonces); - } else { - println!( - "Liquidity pool tokens receiver's account ({user_holding_lp}) private key not found in wallet. Proceeding with only liquidity provider's keys." - ); - } - - let message = nssa::public_transaction::Message::try_new( - program.id(), - account_ids, - nonces, - instruction, - ) - .unwrap(); - - let witness_set = - nssa::public_transaction::WitnessSet::for_message(&message, &private_keys); - - let tx = nssa::PublicTransaction::new(message, witness_set); - - Ok(self - .0 - .sequencer_client - .send_transaction(NSSATransaction::Public(tx)) - .await?) } pub async fn send_swap_exact_input( @@ -129,14 +73,8 @@ impl Amm<'_> { min_amount_out: u128, token_definition_id_in: AccountId, ) -> Result { - let instruction = amm_core::Instruction::SwapExactInput { - swap_amount_in, - min_amount_out, - token_definition_id_in, - }; let program = Program::amm(); let amm_program_id = Program::amm().id(); - let user_a_acc = self .0 .get_account_public(user_holding_a) @@ -159,56 +97,47 @@ impl Amm<'_> { compute_pool_pda(amm_program_id, definition_token_a_id, definition_token_b_id); let vault_holding_a = compute_vault_pda(amm_program_id, amm_pool, definition_token_a_id); let vault_holding_b = compute_vault_pda(amm_program_id, amm_pool, definition_token_b_id); + let instruction = amm_core::Instruction::SwapExactInput { + swap_amount_in, + min_amount_out, + token_definition_id_in, + }; + let instruction_data = + Program::serialize_instruction(instruction).expect("Instruction should serialize"); - let account_ids = vec![ - amm_pool, - vault_holding_a, - vault_holding_b, - user_holding_a, - user_holding_b, - ]; - - let account_id_auth = if definition_token_a_id == token_definition_id_in { - user_holding_a - } else if definition_token_b_id == token_definition_id_in { - user_holding_b - } else { + if (token_definition_id_in != definition_token_a_id) + && (token_definition_id_in != definition_token_b_id) + { return Err(ExecutionFailureKind::AccountDataError( token_definition_id_in, )); + } + + let user_a_signing_identity = if token_definition_id_in == definition_token_a_id { + AccountIdentity::Public(user_holding_a) + } else { + AccountIdentity::PublicNoSign(user_holding_a) }; - let nonces = self - .0 - .get_accounts_nonces(vec![account_id_auth]) + let user_b_signing_identity = if token_definition_id_in == definition_token_b_id { + AccountIdentity::Public(user_holding_b) + } else { + AccountIdentity::PublicNoSign(user_holding_b) + }; + + self.0 + .send_pub_tx( + vec![ + AccountIdentity::PublicNoSign(amm_pool), + AccountIdentity::PublicNoSign(vault_holding_a), + AccountIdentity::PublicNoSign(vault_holding_b), + user_a_signing_identity, + user_b_signing_identity, + ], + instruction_data, + &program.into(), + ) .await - .map_err(ExecutionFailureKind::SequencerError)?; - - let signing_key = self - .0 - .storage - .key_chain() - .pub_account_signing_key(account_id_auth) - .ok_or(ExecutionFailureKind::KeyNotFoundError)?; - - let message = nssa::public_transaction::Message::try_new( - program.id(), - account_ids, - nonces, - instruction, - ) - .unwrap(); - - let witness_set = - nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]); - - let tx = nssa::PublicTransaction::new(message, witness_set); - - Ok(self - .0 - .sequencer_client - .send_transaction(NSSATransaction::Public(tx)) - .await?) } pub async fn send_swap_exact_output( @@ -219,14 +148,8 @@ impl Amm<'_> { max_amount_in: u128, token_definition_id_in: AccountId, ) -> Result { - let instruction = amm_core::Instruction::SwapExactOutput { - exact_amount_out, - max_amount_in, - token_definition_id_in, - }; let program = Program::amm(); let amm_program_id = Program::amm().id(); - let user_a_acc = self .0 .get_account_public(user_holding_a) @@ -249,56 +172,47 @@ impl Amm<'_> { compute_pool_pda(amm_program_id, definition_token_a_id, definition_token_b_id); let vault_holding_a = compute_vault_pda(amm_program_id, amm_pool, definition_token_a_id); let vault_holding_b = compute_vault_pda(amm_program_id, amm_pool, definition_token_b_id); + let instruction = amm_core::Instruction::SwapExactOutput { + exact_amount_out, + max_amount_in, + token_definition_id_in, + }; + let instruction_data = + Program::serialize_instruction(instruction).expect("Instruction should serialize"); - let account_ids = vec![ - amm_pool, - vault_holding_a, - vault_holding_b, - user_holding_a, - user_holding_b, - ]; - - let account_id_auth = if definition_token_a_id == token_definition_id_in { - user_holding_a - } else if definition_token_b_id == token_definition_id_in { - user_holding_b - } else { + if (token_definition_id_in != definition_token_a_id) + && (token_definition_id_in != definition_token_b_id) + { return Err(ExecutionFailureKind::AccountDataError( token_definition_id_in, )); + } + + let user_a_signing_identity = if token_definition_id_in == definition_token_a_id { + AccountIdentity::Public(user_holding_a) + } else { + AccountIdentity::PublicNoSign(user_holding_a) }; - let nonces = self - .0 - .get_accounts_nonces(vec![account_id_auth]) + let user_b_signing_identity = if token_definition_id_in == definition_token_b_id { + AccountIdentity::Public(user_holding_b) + } else { + AccountIdentity::PublicNoSign(user_holding_b) + }; + + self.0 + .send_pub_tx( + vec![ + AccountIdentity::PublicNoSign(amm_pool), + AccountIdentity::PublicNoSign(vault_holding_a), + AccountIdentity::PublicNoSign(vault_holding_b), + user_a_signing_identity, + user_b_signing_identity, + ], + instruction_data, + &program.into(), + ) .await - .map_err(ExecutionFailureKind::SequencerError)?; - - let signing_key = self - .0 - .storage - .key_chain() - .pub_account_signing_key(account_id_auth) - .ok_or(ExecutionFailureKind::KeyNotFoundError)?; - - let message = nssa::public_transaction::Message::try_new( - program.id(), - account_ids, - nonces, - instruction, - ) - .unwrap(); - - let witness_set = - nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]); - - let tx = nssa::PublicTransaction::new(message, witness_set); - - Ok(self - .0 - .sequencer_client - .send_transaction(NSSATransaction::Public(tx)) - .await?) } pub async fn send_add_liquidity( @@ -310,14 +224,8 @@ impl Amm<'_> { max_amount_to_add_token_a: u128, max_amount_to_add_token_b: u128, ) -> Result { - let instruction = amm_core::Instruction::AddLiquidity { - min_amount_liquidity, - max_amount_to_add_token_a, - max_amount_to_add_token_b, - }; let program = Program::amm(); let amm_program_id = Program::amm().id(); - let user_a_acc = self .0 .get_account_public(user_holding_a) @@ -341,57 +249,29 @@ impl Amm<'_> { let vault_holding_a = compute_vault_pda(amm_program_id, amm_pool, definition_token_a_id); let vault_holding_b = compute_vault_pda(amm_program_id, amm_pool, definition_token_b_id); let pool_lp = compute_liquidity_token_pda(amm_program_id, amm_pool); + let instruction = amm_core::Instruction::AddLiquidity { + min_amount_liquidity, + max_amount_to_add_token_a, + max_amount_to_add_token_b, + }; + let instruction_data = + Program::serialize_instruction(instruction).expect("Instruction should serialize"); - let account_ids = vec![ - amm_pool, - vault_holding_a, - vault_holding_b, - pool_lp, - user_holding_a, - user_holding_b, - user_holding_lp, - ]; - - let nonces = self - .0 - .get_accounts_nonces(vec![user_holding_a, user_holding_b]) + self.0 + .send_pub_tx( + vec![ + AccountIdentity::PublicNoSign(amm_pool), + AccountIdentity::PublicNoSign(vault_holding_a), + AccountIdentity::PublicNoSign(vault_holding_b), + AccountIdentity::PublicNoSign(pool_lp), + AccountIdentity::Public(user_holding_a), + AccountIdentity::Public(user_holding_b), + AccountIdentity::PublicNoSign(user_holding_lp), + ], + instruction_data, + &program.into(), + ) .await - .map_err(ExecutionFailureKind::SequencerError)?; - - let signing_key_a = self - .0 - .storage - .key_chain() - .pub_account_signing_key(user_holding_a) - .ok_or(ExecutionFailureKind::KeyNotFoundError)?; - - let signing_key_b = self - .0 - .storage - .key_chain() - .pub_account_signing_key(user_holding_b) - .ok_or(ExecutionFailureKind::KeyNotFoundError)?; - - let message = nssa::public_transaction::Message::try_new( - program.id(), - account_ids, - nonces, - instruction, - ) - .unwrap(); - - let witness_set = nssa::public_transaction::WitnessSet::for_message( - &message, - &[signing_key_a, signing_key_b], - ); - - let tx = nssa::PublicTransaction::new(message, witness_set); - - Ok(self - .0 - .sequencer_client - .send_transaction(NSSATransaction::Public(tx)) - .await?) } pub async fn send_remove_liquidity( @@ -403,14 +283,8 @@ impl Amm<'_> { min_amount_to_remove_token_a: u128, min_amount_to_remove_token_b: u128, ) -> Result { - let instruction = amm_core::Instruction::RemoveLiquidity { - remove_liquidity_amount, - min_amount_to_remove_token_a, - min_amount_to_remove_token_b, - }; let program = Program::amm(); let amm_program_id = Program::amm().id(); - let user_a_acc = self .0 .get_account_public(user_holding_a) @@ -434,47 +308,28 @@ impl Amm<'_> { let vault_holding_a = compute_vault_pda(amm_program_id, amm_pool, definition_token_a_id); let vault_holding_b = compute_vault_pda(amm_program_id, amm_pool, definition_token_b_id); let pool_lp = compute_liquidity_token_pda(amm_program_id, amm_pool); + let instruction = amm_core::Instruction::RemoveLiquidity { + remove_liquidity_amount, + min_amount_to_remove_token_a, + min_amount_to_remove_token_b, + }; + let instruction_data = + Program::serialize_instruction(instruction).expect("Instruction should serialize"); - let account_ids = vec![ - amm_pool, - vault_holding_a, - vault_holding_b, - pool_lp, - user_holding_a, - user_holding_b, - user_holding_lp, - ]; - - let nonces = self - .0 - .get_accounts_nonces(vec![user_holding_lp]) + self.0 + .send_pub_tx( + vec![ + AccountIdentity::PublicNoSign(amm_pool), + AccountIdentity::PublicNoSign(vault_holding_a), + AccountIdentity::PublicNoSign(vault_holding_b), + AccountIdentity::PublicNoSign(pool_lp), + AccountIdentity::PublicNoSign(user_holding_a), + AccountIdentity::PublicNoSign(user_holding_b), + AccountIdentity::Public(user_holding_lp), + ], + instruction_data, + &program.into(), + ) .await - .map_err(ExecutionFailureKind::SequencerError)?; - - let signing_key_lp = self - .0 - .storage - .key_chain() - .pub_account_signing_key(user_holding_lp) - .ok_or(ExecutionFailureKind::KeyNotFoundError)?; - - let message = nssa::public_transaction::Message::try_new( - program.id(), - account_ids, - nonces, - instruction, - ) - .unwrap(); - - let witness_set = - nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key_lp]); - - let tx = nssa::PublicTransaction::new(message, witness_set); - - Ok(self - .0 - .sequencer_client - .send_transaction(NSSATransaction::Public(tx)) - .await?) } } diff --git a/wallet/src/program_facades/ata.rs b/wallet/src/program_facades/ata.rs index bdb72620..68d45bbe 100644 --- a/wallet/src/program_facades/ata.rs +++ b/wallet/src/program_facades/ata.rs @@ -1,14 +1,13 @@ use std::collections::HashMap; use ata_core::{compute_ata_seed, get_associated_token_account_id}; -use common::{HashType, transaction::NSSATransaction}; +use common::HashType; use nssa::{ AccountId, privacy_preserving_transaction::circuit::ProgramWithDependencies, program::Program, }; use nssa_core::SharedSecretKey; -use sequencer_service_rpc::RpcClient as _; -use crate::{ExecutionFailureKind, PrivacyPreservingAccount, WalletCore}; +use crate::{AccountIdentity, ExecutionFailureKind, WalletCore}; pub struct Ata<'wallet>(pub &'wallet WalletCore); @@ -24,38 +23,21 @@ impl Ata<'_> { &ata_program_id, &compute_ata_seed(owner_id, definition_id), ); - - let account_ids = vec![owner_id, definition_id, ata_id]; - - let nonces = self - .0 - .get_accounts_nonces(vec![owner_id]) - .await - .map_err(ExecutionFailureKind::SequencerError)?; - - let Some(signing_key) = self.0.storage.key_chain().pub_account_signing_key(owner_id) else { - return Err(ExecutionFailureKind::KeyNotFoundError); - }; - let instruction = ata_core::Instruction::Create { ata_program_id }; + let instruction_data = + Program::serialize_instruction(instruction).expect("Instruction should serialize"); - let message = nssa::public_transaction::Message::try_new( - program.id(), - account_ids, - nonces, - instruction, - )?; - - let witness_set = - nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]); - - let tx = nssa::PublicTransaction::new(message, witness_set); - - Ok(self - .0 - .sequencer_client - .send_transaction(NSSATransaction::Public(tx)) - .await?) + self.0 + .send_pub_tx( + vec![ + AccountIdentity::Public(owner_id), + AccountIdentity::PublicNoSign(definition_id), + AccountIdentity::PublicNoSign(ata_id), + ], + instruction_data, + &program.into(), + ) + .await } pub async fn send_transfer( @@ -71,41 +53,24 @@ impl Ata<'_> { &ata_program_id, &compute_ata_seed(owner_id, definition_id), ); - - let account_ids = vec![owner_id, sender_ata_id, recipient_id]; - - let nonces = self - .0 - .get_accounts_nonces(vec![owner_id]) - .await - .map_err(ExecutionFailureKind::SequencerError)?; - - let Some(signing_key) = self.0.storage.key_chain().pub_account_signing_key(owner_id) else { - return Err(ExecutionFailureKind::KeyNotFoundError); - }; - let instruction = ata_core::Instruction::Transfer { ata_program_id, amount, }; + let instruction_data = + Program::serialize_instruction(instruction).expect("Instruction should serialize"); - let message = nssa::public_transaction::Message::try_new( - program.id(), - account_ids, - nonces, - instruction, - )?; - - let witness_set = - nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]); - - let tx = nssa::PublicTransaction::new(message, witness_set); - - Ok(self - .0 - .sequencer_client - .send_transaction(NSSATransaction::Public(tx)) - .await?) + self.0 + .send_pub_tx( + vec![ + AccountIdentity::Public(owner_id), + AccountIdentity::PublicNoSign(sender_ata_id), + AccountIdentity::PublicNoSign(recipient_id), + ], + instruction_data, + &program.into(), + ) + .await } pub async fn send_burn( @@ -120,41 +85,24 @@ impl Ata<'_> { &ata_program_id, &compute_ata_seed(owner_id, definition_id), ); - - let account_ids = vec![owner_id, holder_ata_id, definition_id]; - - let nonces = self - .0 - .get_accounts_nonces(vec![owner_id]) - .await - .map_err(ExecutionFailureKind::SequencerError)?; - - let Some(signing_key) = self.0.storage.key_chain().pub_account_signing_key(owner_id) else { - return Err(ExecutionFailureKind::KeyNotFoundError); - }; - let instruction = ata_core::Instruction::Burn { ata_program_id, amount, }; + let instruction_data = + Program::serialize_instruction(instruction).expect("Instruction should serialize"); - let message = nssa::public_transaction::Message::try_new( - program.id(), - account_ids, - nonces, - instruction, - )?; - - let witness_set = - nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]); - - let tx = nssa::PublicTransaction::new(message, witness_set); - - Ok(self - .0 - .sequencer_client - .send_transaction(NSSATransaction::Public(tx)) - .await?) + self.0 + .send_pub_tx( + vec![ + AccountIdentity::Public(owner_id), + AccountIdentity::PublicNoSign(holder_ata_id), + AccountIdentity::PublicNoSign(definition_id), + ], + instruction_data, + &program.into(), + ) + .await } pub async fn send_create_private_owner( @@ -176,8 +124,8 @@ impl Ata<'_> { self.0 .resolve_private_account(owner_id) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, - PrivacyPreservingAccount::Public(definition_id), - PrivacyPreservingAccount::Public(ata_id), + AccountIdentity::Public(definition_id), + AccountIdentity::Public(ata_id), ]; self.0 @@ -213,8 +161,8 @@ impl Ata<'_> { self.0 .resolve_private_account(owner_id) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, - PrivacyPreservingAccount::Public(sender_ata_id), - PrivacyPreservingAccount::Public(recipient_id), + AccountIdentity::Public(sender_ata_id), + AccountIdentity::Public(recipient_id), ]; self.0 @@ -249,8 +197,8 @@ impl Ata<'_> { self.0 .resolve_private_account(owner_id) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, - PrivacyPreservingAccount::Public(holder_ata_id), - PrivacyPreservingAccount::Public(definition_id), + AccountIdentity::Public(holder_ata_id), + AccountIdentity::Public(definition_id), ]; self.0 diff --git a/wallet/src/program_facades/native_token_transfer/deshielded.rs b/wallet/src/program_facades/native_token_transfer/deshielded.rs index d4bde39f..31374f99 100644 --- a/wallet/src/program_facades/native_token_transfer/deshielded.rs +++ b/wallet/src/program_facades/native_token_transfer/deshielded.rs @@ -2,7 +2,7 @@ use common::HashType; use nssa::AccountId; use super::{NativeTokenTransfer, auth_transfer_preparation}; -use crate::{ExecutionFailureKind, PrivacyPreservingAccount}; +use crate::{AccountIdentity, ExecutionFailureKind}; impl NativeTokenTransfer<'_> { pub async fn send_deshielded_transfer( @@ -19,7 +19,7 @@ impl NativeTokenTransfer<'_> { self.0 .resolve_private_account(from) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, - PrivacyPreservingAccount::Public(to), + AccountIdentity::Public(to), ], instruction_data, &program.into(), diff --git a/wallet/src/program_facades/native_token_transfer/private.rs b/wallet/src/program_facades/native_token_transfer/private.rs index e8438d08..481e4a5f 100644 --- a/wallet/src/program_facades/native_token_transfer/private.rs +++ b/wallet/src/program_facades/native_token_transfer/private.rs @@ -5,7 +5,7 @@ use nssa::{AccountId, program::Program}; use nssa_core::{Identifier, NullifierPublicKey, SharedSecretKey, encryption::ViewingPublicKey}; use super::{NativeTokenTransfer, auth_transfer_preparation}; -use crate::{ExecutionFailureKind, PrivacyPreservingAccount}; +use crate::{AccountIdentity, ExecutionFailureKind}; impl NativeTokenTransfer<'_> { pub async fn register_account_private( @@ -49,7 +49,7 @@ impl NativeTokenTransfer<'_> { self.0 .resolve_private_account(from) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, - PrivacyPreservingAccount::PrivateForeign { + AccountIdentity::PrivateForeign { npk: to_npk, vpk: to_vpk, identifier: to_identifier, diff --git a/wallet/src/program_facades/native_token_transfer/public.rs b/wallet/src/program_facades/native_token_transfer/public.rs index ca5c45f9..f1d7699d 100644 --- a/wallet/src/program_facades/native_token_transfer/public.rs +++ b/wallet/src/program_facades/native_token_transfer/public.rs @@ -1,14 +1,12 @@ use authenticated_transfer_core::Instruction as AuthTransferInstruction; -use common::{HashType, transaction::NSSATransaction}; -use nssa::{ - AccountId, PublicTransaction, - program::Program, - public_transaction::{Message, WitnessSet}, -}; -use sequencer_service_rpc::RpcClient as _; +use common::HashType; +use nssa::{AccountId, program::Program}; use super::NativeTokenTransfer; -use crate::ExecutionFailureKind; +use crate::{ + AccountIdentity, ExecutionFailureKind, + program_facades::native_token_transfer::auth_transfer_preparation, +}; impl NativeTokenTransfer<'_> { pub async fn send_public_transfer( @@ -17,101 +15,31 @@ impl NativeTokenTransfer<'_> { to: AccountId, balance_to_move: u128, ) -> Result { - let balance = self - .0 - .get_account_balance(from) - .await - .map_err(ExecutionFailureKind::SequencerError)?; + let (instruction_data, program, tx_pre_check) = auth_transfer_preparation(balance_to_move); - if balance >= balance_to_move { - let account_ids = vec![from, to]; - let program_id = Program::authenticated_transfer_program().id(); - - let mut nonces = self - .0 - .get_accounts_nonces(vec![from]) - .await - .map_err(ExecutionFailureKind::SequencerError)?; - - let mut private_keys = Vec::new(); - let from_signing_key = self.0.storage.key_chain().pub_account_signing_key(from); - let Some(from_signing_key) = from_signing_key else { - return Err(ExecutionFailureKind::KeyNotFoundError); - }; - private_keys.push(from_signing_key); - - let to_signing_key = self.0.storage.key_chain().pub_account_signing_key(to); - if let Some(to_signing_key) = to_signing_key { - private_keys.push(to_signing_key); - let to_nonces = self - .0 - .get_accounts_nonces(vec![to]) - .await - .map_err(ExecutionFailureKind::SequencerError)?; - nonces.extend(to_nonces); - } else { - println!( - "Receiver's account ({to}) private key not found in wallet. Proceeding with only sender's key." - ); - } - - let message = Message::try_new( - program_id, - account_ids, - nonces, - AuthTransferInstruction::Transfer { - amount: balance_to_move, - }, + self.0 + .send_pub_tx_with_pre_check( + vec![AccountIdentity::Public(from), AccountIdentity::Public(to)], + instruction_data, + &program.into(), + tx_pre_check, ) - .unwrap(); - let witness_set = WitnessSet::for_message(&message, &private_keys); - - let tx = PublicTransaction::new(message, witness_set); - - Ok(self - .0 - .sequencer_client - .send_transaction(NSSATransaction::Public(tx)) - .await?) - } else { - Err(ExecutionFailureKind::InsufficientFundsError) - } + .await } pub async fn register_account( &self, from: AccountId, ) -> Result { - let nonces = self - .0 - .get_accounts_nonces(vec![from]) + let instruction_data = Program::serialize_instruction(AuthTransferInstruction::Initialize)?; + let program = Program::authenticated_transfer_program(); + + self.0 + .send_pub_tx( + vec![AccountIdentity::Public(from)], + instruction_data, + &program.into(), + ) .await - .map_err(ExecutionFailureKind::SequencerError)?; - - let account_ids = vec![from]; - let program_id = Program::authenticated_transfer_program().id(); - let message = Message::try_new( - program_id, - account_ids, - nonces, - AuthTransferInstruction::Initialize, - ) - .unwrap(); - - let signing_key = self.0.storage.key_chain().pub_account_signing_key(from); - - let Some(signing_key) = signing_key else { - return Err(ExecutionFailureKind::KeyNotFoundError); - }; - - let witness_set = WitnessSet::for_message(&message, &[signing_key]); - - let tx = PublicTransaction::new(message, witness_set); - - Ok(self - .0 - .sequencer_client - .send_transaction(NSSATransaction::Public(tx)) - .await?) } } diff --git a/wallet/src/program_facades/native_token_transfer/shielded.rs b/wallet/src/program_facades/native_token_transfer/shielded.rs index 98dd0081..44916529 100644 --- a/wallet/src/program_facades/native_token_transfer/shielded.rs +++ b/wallet/src/program_facades/native_token_transfer/shielded.rs @@ -3,7 +3,7 @@ use nssa::AccountId; use nssa_core::{Identifier, NullifierPublicKey, SharedSecretKey, encryption::ViewingPublicKey}; use super::{NativeTokenTransfer, auth_transfer_preparation}; -use crate::{ExecutionFailureKind, PrivacyPreservingAccount}; +use crate::{AccountIdentity, ExecutionFailureKind}; impl NativeTokenTransfer<'_> { pub async fn send_shielded_transfer( @@ -17,7 +17,7 @@ impl NativeTokenTransfer<'_> { self.0 .send_privacy_preserving_tx_with_pre_check( vec![ - PrivacyPreservingAccount::Public(from), + AccountIdentity::Public(from), self.0 .resolve_private_account(to) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, @@ -49,8 +49,8 @@ impl NativeTokenTransfer<'_> { self.0 .send_privacy_preserving_tx_with_pre_check( vec![ - PrivacyPreservingAccount::Public(from), - PrivacyPreservingAccount::PrivateForeign { + AccountIdentity::Public(from), + AccountIdentity::PrivateForeign { npk: to_npk, vpk: to_vpk, identifier: to_identifier, diff --git a/wallet/src/program_facades/pinata.rs b/wallet/src/program_facades/pinata.rs index 0575455e..2e40e78b 100644 --- a/wallet/src/program_facades/pinata.rs +++ b/wallet/src/program_facades/pinata.rs @@ -1,9 +1,8 @@ -use common::{HashType, transaction::NSSATransaction}; -use nssa::AccountId; +use common::HashType; +use nssa::{AccountId, program::Program}; use nssa_core::{MembershipProof, SharedSecretKey}; -use sequencer_service_rpc::RpcClient as _; -use crate::{ExecutionFailureKind, PrivacyPreservingAccount, WalletCore}; +use crate::{AccountIdentity, ExecutionFailureKind, WalletCore}; pub struct Pinata<'wallet>(pub &'wallet WalletCore); @@ -14,20 +13,21 @@ impl Pinata<'_> { winner_account_id: AccountId, solution: u128, ) -> Result { - let account_ids = vec![pinata_account_id, winner_account_id]; - let program_id = nssa::program::Program::pinata().id(); - let message = - nssa::public_transaction::Message::try_new(program_id, account_ids, vec![], solution) - .unwrap(); + let program = Program::pinata(); + let instruction = solution; + let instruction_data = + Program::serialize_instruction(instruction).expect("Instruction should serialize"); - let witness_set = nssa::public_transaction::WitnessSet::for_message(&message, &[]); - let tx = nssa::PublicTransaction::new(message, witness_set); - - Ok(self - .0 - .sequencer_client - .send_transaction(NSSATransaction::Public(tx)) - .await?) + self.0 + .send_pub_tx( + vec![ + AccountIdentity::PublicNoSign(pinata_account_id), + AccountIdentity::PublicNoSign(winner_account_id), + ], + instruction_data, + &program.into(), + ) + .await } /// Claim a pinata reward using a privacy-preserving transaction for an already-initialized @@ -55,7 +55,7 @@ impl Pinata<'_> { self.0 .send_privacy_preserving_tx( vec![ - PrivacyPreservingAccount::Public(pinata_account_id), + AccountIdentity::Public(pinata_account_id), self.0 .resolve_private_account(winner_account_id) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, diff --git a/wallet/src/program_facades/token.rs b/wallet/src/program_facades/token.rs index 7197b1f0..8e9b4f8f 100644 --- a/wallet/src/program_facades/token.rs +++ b/wallet/src/program_facades/token.rs @@ -1,10 +1,9 @@ -use common::{HashType, transaction::NSSATransaction}; +use common::HashType; use nssa::{AccountId, program::Program}; use nssa_core::{Identifier, NullifierPublicKey, SharedSecretKey, encryption::ViewingPublicKey}; -use sequencer_service_rpc::RpcClient as _; use token_core::Instruction; -use crate::{ExecutionFailureKind, PrivacyPreservingAccount, WalletCore}; +use crate::{AccountIdentity, ExecutionFailureKind, WalletCore}; pub struct Token<'wallet>(pub &'wallet WalletCore); @@ -16,47 +15,21 @@ impl Token<'_> { name: String, total_supply: u128, ) -> Result { - let account_ids = vec![definition_account_id, supply_account_id]; - let program_id = nssa::program::Program::token().id(); + let program = Program::token(); let instruction = Instruction::NewFungibleDefinition { name, total_supply }; - let nonces = self - .0 - .get_accounts_nonces(account_ids.clone()) + let instruction_data = + Program::serialize_instruction(instruction).expect("Instruction should serialize"); + + self.0 + .send_pub_tx( + vec![ + AccountIdentity::Public(definition_account_id), + AccountIdentity::Public(supply_account_id), + ], + instruction_data, + &program.into(), + ) .await - .map_err(ExecutionFailureKind::SequencerError)?; - let message = nssa::public_transaction::Message::try_new( - program_id, - account_ids, - nonces, - instruction, - ) - .unwrap(); - - let def_private_key = self - .0 - .storage - .key_chain() - .pub_account_signing_key(definition_account_id) - .ok_or(ExecutionFailureKind::KeyNotFoundError)?; - let supply_private_key = self - .0 - .storage - .key_chain() - .pub_account_signing_key(supply_account_id) - .ok_or(ExecutionFailureKind::KeyNotFoundError)?; - - let witness_set = nssa::public_transaction::WitnessSet::for_message( - &message, - &[def_private_key, supply_private_key], - ); - - let tx = nssa::PublicTransaction::new(message, witness_set); - - Ok(self - .0 - .sequencer_client - .send_transaction(NSSATransaction::Public(tx)) - .await?) } pub async fn send_new_definition_private_owned_supply( @@ -73,7 +46,7 @@ impl Token<'_> { self.0 .send_privacy_preserving_tx( vec![ - PrivacyPreservingAccount::Public(definition_account_id), + AccountIdentity::Public(definition_account_id), self.0 .resolve_private_account(supply_account_id) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, @@ -108,7 +81,7 @@ impl Token<'_> { self.0 .resolve_private_account(definition_account_id) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, - PrivacyPreservingAccount::Public(supply_account_id), + AccountIdentity::Public(supply_account_id), ], instruction_data, &Program::token().into(), @@ -162,62 +135,23 @@ impl Token<'_> { recipient_account_id: AccountId, amount: u128, ) -> Result { - let account_ids = vec![sender_account_id, recipient_account_id]; - let program_id = nssa::program::Program::token().id(); + let program = Program::token(); let instruction = Instruction::Transfer { amount_to_transfer: amount, }; - let mut nonces = self - .0 - .get_accounts_nonces(vec![sender_account_id]) + let instruction_data = + Program::serialize_instruction(instruction).expect("Instruction should serialize"); + + self.0 + .send_pub_tx( + vec![ + AccountIdentity::Public(sender_account_id), + AccountIdentity::Public(recipient_account_id), + ], + instruction_data, + &program.into(), + ) .await - .map_err(ExecutionFailureKind::SequencerError)?; - - let mut private_keys = Vec::new(); - let sender_sk = self - .0 - .storage - .key_chain() - .pub_account_signing_key(sender_account_id) - .ok_or(ExecutionFailureKind::KeyNotFoundError)?; - private_keys.push(sender_sk); - - if let Some(recipient_sk) = self - .0 - .storage - .key_chain() - .pub_account_signing_key(recipient_account_id) - { - private_keys.push(recipient_sk); - let recipient_nonces = self - .0 - .get_accounts_nonces(vec![recipient_account_id]) - .await - .map_err(ExecutionFailureKind::SequencerError)?; - nonces.extend(recipient_nonces); - } else { - println!( - "Receiver's account ({recipient_account_id}) private key not found in wallet. Proceeding with only sender's key." - ); - } - - let message = nssa::public_transaction::Message::try_new( - program_id, - account_ids, - nonces, - instruction, - ) - .unwrap(); - let witness_set = - nssa::public_transaction::WitnessSet::for_message(&message, &private_keys); - - let tx = nssa::PublicTransaction::new(message, witness_set); - - Ok(self - .0 - .sequencer_client - .send_transaction(NSSATransaction::Public(tx)) - .await?) } pub async fn send_transfer_transaction_private_owned_account( @@ -274,7 +208,7 @@ impl Token<'_> { self.0 .resolve_private_account(sender_account_id) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, - PrivacyPreservingAccount::PrivateForeign { + AccountIdentity::PrivateForeign { npk: recipient_npk, vpk: recipient_vpk, identifier: recipient_identifier, @@ -310,7 +244,7 @@ impl Token<'_> { self.0 .resolve_private_account(sender_account_id) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, - PrivacyPreservingAccount::Public(recipient_account_id), + AccountIdentity::Public(recipient_account_id), ], instruction_data, &Program::token().into(), @@ -340,7 +274,7 @@ impl Token<'_> { self.0 .send_privacy_preserving_tx( vec![ - PrivacyPreservingAccount::Public(sender_account_id), + AccountIdentity::Public(sender_account_id), self.0 .resolve_private_account(recipient_account_id) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, @@ -375,8 +309,8 @@ impl Token<'_> { self.0 .send_privacy_preserving_tx( vec![ - PrivacyPreservingAccount::Public(sender_account_id), - PrivacyPreservingAccount::PrivateForeign { + AccountIdentity::Public(sender_account_id), + AccountIdentity::PrivateForeign { npk: recipient_npk, vpk: recipient_vpk, identifier: recipient_identifier, @@ -401,40 +335,23 @@ impl Token<'_> { holder_account_id: AccountId, amount: u128, ) -> Result { - let account_ids = vec![definition_account_id, holder_account_id]; + let program = Program::token(); let instruction = Instruction::Burn { amount_to_burn: amount, }; + let instruction_data = + Program::serialize_instruction(instruction).expect("Instruction should serialize"); - let nonces = self - .0 - .get_accounts_nonces(vec![holder_account_id]) + self.0 + .send_pub_tx( + vec![ + AccountIdentity::PublicNoSign(definition_account_id), + AccountIdentity::Public(holder_account_id), + ], + instruction_data, + &program.into(), + ) .await - .map_err(ExecutionFailureKind::SequencerError)?; - let message = nssa::public_transaction::Message::try_new( - Program::token().id(), - account_ids, - nonces, - instruction, - ) - .expect("Instruction should serialize"); - - let signing_key = self - .0 - .storage - .key_chain() - .pub_account_signing_key(holder_account_id) - .ok_or(ExecutionFailureKind::KeyNotFoundError)?; - let witness_set = - nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]); - - let tx = nssa::PublicTransaction::new(message, witness_set); - - Ok(self - .0 - .sequencer_client - .send_transaction(NSSATransaction::Public(tx)) - .await?) } pub async fn send_burn_transaction_private_owned_account( @@ -489,7 +406,7 @@ impl Token<'_> { self.0 .resolve_private_account(definition_account_id) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, - PrivacyPreservingAccount::Public(holder_account_id), + AccountIdentity::Public(holder_account_id), ], instruction_data, &Program::token().into(), @@ -519,7 +436,7 @@ impl Token<'_> { self.0 .send_privacy_preserving_tx( vec![ - PrivacyPreservingAccount::Public(definition_account_id), + AccountIdentity::Public(definition_account_id), self.0 .resolve_private_account(holder_account_id) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, @@ -543,62 +460,23 @@ impl Token<'_> { holder_account_id: AccountId, amount: u128, ) -> Result { - let account_ids = vec![definition_account_id, holder_account_id]; + let program = Program::token(); let instruction = Instruction::Mint { amount_to_mint: amount, }; + let instruction_data = + Program::serialize_instruction(instruction).expect("Instruction should serialize"); - let mut nonces = self - .0 - .get_accounts_nonces(vec![definition_account_id]) + self.0 + .send_pub_tx( + vec![ + AccountIdentity::Public(definition_account_id), + AccountIdentity::Public(holder_account_id), + ], + instruction_data, + &program.into(), + ) .await - .map_err(ExecutionFailureKind::SequencerError)?; - - let mut private_keys = Vec::new(); - let definition_sk = self - .0 - .storage - .key_chain() - .pub_account_signing_key(definition_account_id) - .ok_or(ExecutionFailureKind::KeyNotFoundError)?; - private_keys.push(definition_sk); - - if let Some(holder_sk) = self - .0 - .storage - .key_chain() - .pub_account_signing_key(holder_account_id) - { - private_keys.push(holder_sk); - let recipient_nonces = self - .0 - .get_accounts_nonces(vec![holder_account_id]) - .await - .map_err(ExecutionFailureKind::SequencerError)?; - nonces.extend(recipient_nonces); - } else { - println!( - "Holder's account ({holder_account_id}) private key not found in wallet. Proceeding with only definition's key." - ); - } - - let message = nssa::public_transaction::Message::try_new( - Program::token().id(), - account_ids, - nonces, - instruction, - ) - .unwrap(); - let witness_set = - nssa::public_transaction::WitnessSet::for_message(&message, &private_keys); - - let tx = nssa::PublicTransaction::new(message, witness_set); - - Ok(self - .0 - .sequencer_client - .send_transaction(NSSATransaction::Public(tx)) - .await?) } pub async fn send_mint_transaction_private_owned_account( @@ -655,7 +533,7 @@ impl Token<'_> { self.0 .resolve_private_account(definition_account_id) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, - PrivacyPreservingAccount::PrivateForeign { + AccountIdentity::PrivateForeign { npk: holder_npk, vpk: holder_vpk, identifier: holder_identifier, @@ -691,7 +569,7 @@ impl Token<'_> { self.0 .resolve_private_account(definition_account_id) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, - PrivacyPreservingAccount::Public(holder_account_id), + AccountIdentity::Public(holder_account_id), ], instruction_data, &Program::token().into(), @@ -721,7 +599,7 @@ impl Token<'_> { self.0 .send_privacy_preserving_tx( vec![ - PrivacyPreservingAccount::Public(definition_account_id), + AccountIdentity::Public(definition_account_id), self.0 .resolve_private_account(holder_account_id) .ok_or(ExecutionFailureKind::KeyNotFoundError)?, @@ -756,8 +634,8 @@ impl Token<'_> { self.0 .send_privacy_preserving_tx( vec![ - PrivacyPreservingAccount::Public(definition_account_id), - PrivacyPreservingAccount::PrivateForeign { + AccountIdentity::Public(definition_account_id), + AccountIdentity::PrivateForeign { npk: holder_npk, vpk: holder_vpk, identifier: holder_identifier,