86 lines
3.1 KiB
Rust
Raw Normal View History

2025-09-22 16:38:25 +03:00
use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse};
2025-10-02 22:30:33 -03:00
use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder;
2025-10-03 15:59:27 -03:00
use nssa::{
Address, PrivacyPreservingTransaction,
privacy_preserving_transaction::{circuit, message::Message, witness_set::WitnessSet},
program::Program,
};
use nssa_core::{Commitment, account::AccountWithMetadata};
2025-09-22 16:38:25 +03:00
2025-10-03 08:08:54 -03:00
use crate::{WalletCore, helperfunctions::produce_random_nonces};
2025-09-22 16:38:25 +03:00
impl WalletCore {
pub async fn send_deshielded_native_token_transfer(
&self,
from: Address,
to: Address,
balance_to_move: u128,
2025-09-23 09:54:33 +03:00
) -> Result<(SendTxResponse, nssa_core::SharedSecretKey), ExecutionFailureKind> {
2025-10-03 08:08:54 -03:00
let Some((from_keys, from_acc)) =
2025-09-30 14:31:04 -03:00
self.storage.user_data.get_private_account(&from).cloned()
else {
2025-09-22 16:38:25 +03:00
return Err(ExecutionFailureKind::KeyNotFoundError);
};
2025-10-03 15:59:27 -03:00
let Ok(to_acc) = self.get_account_public(to).await else {
2025-09-22 16:38:25 +03:00
return Err(ExecutionFailureKind::KeyNotFoundError);
};
if from_acc.balance >= balance_to_move {
2025-10-03 15:59:27 -03:00
let program = Program::authenticated_transfer_program();
2025-09-24 16:44:03 +03:00
2025-10-02 22:30:33 -03:00
let npk_from = from_keys.nullifer_public_key;
let ipk_from = from_keys.incoming_viewing_public_key;
2025-10-03 15:59:27 -03:00
let sender_commitment = Commitment::new(&npk_from, &from_acc);
2025-09-22 16:38:25 +03:00
2025-10-03 08:44:15 -03:00
let sender_pre = AccountWithMetadata::new(from_acc.clone(), true, &npk_from);
let recipient_pre = AccountWithMetadata::new(to_acc.clone(), false, to);
2025-09-22 16:38:25 +03:00
2025-10-02 22:30:33 -03:00
let eph_holder = EphemeralKeyHolder::new(&npk_from);
let shared_secret = eph_holder.calculate_shared_secret_sender(&ipk_from);
2025-09-22 16:38:25 +03:00
2025-10-03 15:59:27 -03:00
let (output, proof) = circuit::execute_and_prove(
2025-09-22 16:38:25 +03:00
&[sender_pre, recipient_pre],
2025-10-03 15:59:27 -03:00
&Program::serialize_instruction(balance_to_move).unwrap(),
2025-09-22 16:38:25 +03:00
&[1, 0],
&produce_random_nonces(1),
2025-10-02 22:30:33 -03:00
&[(npk_from.clone(), shared_secret.clone())],
2025-09-22 16:38:25 +03:00
&[(
from_keys.private_key_holder.nullifier_secret_key,
self.sequencer_client
.get_proof_for_commitment(sender_commitment)
.await
.unwrap()
.unwrap(),
)],
&program,
)
.unwrap();
2025-10-03 15:59:27 -03:00
let message = Message::try_from_circuit_output(
vec![to],
vec![],
vec![(
npk_from.clone(),
ipk_from.clone(),
eph_holder.generate_ephemeral_public_key(),
)],
output,
)
.unwrap();
2025-09-22 16:38:25 +03:00
2025-10-03 15:59:27 -03:00
let witness_set = WitnessSet::for_message(&message, proof, &[]);
2025-09-22 16:38:25 +03:00
2025-10-03 15:59:27 -03:00
let tx = PrivacyPreservingTransaction::new(message, witness_set);
2025-09-22 16:38:25 +03:00
2025-09-23 09:54:33 +03:00
Ok((
self.sequencer_client.send_tx_private(tx).await?,
shared_secret,
))
2025-09-22 16:38:25 +03:00
} else {
Err(ExecutionFailureKind::InsufficientFundsError)
}
}
}