102 lines
3.6 KiB
Rust
Raw Normal View History

2025-09-22 16:38:25 +03:00
use common::{ExecutionFailureKind, sequencer_client::json::SendTxResponse};
2025-09-23 09:54:33 +03:00
use k256::elliptic_curve::rand_core::{OsRng, RngCore};
2025-09-22 16:38:25 +03:00
use nssa::Address;
2025-09-23 09:54:33 +03:00
use nssa_core::{SharedSecretKey, encryption::EphemeralPublicKey};
2025-09-22 16:38:25 +03:00
use crate::WalletCore;
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-09-30 14:31:04 -03:00
let Some((from_keys, mut from_acc)) =
self.storage.user_data.get_private_account(&from).cloned()
else {
2025-09-22 16:38:25 +03:00
return Err(ExecutionFailureKind::KeyNotFoundError);
};
2025-09-30 14:31:04 -03:00
let Ok(to_acc) = self.get_account(to).await else {
2025-09-22 16:38:25 +03:00
return Err(ExecutionFailureKind::KeyNotFoundError);
};
if from_acc.balance >= balance_to_move {
let program = nssa::program::Program::authenticated_transfer_program();
2025-09-24 16:44:03 +03:00
from_acc.program_owner = program.id();
2025-09-22 16:38:25 +03:00
let sender_commitment =
2025-09-24 16:44:03 +03:00
nssa_core::Commitment::new(&from_keys.nullifer_public_key, &from_acc);
2025-09-22 16:38:25 +03:00
let sender_pre = nssa_core::account::AccountWithMetadata {
account: from_acc.clone(),
is_authorized: true,
2025-09-26 09:50:09 +03:00
account_id: (&from_keys.nullifer_public_key).into(),
2025-09-22 16:38:25 +03:00
};
let recipient_pre = nssa_core::account::AccountWithMetadata {
account: to_acc.clone(),
is_authorized: false,
2025-10-02 08:39:53 -03:00
account_id: to,
2025-09-22 16:38:25 +03:00
};
2025-09-23 09:54:33 +03:00
//Move into different function
let mut esk = [0; 32];
OsRng.fill_bytes(&mut esk);
let shared_secret = SharedSecretKey::new(&esk, &from_keys.incoming_viewing_public_key);
let epk = EphemeralPublicKey::from_scalar(esk);
2025-09-22 16:38:25 +03:00
let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove(
&[sender_pre, recipient_pre],
&nssa::program::Program::serialize_instruction(balance_to_move).unwrap(),
&[1, 0],
&[from_acc.nonce + 1],
&[(from_keys.nullifer_public_key.clone(), shared_secret.clone())],
&[(
from_keys.private_key_holder.nullifier_secret_key,
self.sequencer_client
.get_proof_for_commitment(sender_commitment)
.await
.unwrap()
.unwrap(),
)],
&program,
)
.unwrap();
let message =
nssa::privacy_preserving_transaction::message::Message::try_from_circuit_output(
vec![to],
vec![],
vec![(
from_keys.nullifer_public_key.clone(),
from_keys.incoming_viewing_public_key.clone(),
2025-09-23 09:54:33 +03:00
epk,
2025-09-22 16:38:25 +03:00
)],
output,
)
.unwrap();
let witness_set =
nssa::privacy_preserving_transaction::witness_set::WitnessSet::for_message(
&message,
proof,
&[],
);
let tx = nssa::privacy_preserving_transaction::PrivacyPreservingTransaction::new(
message,
witness_set,
);
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)
}
}
}