2025-10-20 22:51:13 -03:00
|
|
|
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
2025-11-24 17:09:30 +03:00
|
|
|
use nssa::{Account, AccountId, program::Program};
|
2025-10-13 13:29:32 +03:00
|
|
|
use nssa_core::{
|
2025-10-21 10:32:42 +03:00
|
|
|
MembershipProof, NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey,
|
|
|
|
|
program::InstructionData,
|
2025-10-13 13:29:32 +03:00
|
|
|
};
|
|
|
|
|
|
2025-10-21 10:32:42 +03:00
|
|
|
use crate::WalletCore;
|
2025-10-13 13:29:32 +03:00
|
|
|
|
|
|
|
|
impl WalletCore {
|
2025-10-21 10:32:42 +03:00
|
|
|
pub fn token_program_preparation_transfer(
|
|
|
|
|
amount: u128,
|
|
|
|
|
) -> (
|
|
|
|
|
InstructionData,
|
|
|
|
|
Program,
|
|
|
|
|
impl FnOnce(&Account, &Account) -> Result<(), ExecutionFailureKind>,
|
|
|
|
|
) {
|
2025-11-26 00:27:20 +03:00
|
|
|
// Instruction must be: [0x01 || amount (little-endian 16 bytes) || 0x00 || 0x00 || 0x00 ||
|
|
|
|
|
// 0x00 || 0x00 || 0x00].
|
2025-10-21 10:32:42 +03:00
|
|
|
let mut instruction = [0; 23];
|
|
|
|
|
instruction[0] = 0x01;
|
|
|
|
|
instruction[1..17].copy_from_slice(&amount.to_le_bytes());
|
|
|
|
|
let instruction_data = Program::serialize_instruction(instruction).unwrap();
|
|
|
|
|
let program = Program::token();
|
|
|
|
|
let tx_pre_check = |_: &Account, _: &Account| Ok(());
|
|
|
|
|
|
|
|
|
|
(instruction_data, program, tx_pre_check)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn token_program_preparation_definition(
|
|
|
|
|
name: [u8; 6],
|
|
|
|
|
total_supply: u128,
|
|
|
|
|
) -> (
|
|
|
|
|
InstructionData,
|
|
|
|
|
Program,
|
|
|
|
|
impl FnOnce(&Account, &Account) -> Result<(), ExecutionFailureKind>,
|
|
|
|
|
) {
|
|
|
|
|
// Instruction must be: [0x00 || total_supply (little-endian 16 bytes) || name (6 bytes)]
|
|
|
|
|
let mut instruction = [0; 23];
|
|
|
|
|
instruction[1..17].copy_from_slice(&total_supply.to_le_bytes());
|
|
|
|
|
instruction[17..].copy_from_slice(&name);
|
|
|
|
|
let instruction_data = Program::serialize_instruction(instruction).unwrap();
|
|
|
|
|
let program = Program::token();
|
|
|
|
|
let tx_pre_check = |_: &Account, _: &Account| Ok(());
|
|
|
|
|
|
|
|
|
|
(instruction_data, program, tx_pre_check)
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-13 13:29:32 +03:00
|
|
|
pub async fn send_new_token_definition(
|
|
|
|
|
&self,
|
2025-11-24 17:09:30 +03:00
|
|
|
definition_account_id: AccountId,
|
|
|
|
|
supply_account_id: AccountId,
|
2025-10-13 13:29:32 +03:00
|
|
|
name: [u8; 6],
|
|
|
|
|
total_supply: u128,
|
|
|
|
|
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
2025-11-24 17:09:30 +03:00
|
|
|
let account_ids = vec![definition_account_id, supply_account_id];
|
2025-10-13 13:29:32 +03:00
|
|
|
let program_id = nssa::program::Program::token().id();
|
|
|
|
|
// Instruction must be: [0x00 || total_supply (little-endian 16 bytes) || name (6 bytes)]
|
|
|
|
|
let mut instruction = [0; 23];
|
|
|
|
|
instruction[1..17].copy_from_slice(&total_supply.to_le_bytes());
|
|
|
|
|
instruction[17..].copy_from_slice(&name);
|
2025-11-24 17:09:30 +03:00
|
|
|
let message = nssa::public_transaction::Message::try_new(
|
|
|
|
|
program_id,
|
|
|
|
|
account_ids,
|
|
|
|
|
vec![],
|
|
|
|
|
instruction,
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
2025-10-13 13:29:32 +03:00
|
|
|
|
|
|
|
|
let witness_set = nssa::public_transaction::WitnessSet::for_message(&message, &[]);
|
|
|
|
|
|
|
|
|
|
let tx = nssa::PublicTransaction::new(message, witness_set);
|
|
|
|
|
|
|
|
|
|
Ok(self.sequencer_client.send_tx_public(tx).await?)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn send_new_token_definition_private_owned(
|
|
|
|
|
&self,
|
2025-11-24 17:09:30 +03:00
|
|
|
definition_account_id: AccountId,
|
|
|
|
|
supply_account_id: AccountId,
|
2025-10-13 13:29:32 +03:00
|
|
|
name: [u8; 6],
|
|
|
|
|
total_supply: u128,
|
|
|
|
|
) -> Result<(SendTxResponse, [SharedSecretKey; 1]), ExecutionFailureKind> {
|
2025-10-21 10:32:42 +03:00
|
|
|
let (instruction_data, program, tx_pre_check) =
|
|
|
|
|
WalletCore::token_program_preparation_definition(name, total_supply);
|
|
|
|
|
|
|
|
|
|
// Kind of non-obvious naming
|
|
|
|
|
// Basically this funtion is called because authentication mask is [0, 2]
|
|
|
|
|
self.shielded_two_accs_receiver_uninit(
|
2025-11-24 17:09:30 +03:00
|
|
|
definition_account_id,
|
|
|
|
|
supply_account_id,
|
2025-10-21 10:32:42 +03:00
|
|
|
instruction_data,
|
|
|
|
|
tx_pre_check,
|
|
|
|
|
program,
|
2025-10-13 13:29:32 +03:00
|
|
|
)
|
2025-10-21 10:32:42 +03:00
|
|
|
.await
|
2025-10-13 13:29:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn send_transfer_token_transaction(
|
|
|
|
|
&self,
|
2025-11-24 17:09:30 +03:00
|
|
|
sender_account_id: AccountId,
|
|
|
|
|
recipient_account_id: AccountId,
|
2025-10-13 13:29:32 +03:00
|
|
|
amount: u128,
|
|
|
|
|
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
2025-11-24 17:09:30 +03:00
|
|
|
let account_ids = vec![sender_account_id, recipient_account_id];
|
2025-10-13 13:29:32 +03:00
|
|
|
let program_id = nssa::program::Program::token().id();
|
2025-11-26 00:27:20 +03:00
|
|
|
// Instruction must be: [0x01 || amount (little-endian 16 bytes) || 0x00 || 0x00 || 0x00 ||
|
|
|
|
|
// 0x00 || 0x00 || 0x00].
|
2025-10-13 13:29:32 +03:00
|
|
|
let mut instruction = [0; 23];
|
|
|
|
|
instruction[0] = 0x01;
|
|
|
|
|
instruction[1..17].copy_from_slice(&amount.to_le_bytes());
|
2025-11-24 17:09:30 +03:00
|
|
|
let Ok(nonces) = self.get_accounts_nonces(vec![sender_account_id]).await else {
|
2025-10-13 13:29:32 +03:00
|
|
|
return Err(ExecutionFailureKind::SequencerError);
|
|
|
|
|
};
|
2025-11-24 17:09:30 +03:00
|
|
|
let message = nssa::public_transaction::Message::try_new(
|
|
|
|
|
program_id,
|
|
|
|
|
account_ids,
|
|
|
|
|
nonces,
|
|
|
|
|
instruction,
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
2025-10-13 13:29:32 +03:00
|
|
|
|
|
|
|
|
let Some(signing_key) = self
|
|
|
|
|
.storage
|
|
|
|
|
.user_data
|
2025-11-24 17:09:30 +03:00
|
|
|
.get_pub_account_signing_key(&sender_account_id)
|
2025-10-13 13:29:32 +03:00
|
|
|
else {
|
|
|
|
|
return Err(ExecutionFailureKind::KeyNotFoundError);
|
|
|
|
|
};
|
|
|
|
|
let witness_set =
|
|
|
|
|
nssa::public_transaction::WitnessSet::for_message(&message, &[signing_key]);
|
|
|
|
|
|
|
|
|
|
let tx = nssa::PublicTransaction::new(message, witness_set);
|
|
|
|
|
|
|
|
|
|
Ok(self.sequencer_client.send_tx_public(tx).await?)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn send_transfer_token_transaction_private_owned_account_already_initialized(
|
|
|
|
|
&self,
|
2025-11-24 17:09:30 +03:00
|
|
|
sender_account_id: AccountId,
|
|
|
|
|
recipient_account_id: AccountId,
|
2025-10-13 13:29:32 +03:00
|
|
|
amount: u128,
|
2025-10-15 15:29:28 +03:00
|
|
|
recipient_proof: MembershipProof,
|
2025-10-13 13:29:32 +03:00
|
|
|
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
2025-10-21 10:32:42 +03:00
|
|
|
let (instruction_data, program, tx_pre_check) =
|
|
|
|
|
WalletCore::token_program_preparation_transfer(amount);
|
|
|
|
|
|
|
|
|
|
self.private_tx_two_accs_all_init(
|
2025-11-24 17:09:30 +03:00
|
|
|
sender_account_id,
|
|
|
|
|
recipient_account_id,
|
2025-10-21 10:32:42 +03:00
|
|
|
instruction_data,
|
|
|
|
|
tx_pre_check,
|
|
|
|
|
program,
|
|
|
|
|
recipient_proof,
|
2025-10-13 13:29:32 +03:00
|
|
|
)
|
2025-10-21 10:32:42 +03:00
|
|
|
.await
|
2025-10-13 13:29:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn send_transfer_token_transaction_private_owned_account_not_initialized(
|
|
|
|
|
&self,
|
2025-11-24 17:09:30 +03:00
|
|
|
sender_account_id: AccountId,
|
|
|
|
|
recipient_account_id: AccountId,
|
2025-10-13 13:29:32 +03:00
|
|
|
amount: u128,
|
|
|
|
|
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
2025-10-21 10:32:42 +03:00
|
|
|
let (instruction_data, program, tx_pre_check) =
|
|
|
|
|
WalletCore::token_program_preparation_transfer(amount);
|
|
|
|
|
|
|
|
|
|
self.private_tx_two_accs_receiver_uninit(
|
2025-11-24 17:09:30 +03:00
|
|
|
sender_account_id,
|
|
|
|
|
recipient_account_id,
|
2025-10-21 10:32:42 +03:00
|
|
|
instruction_data,
|
|
|
|
|
tx_pre_check,
|
|
|
|
|
program,
|
2025-10-13 13:29:32 +03:00
|
|
|
)
|
2025-10-21 10:32:42 +03:00
|
|
|
.await
|
2025-10-13 13:29:32 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn send_transfer_token_transaction_private_foreign_account(
|
|
|
|
|
&self,
|
2025-11-24 17:09:30 +03:00
|
|
|
sender_account_id: AccountId,
|
2025-10-13 13:29:32 +03:00
|
|
|
recipient_npk: NullifierPublicKey,
|
|
|
|
|
recipient_ipk: IncomingViewingPublicKey,
|
|
|
|
|
amount: u128,
|
|
|
|
|
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
2025-10-21 10:32:42 +03:00
|
|
|
let (instruction_data, program, tx_pre_check) =
|
|
|
|
|
WalletCore::token_program_preparation_transfer(amount);
|
|
|
|
|
|
|
|
|
|
self.private_tx_two_accs_receiver_outer(
|
2025-11-24 17:09:30 +03:00
|
|
|
sender_account_id,
|
2025-10-21 10:32:42 +03:00
|
|
|
recipient_npk,
|
|
|
|
|
recipient_ipk,
|
|
|
|
|
instruction_data,
|
|
|
|
|
tx_pre_check,
|
|
|
|
|
program,
|
2025-10-13 13:29:32 +03:00
|
|
|
)
|
2025-10-21 10:32:42 +03:00
|
|
|
.await
|
2025-10-13 13:29:32 +03:00
|
|
|
}
|
2025-10-20 09:10:54 +03:00
|
|
|
|
|
|
|
|
pub async fn send_transfer_token_transaction_deshielded(
|
|
|
|
|
&self,
|
2025-11-24 17:09:30 +03:00
|
|
|
sender_account_id: AccountId,
|
|
|
|
|
recipient_account_id: AccountId,
|
2025-10-20 09:10:54 +03:00
|
|
|
amount: u128,
|
|
|
|
|
) -> Result<(SendTxResponse, [SharedSecretKey; 1]), ExecutionFailureKind> {
|
2025-10-21 10:32:42 +03:00
|
|
|
let (instruction_data, program, tx_pre_check) =
|
|
|
|
|
WalletCore::token_program_preparation_transfer(amount);
|
|
|
|
|
|
|
|
|
|
self.deshielded_tx_two_accs(
|
2025-11-24 17:09:30 +03:00
|
|
|
sender_account_id,
|
|
|
|
|
recipient_account_id,
|
2025-10-21 10:32:42 +03:00
|
|
|
instruction_data,
|
|
|
|
|
tx_pre_check,
|
|
|
|
|
program,
|
2025-10-20 09:10:54 +03:00
|
|
|
)
|
2025-10-21 10:32:42 +03:00
|
|
|
.await
|
2025-10-20 09:10:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn send_transfer_token_transaction_shielded_owned_account_already_initialized(
|
|
|
|
|
&self,
|
2025-11-24 17:09:30 +03:00
|
|
|
sender_account_id: AccountId,
|
|
|
|
|
recipient_account_id: AccountId,
|
2025-10-20 09:10:54 +03:00
|
|
|
amount: u128,
|
|
|
|
|
recipient_proof: MembershipProof,
|
|
|
|
|
) -> Result<(SendTxResponse, [SharedSecretKey; 1]), ExecutionFailureKind> {
|
2025-10-21 10:32:42 +03:00
|
|
|
let (instruction_data, program, tx_pre_check) =
|
|
|
|
|
WalletCore::token_program_preparation_transfer(amount);
|
|
|
|
|
|
|
|
|
|
self.shielded_two_accs_all_init(
|
2025-11-24 17:09:30 +03:00
|
|
|
sender_account_id,
|
|
|
|
|
recipient_account_id,
|
2025-10-21 10:32:42 +03:00
|
|
|
instruction_data,
|
|
|
|
|
tx_pre_check,
|
|
|
|
|
program,
|
|
|
|
|
recipient_proof,
|
2025-10-20 09:10:54 +03:00
|
|
|
)
|
2025-10-21 10:32:42 +03:00
|
|
|
.await
|
2025-10-20 09:10:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn send_transfer_token_transaction_shielded_owned_account_not_initialized(
|
|
|
|
|
&self,
|
2025-11-24 17:09:30 +03:00
|
|
|
sender_account_id: AccountId,
|
|
|
|
|
recipient_account_id: AccountId,
|
2025-10-20 09:10:54 +03:00
|
|
|
amount: u128,
|
|
|
|
|
) -> Result<(SendTxResponse, [SharedSecretKey; 1]), ExecutionFailureKind> {
|
2025-10-21 10:32:42 +03:00
|
|
|
let (instruction_data, program, tx_pre_check) =
|
|
|
|
|
WalletCore::token_program_preparation_transfer(amount);
|
|
|
|
|
|
|
|
|
|
self.shielded_two_accs_receiver_uninit(
|
2025-11-24 17:09:30 +03:00
|
|
|
sender_account_id,
|
|
|
|
|
recipient_account_id,
|
2025-10-21 10:32:42 +03:00
|
|
|
instruction_data,
|
|
|
|
|
tx_pre_check,
|
|
|
|
|
program,
|
2025-10-20 09:10:54 +03:00
|
|
|
)
|
2025-10-21 10:32:42 +03:00
|
|
|
.await
|
2025-10-20 09:10:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn send_transfer_token_transaction_shielded_foreign_account(
|
|
|
|
|
&self,
|
2025-11-24 17:09:30 +03:00
|
|
|
sender_account_id: AccountId,
|
2025-10-20 09:10:54 +03:00
|
|
|
recipient_npk: NullifierPublicKey,
|
|
|
|
|
recipient_ipk: IncomingViewingPublicKey,
|
|
|
|
|
amount: u128,
|
|
|
|
|
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
2025-10-21 10:32:42 +03:00
|
|
|
let (instruction_data, program, tx_pre_check) =
|
|
|
|
|
WalletCore::token_program_preparation_transfer(amount);
|
|
|
|
|
|
|
|
|
|
self.shielded_two_accs_receiver_outer(
|
2025-11-24 17:09:30 +03:00
|
|
|
sender_account_id,
|
2025-10-21 10:32:42 +03:00
|
|
|
recipient_npk,
|
|
|
|
|
recipient_ipk,
|
|
|
|
|
instruction_data,
|
|
|
|
|
tx_pre_check,
|
|
|
|
|
program,
|
2025-10-20 09:10:54 +03:00
|
|
|
)
|
2025-10-21 10:32:42 +03:00
|
|
|
.await
|
2025-10-20 09:10:54 +03:00
|
|
|
}
|
2025-10-13 13:29:32 +03:00
|
|
|
}
|