mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-01-08 00:03:09 +00:00
refactor: implement program interactions as facades
This commit is contained in:
parent
df64f8864f
commit
55fc4e9777
@ -7,6 +7,7 @@ use crate::{
|
|||||||
WalletCore,
|
WalletCore,
|
||||||
cli::{SubcommandReturnValue, WalletSubcommand},
|
cli::{SubcommandReturnValue, WalletSubcommand},
|
||||||
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
||||||
|
program_facades::native_token_transfer::NativeTokenTransfer,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents generic CLI subcommand for a wallet working with native token transfer program
|
/// Represents generic CLI subcommand for a wallet working with native token transfer program
|
||||||
@ -56,8 +57,8 @@ impl WalletSubcommand for AuthTransferSubcommand {
|
|||||||
AccountPrivacyKind::Public => {
|
AccountPrivacyKind::Public => {
|
||||||
let account_id = account_id.parse()?;
|
let account_id = account_id.parse()?;
|
||||||
|
|
||||||
let res = wallet_core
|
let res = NativeTokenTransfer(wallet_core)
|
||||||
.register_account_under_authenticated_transfers_programs(account_id)
|
.register_account(account_id)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
println!("Results of tx send is {res:#?}");
|
println!("Results of tx send is {res:#?}");
|
||||||
@ -317,8 +318,8 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommandPrivate {
|
|||||||
let from: AccountId = from.parse().unwrap();
|
let from: AccountId = from.parse().unwrap();
|
||||||
let to: AccountId = to.parse().unwrap();
|
let to: AccountId = to.parse().unwrap();
|
||||||
|
|
||||||
let (res, [secret_from, secret_to]) = wallet_core
|
let (res, [secret_from, secret_to]) = NativeTokenTransfer(wallet_core)
|
||||||
.send_private_native_token_transfer_owned_account(from, to, amount)
|
.send_private_transfer_to_owned_account(from, to, amount)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
println!("Results of tx send is {res:#?}");
|
println!("Results of tx send is {res:#?}");
|
||||||
@ -361,8 +362,8 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommandPrivate {
|
|||||||
let to_ipk =
|
let to_ipk =
|
||||||
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_ipk.to_vec());
|
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_ipk.to_vec());
|
||||||
|
|
||||||
let (res, [secret_from, _]) = wallet_core
|
let (res, [secret_from, _]) = NativeTokenTransfer(wallet_core)
|
||||||
.send_private_native_token_transfer_outer_account(from, to_npk, to_ipk, amount)
|
.send_private_transfer_to_outer_account(from, to_npk, to_ipk, amount)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
println!("Results of tx send is {res:#?}");
|
println!("Results of tx send is {res:#?}");
|
||||||
@ -401,8 +402,8 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommandShielded {
|
|||||||
let from: AccountId = from.parse().unwrap();
|
let from: AccountId = from.parse().unwrap();
|
||||||
let to: AccountId = to.parse().unwrap();
|
let to: AccountId = to.parse().unwrap();
|
||||||
|
|
||||||
let (res, secret) = wallet_core
|
let (res, secret) = NativeTokenTransfer(wallet_core)
|
||||||
.send_shielded_native_token_transfer(from, to, amount)
|
.send_shielded_transfer(from, to, amount)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
println!("Results of tx send is {res:#?}");
|
println!("Results of tx send is {res:#?}");
|
||||||
@ -446,8 +447,8 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommandShielded {
|
|||||||
let to_ipk =
|
let to_ipk =
|
||||||
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_ipk.to_vec());
|
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_ipk.to_vec());
|
||||||
|
|
||||||
let (res, _) = wallet_core
|
let (res, _) = NativeTokenTransfer(wallet_core)
|
||||||
.send_shielded_native_token_transfer_outer_account(from, to_npk, to_ipk, amount)
|
.send_shielded_transfer_to_outer_account(from, to_npk, to_ipk, amount)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
println!("Results of tx send is {res:#?}");
|
println!("Results of tx send is {res:#?}");
|
||||||
@ -480,8 +481,8 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommand {
|
|||||||
let from: AccountId = from.parse().unwrap();
|
let from: AccountId = from.parse().unwrap();
|
||||||
let to: AccountId = to.parse().unwrap();
|
let to: AccountId = to.parse().unwrap();
|
||||||
|
|
||||||
let (res, secret) = wallet_core
|
let (res, secret) = NativeTokenTransfer(wallet_core)
|
||||||
.send_deshielded_native_token_transfer(from, to, amount)
|
.send_deshielded_transfer(from, to, amount)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
println!("Results of tx send is {res:#?}");
|
println!("Results of tx send is {res:#?}");
|
||||||
@ -510,8 +511,8 @@ impl WalletSubcommand for NativeTokenTransferProgramSubcommand {
|
|||||||
let from: AccountId = from.parse().unwrap();
|
let from: AccountId = from.parse().unwrap();
|
||||||
let to: AccountId = to.parse().unwrap();
|
let to: AccountId = to.parse().unwrap();
|
||||||
|
|
||||||
let res = wallet_core
|
let res = NativeTokenTransfer(wallet_core)
|
||||||
.send_public_native_token_transfer(from, to, amount)
|
.send_public_transfer(from, to, amount)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
println!("Results of tx send is {res:#?}");
|
println!("Results of tx send is {res:#?}");
|
||||||
|
|||||||
@ -7,6 +7,7 @@ use crate::{
|
|||||||
WalletCore,
|
WalletCore,
|
||||||
cli::{SubcommandReturnValue, WalletSubcommand},
|
cli::{SubcommandReturnValue, WalletSubcommand},
|
||||||
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
||||||
|
program_facades::pinata::Pinata,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents generic CLI subcommand for a wallet working with pinata program
|
/// Represents generic CLI subcommand for a wallet working with pinata program
|
||||||
@ -117,8 +118,8 @@ impl WalletSubcommand for PinataProgramSubcommandPublic {
|
|||||||
winner_account_id,
|
winner_account_id,
|
||||||
solution,
|
solution,
|
||||||
} => {
|
} => {
|
||||||
let res = wallet_core
|
let res = Pinata(wallet_core)
|
||||||
.claim_pinata(
|
.claim(
|
||||||
pinata_account_id.parse().unwrap(),
|
pinata_account_id.parse().unwrap(),
|
||||||
winner_account_id.parse().unwrap(),
|
winner_account_id.parse().unwrap(),
|
||||||
solution,
|
solution,
|
||||||
@ -146,29 +147,10 @@ impl WalletSubcommand for PinataProgramSubcommandPrivate {
|
|||||||
let pinata_account_id = pinata_account_id.parse().unwrap();
|
let pinata_account_id = pinata_account_id.parse().unwrap();
|
||||||
let winner_account_id = winner_account_id.parse().unwrap();
|
let winner_account_id = winner_account_id.parse().unwrap();
|
||||||
|
|
||||||
let winner_initialization = wallet_core
|
let (res, secret_winner) = Pinata(wallet_core)
|
||||||
.check_private_account_initialized(&winner_account_id)
|
.claim_private_owned_account(pinata_account_id, winner_account_id, solution)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let (res, [secret_winner]) = if let Some(winner_proof) = winner_initialization {
|
|
||||||
wallet_core
|
|
||||||
.claim_pinata_private_owned_account_already_initialized(
|
|
||||||
pinata_account_id,
|
|
||||||
winner_account_id,
|
|
||||||
solution,
|
|
||||||
winner_proof,
|
|
||||||
)
|
|
||||||
.await?
|
|
||||||
} else {
|
|
||||||
wallet_core
|
|
||||||
.claim_pinata_private_owned_account_not_initialized(
|
|
||||||
pinata_account_id,
|
|
||||||
winner_account_id,
|
|
||||||
solution,
|
|
||||||
)
|
|
||||||
.await?
|
|
||||||
};
|
|
||||||
|
|
||||||
info!("Results of tx send is {res:#?}");
|
info!("Results of tx send is {res:#?}");
|
||||||
|
|
||||||
let tx_hash = res.tx_hash;
|
let tx_hash = res.tx_hash;
|
||||||
|
|||||||
@ -7,6 +7,7 @@ use crate::{
|
|||||||
WalletCore,
|
WalletCore,
|
||||||
cli::{SubcommandReturnValue, WalletSubcommand},
|
cli::{SubcommandReturnValue, WalletSubcommand},
|
||||||
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
||||||
|
program_facades::token::Token,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents generic CLI subcommand for a wallet working with token program
|
/// Represents generic CLI subcommand for a wallet working with token program
|
||||||
@ -338,8 +339,8 @@ impl WalletSubcommand for TokenProgramSubcommandPublic {
|
|||||||
}
|
}
|
||||||
let mut name_bytes = [0; 6];
|
let mut name_bytes = [0; 6];
|
||||||
name_bytes[..name.len()].copy_from_slice(name);
|
name_bytes[..name.len()].copy_from_slice(name);
|
||||||
wallet_core
|
Token(wallet_core)
|
||||||
.send_new_token_definition(
|
.send_new_definition(
|
||||||
definition_account_id.parse().unwrap(),
|
definition_account_id.parse().unwrap(),
|
||||||
supply_account_id.parse().unwrap(),
|
supply_account_id.parse().unwrap(),
|
||||||
name_bytes,
|
name_bytes,
|
||||||
@ -353,8 +354,8 @@ impl WalletSubcommand for TokenProgramSubcommandPublic {
|
|||||||
recipient_account_id,
|
recipient_account_id,
|
||||||
balance_to_move,
|
balance_to_move,
|
||||||
} => {
|
} => {
|
||||||
wallet_core
|
Token(wallet_core)
|
||||||
.send_transfer_token_transaction(
|
.send_transfer_transaction(
|
||||||
sender_account_id.parse().unwrap(),
|
sender_account_id.parse().unwrap(),
|
||||||
recipient_account_id.parse().unwrap(),
|
recipient_account_id.parse().unwrap(),
|
||||||
balance_to_move,
|
balance_to_move,
|
||||||
@ -389,8 +390,8 @@ impl WalletSubcommand for TokenProgramSubcommandPrivate {
|
|||||||
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
|
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
|
||||||
let supply_account_id: AccountId = supply_account_id.parse().unwrap();
|
let supply_account_id: AccountId = supply_account_id.parse().unwrap();
|
||||||
|
|
||||||
let (res, secret_supply) = wallet_core
|
let (res, secret_supply) = Token(wallet_core)
|
||||||
.send_new_token_definition_private_owned(
|
.send_new_definition_private_owned(
|
||||||
definition_account_id,
|
definition_account_id,
|
||||||
supply_account_id,
|
supply_account_id,
|
||||||
name_bytes,
|
name_bytes,
|
||||||
@ -428,8 +429,8 @@ impl WalletSubcommand for TokenProgramSubcommandPrivate {
|
|||||||
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
|
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
|
||||||
let recipient_account_id: AccountId = recipient_account_id.parse().unwrap();
|
let recipient_account_id: AccountId = recipient_account_id.parse().unwrap();
|
||||||
|
|
||||||
let (res, [secret_sender, secret_recipient]) = wallet_core
|
let (res, [secret_sender, secret_recipient]) = Token(wallet_core)
|
||||||
.send_transfer_token_transaction_private_owned_account(
|
.send_transfer_transaction_private_owned_account(
|
||||||
sender_account_id,
|
sender_account_id,
|
||||||
recipient_account_id,
|
recipient_account_id,
|
||||||
balance_to_move,
|
balance_to_move,
|
||||||
@ -480,8 +481,8 @@ impl WalletSubcommand for TokenProgramSubcommandPrivate {
|
|||||||
recipient_ipk.to_vec(),
|
recipient_ipk.to_vec(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (res, [secret_sender, _]) = wallet_core
|
let (res, [secret_sender, _]) = Token(wallet_core)
|
||||||
.send_transfer_token_transaction_private_foreign_account(
|
.send_transfer_transaction_private_foreign_account(
|
||||||
sender_account_id,
|
sender_account_id,
|
||||||
recipient_npk,
|
recipient_npk,
|
||||||
recipient_ipk,
|
recipient_ipk,
|
||||||
@ -529,8 +530,8 @@ impl WalletSubcommand for TokenProgramSubcommandDeshielded {
|
|||||||
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
|
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
|
||||||
let recipient_account_id: AccountId = recipient_account_id.parse().unwrap();
|
let recipient_account_id: AccountId = recipient_account_id.parse().unwrap();
|
||||||
|
|
||||||
let (res, secret_sender) = wallet_core
|
let (res, secret_sender) = Token(wallet_core)
|
||||||
.send_transfer_token_transaction_deshielded(
|
.send_transfer_transaction_deshielded(
|
||||||
sender_account_id,
|
sender_account_id,
|
||||||
recipient_account_id,
|
recipient_account_id,
|
||||||
balance_to_move,
|
balance_to_move,
|
||||||
@ -588,8 +589,8 @@ impl WalletSubcommand for TokenProgramSubcommandShielded {
|
|||||||
recipient_ipk.to_vec(),
|
recipient_ipk.to_vec(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (res, _) = wallet_core
|
let (res, _) = Token(wallet_core)
|
||||||
.send_transfer_token_transaction_shielded_foreign_account(
|
.send_transfer_transaction_shielded_foreign_account(
|
||||||
sender_account_id,
|
sender_account_id,
|
||||||
recipient_npk,
|
recipient_npk,
|
||||||
recipient_ipk,
|
recipient_ipk,
|
||||||
@ -622,8 +623,8 @@ impl WalletSubcommand for TokenProgramSubcommandShielded {
|
|||||||
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
|
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
|
||||||
let recipient_account_id: AccountId = recipient_account_id.parse().unwrap();
|
let recipient_account_id: AccountId = recipient_account_id.parse().unwrap();
|
||||||
|
|
||||||
let (res, secret_recipient) = wallet_core
|
let (res, secret_recipient) = Token(wallet_core)
|
||||||
.send_transfer_token_transaction_shielded_owned_account(
|
.send_transfer_transaction_shielded_owned_account(
|
||||||
sender_account_id,
|
sender_account_id,
|
||||||
recipient_account_id,
|
recipient_account_id,
|
||||||
balance_to_move,
|
balance_to_move,
|
||||||
|
|||||||
@ -32,8 +32,7 @@ pub mod config;
|
|||||||
pub mod helperfunctions;
|
pub mod helperfunctions;
|
||||||
pub mod poller;
|
pub mod poller;
|
||||||
mod privacy_preserving_tx;
|
mod privacy_preserving_tx;
|
||||||
pub mod program_interactions;
|
pub mod program_facades;
|
||||||
pub mod token_transfers;
|
|
||||||
pub mod transaction_utils;
|
pub mod transaction_utils;
|
||||||
|
|
||||||
pub struct WalletCore {
|
pub struct WalletCore {
|
||||||
@ -224,9 +223,9 @@ impl WalletCore {
|
|||||||
pub async fn send_privacy_preserving_tx(
|
pub async fn send_privacy_preserving_tx(
|
||||||
&self,
|
&self,
|
||||||
accounts: Vec<PrivacyPreservingAccount>,
|
accounts: Vec<PrivacyPreservingAccount>,
|
||||||
instruction_data: InstructionData,
|
instruction_data: &InstructionData,
|
||||||
tx_pre_check: impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>,
|
tx_pre_check: impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>,
|
||||||
program: Program,
|
program: &Program,
|
||||||
) -> Result<(SendTxResponse, Vec<SharedSecretKey>), ExecutionFailureKind> {
|
) -> Result<(SendTxResponse, Vec<SharedSecretKey>), ExecutionFailureKind> {
|
||||||
let payload = privacy_preserving_tx::Payload::new(self, accounts).await?;
|
let payload = privacy_preserving_tx::Payload::new(self, accounts).await?;
|
||||||
|
|
||||||
@ -241,7 +240,7 @@ impl WalletCore {
|
|||||||
let private_account_keys = payload.private_account_keys();
|
let private_account_keys = payload.private_account_keys();
|
||||||
let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove(
|
let (output, proof) = nssa::privacy_preserving_transaction::circuit::execute_and_prove(
|
||||||
&pre_states,
|
&pre_states,
|
||||||
&instruction_data,
|
instruction_data,
|
||||||
payload.visibility_mask(),
|
payload.visibility_mask(),
|
||||||
&produce_random_nonces(private_account_keys.len()),
|
&produce_random_nonces(private_account_keys.len()),
|
||||||
&private_account_keys
|
&private_account_keys
|
||||||
@ -249,7 +248,7 @@ impl WalletCore {
|
|||||||
.map(|keys| (keys.npk.clone(), keys.ssk.clone()))
|
.map(|keys| (keys.npk.clone(), keys.ssk.clone()))
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
&payload.private_account_auth(),
|
&payload.private_account_auth(),
|
||||||
&program,
|
program,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ use crate::{WalletCore, transaction_utils::AccountPreparedData};
|
|||||||
|
|
||||||
pub enum PrivacyPreservingAccount {
|
pub enum PrivacyPreservingAccount {
|
||||||
Public(AccountId),
|
Public(AccountId),
|
||||||
PrivateLocal(AccountId),
|
PrivateOwned(AccountId),
|
||||||
PrivateForeign {
|
PrivateForeign {
|
||||||
npk: NullifierPublicKey,
|
npk: NullifierPublicKey,
|
||||||
ipk: IncomingViewingPublicKey,
|
ipk: IncomingViewingPublicKey,
|
||||||
@ -59,7 +59,7 @@ impl Payload {
|
|||||||
|
|
||||||
(State::Public { account, sk }, 0)
|
(State::Public { account, sk }, 0)
|
||||||
}
|
}
|
||||||
PrivacyPreservingAccount::PrivateLocal(account_id) => {
|
PrivacyPreservingAccount::PrivateOwned(account_id) => {
|
||||||
let mut pre = wallet
|
let mut pre = wallet
|
||||||
.private_acc_preparation(account_id, true, true)
|
.private_acc_preparation(account_id, true, true)
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
6
wallet/src/program_facades/mod.rs
Normal file
6
wallet/src/program_facades/mod.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
//! This module contains [`WalletCore`](crate::WalletCore) facades for interacting with various
|
||||||
|
//! on-chain programs.
|
||||||
|
|
||||||
|
pub mod native_token_transfer;
|
||||||
|
pub mod pinata;
|
||||||
|
pub mod token;
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||||
|
use nssa::AccountId;
|
||||||
|
|
||||||
|
use super::{NativeTokenTransfer, auth_transfer_preparation};
|
||||||
|
use crate::PrivacyPreservingAccount;
|
||||||
|
|
||||||
|
impl NativeTokenTransfer<'_> {
|
||||||
|
pub async fn send_deshielded_transfer(
|
||||||
|
&self,
|
||||||
|
from: AccountId,
|
||||||
|
to: AccountId,
|
||||||
|
balance_to_move: u128,
|
||||||
|
) -> Result<(SendTxResponse, nssa_core::SharedSecretKey), ExecutionFailureKind> {
|
||||||
|
let (instruction_data, program, tx_pre_check) = auth_transfer_preparation(balance_to_move);
|
||||||
|
|
||||||
|
self.0
|
||||||
|
.send_privacy_preserving_tx(
|
||||||
|
vec![
|
||||||
|
PrivacyPreservingAccount::PrivateOwned(from),
|
||||||
|
PrivacyPreservingAccount::Public(to),
|
||||||
|
],
|
||||||
|
&instruction_data,
|
||||||
|
tx_pre_check,
|
||||||
|
&program,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|(resp, secrets)| {
|
||||||
|
let first = secrets
|
||||||
|
.into_iter()
|
||||||
|
.next()
|
||||||
|
.expect("expected sender's secret");
|
||||||
|
(resp, first)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
33
wallet/src/program_facades/native_token_transfer/mod.rs
Normal file
33
wallet/src/program_facades/native_token_transfer/mod.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
use common::error::ExecutionFailureKind;
|
||||||
|
use nssa::{Account, program::Program};
|
||||||
|
use nssa_core::program::InstructionData;
|
||||||
|
|
||||||
|
use crate::WalletCore;
|
||||||
|
|
||||||
|
pub mod deshielded;
|
||||||
|
pub mod private;
|
||||||
|
pub mod public;
|
||||||
|
pub mod shielded;
|
||||||
|
|
||||||
|
pub struct NativeTokenTransfer<'w>(pub &'w WalletCore);
|
||||||
|
|
||||||
|
fn auth_transfer_preparation(
|
||||||
|
balance_to_move: u128,
|
||||||
|
) -> (
|
||||||
|
InstructionData,
|
||||||
|
Program,
|
||||||
|
impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>,
|
||||||
|
) {
|
||||||
|
let instruction_data = Program::serialize_instruction(balance_to_move).unwrap();
|
||||||
|
let program = Program::authenticated_transfer_program();
|
||||||
|
let tx_pre_check = move |accounts: &[&Account]| {
|
||||||
|
let from = accounts[0];
|
||||||
|
if from.balance >= balance_to_move {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(ExecutionFailureKind::InsufficientFundsError)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(instruction_data, program, tx_pre_check)
|
||||||
|
}
|
||||||
68
wallet/src/program_facades/native_token_transfer/private.rs
Normal file
68
wallet/src/program_facades/native_token_transfer/private.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use std::vec;
|
||||||
|
|
||||||
|
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||||
|
use nssa::AccountId;
|
||||||
|
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey};
|
||||||
|
|
||||||
|
use super::{NativeTokenTransfer, auth_transfer_preparation};
|
||||||
|
use crate::PrivacyPreservingAccount;
|
||||||
|
|
||||||
|
impl NativeTokenTransfer<'_> {
|
||||||
|
pub async fn send_private_transfer_to_outer_account(
|
||||||
|
&self,
|
||||||
|
from: AccountId,
|
||||||
|
to_npk: NullifierPublicKey,
|
||||||
|
to_ipk: IncomingViewingPublicKey,
|
||||||
|
balance_to_move: u128,
|
||||||
|
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
||||||
|
let (instruction_data, program, tx_pre_check) = auth_transfer_preparation(balance_to_move);
|
||||||
|
|
||||||
|
self.0
|
||||||
|
.send_privacy_preserving_tx(
|
||||||
|
vec![
|
||||||
|
PrivacyPreservingAccount::PrivateOwned(from),
|
||||||
|
PrivacyPreservingAccount::PrivateForeign {
|
||||||
|
npk: to_npk,
|
||||||
|
ipk: to_ipk,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
&instruction_data,
|
||||||
|
tx_pre_check,
|
||||||
|
&program,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|(resp, secrets)| {
|
||||||
|
let mut secrets_iter = secrets.into_iter();
|
||||||
|
let first = secrets_iter.next().expect("expected sender's secret");
|
||||||
|
let second = secrets_iter.next().expect("expected receiver's secret");
|
||||||
|
(resp, [first, second])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_private_transfer_to_owned_account(
|
||||||
|
&self,
|
||||||
|
from: AccountId,
|
||||||
|
to: AccountId,
|
||||||
|
balance_to_move: u128,
|
||||||
|
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
||||||
|
let (instruction_data, program, tx_pre_check) = auth_transfer_preparation(balance_to_move);
|
||||||
|
|
||||||
|
self.0
|
||||||
|
.send_privacy_preserving_tx(
|
||||||
|
vec![
|
||||||
|
PrivacyPreservingAccount::PrivateOwned(from),
|
||||||
|
PrivacyPreservingAccount::PrivateOwned(to),
|
||||||
|
],
|
||||||
|
&instruction_data,
|
||||||
|
tx_pre_check,
|
||||||
|
&program,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|(resp, secrets)| {
|
||||||
|
let mut secrets_iter = secrets.into_iter();
|
||||||
|
let first = secrets_iter.next().expect("expected sender's secret");
|
||||||
|
let second = secrets_iter.next().expect("expected receiver's secret");
|
||||||
|
(resp, [first, second])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,21 +5,21 @@ use nssa::{
|
|||||||
public_transaction::{Message, WitnessSet},
|
public_transaction::{Message, WitnessSet},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::WalletCore;
|
use super::NativeTokenTransfer;
|
||||||
|
|
||||||
impl WalletCore {
|
impl NativeTokenTransfer<'_> {
|
||||||
pub async fn send_public_native_token_transfer(
|
pub async fn send_public_transfer(
|
||||||
&self,
|
&self,
|
||||||
from: AccountId,
|
from: AccountId,
|
||||||
to: AccountId,
|
to: AccountId,
|
||||||
balance_to_move: u128,
|
balance_to_move: u128,
|
||||||
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
||||||
let Ok(balance) = self.get_account_balance(from).await else {
|
let Ok(balance) = self.0.get_account_balance(from).await else {
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
return Err(ExecutionFailureKind::SequencerError);
|
||||||
};
|
};
|
||||||
|
|
||||||
if balance >= balance_to_move {
|
if balance >= balance_to_move {
|
||||||
let Ok(nonces) = self.get_accounts_nonces(vec![from]).await else {
|
let Ok(nonces) = self.0.get_accounts_nonces(vec![from]).await else {
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
return Err(ExecutionFailureKind::SequencerError);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ impl WalletCore {
|
|||||||
let message =
|
let message =
|
||||||
Message::try_new(program_id, account_ids, nonces, balance_to_move).unwrap();
|
Message::try_new(program_id, account_ids, nonces, balance_to_move).unwrap();
|
||||||
|
|
||||||
let signing_key = self.storage.user_data.get_pub_account_signing_key(&from);
|
let signing_key = self.0.storage.user_data.get_pub_account_signing_key(&from);
|
||||||
|
|
||||||
let Some(signing_key) = signing_key else {
|
let Some(signing_key) = signing_key else {
|
||||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||||
@ -38,17 +38,17 @@ impl WalletCore {
|
|||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
|
|
||||||
Ok(self.sequencer_client.send_tx_public(tx).await?)
|
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
||||||
} else {
|
} else {
|
||||||
Err(ExecutionFailureKind::InsufficientFundsError)
|
Err(ExecutionFailureKind::InsufficientFundsError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn register_account_under_authenticated_transfers_programs(
|
pub async fn register_account(
|
||||||
&self,
|
&self,
|
||||||
from: AccountId,
|
from: AccountId,
|
||||||
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
||||||
let Ok(nonces) = self.get_accounts_nonces(vec![from]).await else {
|
let Ok(nonces) = self.0.get_accounts_nonces(vec![from]).await else {
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
return Err(ExecutionFailureKind::SequencerError);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ impl WalletCore {
|
|||||||
let program_id = Program::authenticated_transfer_program().id();
|
let program_id = Program::authenticated_transfer_program().id();
|
||||||
let message = Message::try_new(program_id, account_ids, nonces, instruction).unwrap();
|
let message = Message::try_new(program_id, account_ids, nonces, instruction).unwrap();
|
||||||
|
|
||||||
let signing_key = self.storage.user_data.get_pub_account_signing_key(&from);
|
let signing_key = self.0.storage.user_data.get_pub_account_signing_key(&from);
|
||||||
|
|
||||||
let Some(signing_key) = signing_key else {
|
let Some(signing_key) = signing_key else {
|
||||||
return Err(ExecutionFailureKind::KeyNotFoundError);
|
return Err(ExecutionFailureKind::KeyNotFoundError);
|
||||||
@ -67,6 +67,6 @@ impl WalletCore {
|
|||||||
|
|
||||||
let tx = PublicTransaction::new(message, witness_set);
|
let tx = PublicTransaction::new(message, witness_set);
|
||||||
|
|
||||||
Ok(self.sequencer_client.send_tx_public(tx).await?)
|
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
68
wallet/src/program_facades/native_token_transfer/shielded.rs
Normal file
68
wallet/src/program_facades/native_token_transfer/shielded.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||||
|
use nssa::AccountId;
|
||||||
|
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey};
|
||||||
|
|
||||||
|
use super::{NativeTokenTransfer, auth_transfer_preparation};
|
||||||
|
use crate::PrivacyPreservingAccount;
|
||||||
|
|
||||||
|
impl NativeTokenTransfer<'_> {
|
||||||
|
pub async fn send_shielded_transfer(
|
||||||
|
&self,
|
||||||
|
from: AccountId,
|
||||||
|
to: AccountId,
|
||||||
|
balance_to_move: u128,
|
||||||
|
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
||||||
|
let (instruction_data, program, tx_pre_check) = auth_transfer_preparation(balance_to_move);
|
||||||
|
|
||||||
|
self.0
|
||||||
|
.send_privacy_preserving_tx(
|
||||||
|
vec![
|
||||||
|
PrivacyPreservingAccount::Public(from),
|
||||||
|
PrivacyPreservingAccount::PrivateOwned(to),
|
||||||
|
],
|
||||||
|
&instruction_data,
|
||||||
|
tx_pre_check,
|
||||||
|
&program,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|(resp, secrets)| {
|
||||||
|
let first = secrets
|
||||||
|
.into_iter()
|
||||||
|
.next()
|
||||||
|
.expect("expected sender's secret");
|
||||||
|
(resp, first)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_shielded_transfer_to_outer_account(
|
||||||
|
&self,
|
||||||
|
from: AccountId,
|
||||||
|
to_npk: NullifierPublicKey,
|
||||||
|
to_ipk: IncomingViewingPublicKey,
|
||||||
|
balance_to_move: u128,
|
||||||
|
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
||||||
|
let (instruction_data, program, tx_pre_check) = auth_transfer_preparation(balance_to_move);
|
||||||
|
|
||||||
|
self.0
|
||||||
|
.send_privacy_preserving_tx(
|
||||||
|
vec![
|
||||||
|
PrivacyPreservingAccount::Public(from),
|
||||||
|
PrivacyPreservingAccount::PrivateForeign {
|
||||||
|
npk: to_npk,
|
||||||
|
ipk: to_ipk,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
&instruction_data,
|
||||||
|
tx_pre_check,
|
||||||
|
&program,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|(resp, secrets)| {
|
||||||
|
let first = secrets
|
||||||
|
.into_iter()
|
||||||
|
.next()
|
||||||
|
.expect("expected sender's secret");
|
||||||
|
(resp, first)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
53
wallet/src/program_facades/pinata.rs
Normal file
53
wallet/src/program_facades/pinata.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||||
|
use nssa::AccountId;
|
||||||
|
use nssa_core::SharedSecretKey;
|
||||||
|
|
||||||
|
use crate::{PrivacyPreservingAccount, WalletCore};
|
||||||
|
|
||||||
|
pub struct Pinata<'w>(pub &'w WalletCore);
|
||||||
|
|
||||||
|
impl Pinata<'_> {
|
||||||
|
pub async fn claim(
|
||||||
|
&self,
|
||||||
|
pinata_account_id: AccountId,
|
||||||
|
winner_account_id: AccountId,
|
||||||
|
solution: u128,
|
||||||
|
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
||||||
|
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 witness_set = nssa::public_transaction::WitnessSet::for_message(&message, &[]);
|
||||||
|
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||||
|
|
||||||
|
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn claim_private_owned_account(
|
||||||
|
&self,
|
||||||
|
pinata_account_id: AccountId,
|
||||||
|
winner_account_id: AccountId,
|
||||||
|
solution: u128,
|
||||||
|
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
||||||
|
self.0
|
||||||
|
.send_privacy_preserving_tx(
|
||||||
|
vec![
|
||||||
|
PrivacyPreservingAccount::Public(pinata_account_id),
|
||||||
|
PrivacyPreservingAccount::PrivateOwned(winner_account_id),
|
||||||
|
],
|
||||||
|
&nssa::program::Program::serialize_instruction(solution).unwrap(),
|
||||||
|
|_| Ok(()),
|
||||||
|
&nssa::program::Program::pinata(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|(resp, secrets)| {
|
||||||
|
let first = secrets
|
||||||
|
.into_iter()
|
||||||
|
.next()
|
||||||
|
.expect("expected recipient's secret");
|
||||||
|
(resp, first)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
294
wallet/src/program_facades/token.rs
Normal file
294
wallet/src/program_facades/token.rs
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
||||||
|
use nssa::{Account, AccountId, program::Program};
|
||||||
|
use nssa_core::{
|
||||||
|
NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey,
|
||||||
|
program::InstructionData,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{PrivacyPreservingAccount, WalletCore};
|
||||||
|
|
||||||
|
pub struct Token<'w>(pub &'w WalletCore);
|
||||||
|
|
||||||
|
impl Token<'_> {
|
||||||
|
pub async fn send_new_definition(
|
||||||
|
&self,
|
||||||
|
definition_account_id: AccountId,
|
||||||
|
supply_account_id: AccountId,
|
||||||
|
name: [u8; 6],
|
||||||
|
total_supply: u128,
|
||||||
|
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
||||||
|
let account_ids = vec![definition_account_id, supply_account_id];
|
||||||
|
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);
|
||||||
|
let message = nssa::public_transaction::Message::try_new(
|
||||||
|
program_id,
|
||||||
|
account_ids,
|
||||||
|
vec![],
|
||||||
|
instruction,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let witness_set = nssa::public_transaction::WitnessSet::for_message(&message, &[]);
|
||||||
|
|
||||||
|
let tx = nssa::PublicTransaction::new(message, witness_set);
|
||||||
|
|
||||||
|
Ok(self.0.sequencer_client.send_tx_public(tx).await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_new_definition_private_owned(
|
||||||
|
&self,
|
||||||
|
definition_account_id: AccountId,
|
||||||
|
supply_account_id: AccountId,
|
||||||
|
name: [u8; 6],
|
||||||
|
total_supply: u128,
|
||||||
|
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
||||||
|
let (instruction_data, program, tx_pre_check) =
|
||||||
|
token_program_preparation_definition(name, total_supply);
|
||||||
|
|
||||||
|
self.0
|
||||||
|
.send_privacy_preserving_tx(
|
||||||
|
vec![
|
||||||
|
PrivacyPreservingAccount::Public(definition_account_id),
|
||||||
|
PrivacyPreservingAccount::PrivateOwned(supply_account_id),
|
||||||
|
],
|
||||||
|
&instruction_data,
|
||||||
|
tx_pre_check,
|
||||||
|
&program,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|(resp, secrets)| {
|
||||||
|
let first = secrets
|
||||||
|
.into_iter()
|
||||||
|
.next()
|
||||||
|
.expect("expected recipient's secret");
|
||||||
|
(resp, first)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_transfer_transaction(
|
||||||
|
&self,
|
||||||
|
sender_account_id: AccountId,
|
||||||
|
recipient_account_id: AccountId,
|
||||||
|
amount: u128,
|
||||||
|
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
||||||
|
let account_ids = vec![sender_account_id, recipient_account_id];
|
||||||
|
let program_id = nssa::program::Program::token().id();
|
||||||
|
// Instruction must be: [0x01 || amount (little-endian 16 bytes) || 0x00 || 0x00 || 0x00 ||
|
||||||
|
// 0x00 || 0x00 || 0x00].
|
||||||
|
let mut instruction = [0; 23];
|
||||||
|
instruction[0] = 0x01;
|
||||||
|
instruction[1..17].copy_from_slice(&amount.to_le_bytes());
|
||||||
|
let Ok(nonces) = self.0.get_accounts_nonces(vec![sender_account_id]).await else {
|
||||||
|
return Err(ExecutionFailureKind::SequencerError);
|
||||||
|
};
|
||||||
|
let message = nssa::public_transaction::Message::try_new(
|
||||||
|
program_id,
|
||||||
|
account_ids,
|
||||||
|
nonces,
|
||||||
|
instruction,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let Some(signing_key) = self
|
||||||
|
.0
|
||||||
|
.storage
|
||||||
|
.user_data
|
||||||
|
.get_pub_account_signing_key(&sender_account_id)
|
||||||
|
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.0.sequencer_client.send_tx_public(tx).await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_transfer_transaction_private_owned_account(
|
||||||
|
&self,
|
||||||
|
sender_account_id: AccountId,
|
||||||
|
recipient_account_id: AccountId,
|
||||||
|
amount: u128,
|
||||||
|
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
||||||
|
let (instruction_data, program, tx_pre_check) = token_program_preparation_transfer(amount);
|
||||||
|
|
||||||
|
self.0
|
||||||
|
.send_privacy_preserving_tx(
|
||||||
|
vec![
|
||||||
|
PrivacyPreservingAccount::PrivateOwned(sender_account_id),
|
||||||
|
PrivacyPreservingAccount::PrivateOwned(recipient_account_id),
|
||||||
|
],
|
||||||
|
&instruction_data,
|
||||||
|
tx_pre_check,
|
||||||
|
&program,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|(resp, secrets)| {
|
||||||
|
let mut iter = secrets.into_iter();
|
||||||
|
let first = iter.next().expect("expected sender's secret");
|
||||||
|
let second = iter.next().expect("expected recipient's secret");
|
||||||
|
(resp, [first, second])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_transfer_transaction_private_foreign_account(
|
||||||
|
&self,
|
||||||
|
sender_account_id: AccountId,
|
||||||
|
recipient_npk: NullifierPublicKey,
|
||||||
|
recipient_ipk: IncomingViewingPublicKey,
|
||||||
|
amount: u128,
|
||||||
|
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
||||||
|
let (instruction_data, program, tx_pre_check) = token_program_preparation_transfer(amount);
|
||||||
|
|
||||||
|
self.0
|
||||||
|
.send_privacy_preserving_tx(
|
||||||
|
vec![
|
||||||
|
PrivacyPreservingAccount::PrivateOwned(sender_account_id),
|
||||||
|
PrivacyPreservingAccount::PrivateForeign {
|
||||||
|
npk: recipient_npk,
|
||||||
|
ipk: recipient_ipk,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
&instruction_data,
|
||||||
|
tx_pre_check,
|
||||||
|
&program,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|(resp, secrets)| {
|
||||||
|
let mut iter = secrets.into_iter();
|
||||||
|
let first = iter.next().expect("expected sender's secret");
|
||||||
|
let second = iter.next().expect("expected recipient's secret");
|
||||||
|
(resp, [first, second])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_transfer_transaction_deshielded(
|
||||||
|
&self,
|
||||||
|
sender_account_id: AccountId,
|
||||||
|
recipient_account_id: AccountId,
|
||||||
|
amount: u128,
|
||||||
|
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
||||||
|
let (instruction_data, program, tx_pre_check) = token_program_preparation_transfer(amount);
|
||||||
|
|
||||||
|
self.0
|
||||||
|
.send_privacy_preserving_tx(
|
||||||
|
vec![
|
||||||
|
PrivacyPreservingAccount::PrivateOwned(sender_account_id),
|
||||||
|
PrivacyPreservingAccount::Public(recipient_account_id),
|
||||||
|
],
|
||||||
|
&instruction_data,
|
||||||
|
tx_pre_check,
|
||||||
|
&program,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|(resp, secrets)| {
|
||||||
|
let first = secrets
|
||||||
|
.into_iter()
|
||||||
|
.next()
|
||||||
|
.expect("expected sender's secret");
|
||||||
|
(resp, first)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_transfer_transaction_shielded_owned_account(
|
||||||
|
&self,
|
||||||
|
sender_account_id: AccountId,
|
||||||
|
recipient_account_id: AccountId,
|
||||||
|
amount: u128,
|
||||||
|
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
||||||
|
let (instruction_data, program, tx_pre_check) = token_program_preparation_transfer(amount);
|
||||||
|
|
||||||
|
self.0
|
||||||
|
.send_privacy_preserving_tx(
|
||||||
|
vec![
|
||||||
|
PrivacyPreservingAccount::Public(sender_account_id),
|
||||||
|
PrivacyPreservingAccount::PrivateOwned(recipient_account_id),
|
||||||
|
],
|
||||||
|
&instruction_data,
|
||||||
|
tx_pre_check,
|
||||||
|
&program,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|(resp, secrets)| {
|
||||||
|
let first = secrets
|
||||||
|
.into_iter()
|
||||||
|
.next()
|
||||||
|
.expect("expected recipient's secret");
|
||||||
|
(resp, first)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_transfer_transaction_shielded_foreign_account(
|
||||||
|
&self,
|
||||||
|
sender_account_id: AccountId,
|
||||||
|
recipient_npk: NullifierPublicKey,
|
||||||
|
recipient_ipk: IncomingViewingPublicKey,
|
||||||
|
amount: u128,
|
||||||
|
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
||||||
|
let (instruction_data, program, tx_pre_check) = token_program_preparation_transfer(amount);
|
||||||
|
|
||||||
|
self.0
|
||||||
|
.send_privacy_preserving_tx(
|
||||||
|
vec![
|
||||||
|
PrivacyPreservingAccount::Public(sender_account_id),
|
||||||
|
PrivacyPreservingAccount::PrivateForeign {
|
||||||
|
npk: recipient_npk,
|
||||||
|
ipk: recipient_ipk,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
&instruction_data,
|
||||||
|
tx_pre_check,
|
||||||
|
&program,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map(|(resp, secrets)| {
|
||||||
|
let first = secrets
|
||||||
|
.into_iter()
|
||||||
|
.next()
|
||||||
|
.expect("expected recipient's secret");
|
||||||
|
(resp, first)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn token_program_preparation_transfer(
|
||||||
|
amount: u128,
|
||||||
|
) -> (
|
||||||
|
InstructionData,
|
||||||
|
Program,
|
||||||
|
impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>,
|
||||||
|
) {
|
||||||
|
// Instruction must be: [0x01 || amount (little-endian 16 bytes) || 0x00 || 0x00 || 0x00 ||
|
||||||
|
// 0x00 || 0x00 || 0x00].
|
||||||
|
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]| Ok(());
|
||||||
|
|
||||||
|
(instruction_data, program, tx_pre_check)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn token_program_preparation_definition(
|
||||||
|
name: [u8; 6],
|
||||||
|
total_supply: u128,
|
||||||
|
) -> (
|
||||||
|
InstructionData,
|
||||||
|
Program,
|
||||||
|
impl FnOnce(&[&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]| Ok(());
|
||||||
|
|
||||||
|
(instruction_data, program, tx_pre_check)
|
||||||
|
}
|
||||||
@ -1,2 +0,0 @@
|
|||||||
pub mod pinata;
|
|
||||||
pub mod token;
|
|
||||||
@ -1,161 +0,0 @@
|
|||||||
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
|
||||||
use key_protocol::key_management::ephemeral_key_holder::EphemeralKeyHolder;
|
|
||||||
use nssa::{AccountId, privacy_preserving_transaction::circuit};
|
|
||||||
use nssa_core::{MembershipProof, SharedSecretKey, account::AccountWithMetadata};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
WalletCore, helperfunctions::produce_random_nonces, transaction_utils::AccountPreparedData,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl WalletCore {
|
|
||||||
pub async fn claim_pinata(
|
|
||||||
&self,
|
|
||||||
pinata_account_id: AccountId,
|
|
||||||
winner_account_id: AccountId,
|
|
||||||
solution: u128,
|
|
||||||
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
|
||||||
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 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 claim_pinata_private_owned_account_already_initialized(
|
|
||||||
&self,
|
|
||||||
pinata_account_id: AccountId,
|
|
||||||
winner_account_id: AccountId,
|
|
||||||
solution: u128,
|
|
||||||
winner_proof: MembershipProof,
|
|
||||||
) -> Result<(SendTxResponse, [SharedSecretKey; 1]), ExecutionFailureKind> {
|
|
||||||
let AccountPreparedData {
|
|
||||||
nsk: winner_nsk,
|
|
||||||
npk: winner_npk,
|
|
||||||
ipk: winner_ipk,
|
|
||||||
auth_acc: winner_pre,
|
|
||||||
proof: _,
|
|
||||||
} = self
|
|
||||||
.private_acc_preparation(winner_account_id, true, false)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let pinata_acc = self.get_account_public(pinata_account_id).await.unwrap();
|
|
||||||
|
|
||||||
let program = nssa::program::Program::pinata();
|
|
||||||
|
|
||||||
let pinata_pre = AccountWithMetadata::new(pinata_acc.clone(), false, pinata_account_id);
|
|
||||||
|
|
||||||
let eph_holder_winner = EphemeralKeyHolder::new(&winner_npk);
|
|
||||||
let shared_secret_winner = eph_holder_winner.calculate_shared_secret_sender(&winner_ipk);
|
|
||||||
|
|
||||||
let (output, proof) = circuit::execute_and_prove(
|
|
||||||
&[pinata_pre, winner_pre],
|
|
||||||
&nssa::program::Program::serialize_instruction(solution).unwrap(),
|
|
||||||
&[0, 1],
|
|
||||||
&produce_random_nonces(1),
|
|
||||||
&[(winner_npk.clone(), shared_secret_winner.clone())],
|
|
||||||
&[(winner_nsk.unwrap(), winner_proof)],
|
|
||||||
&program,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let message =
|
|
||||||
nssa::privacy_preserving_transaction::message::Message::try_from_circuit_output(
|
|
||||||
vec![pinata_account_id],
|
|
||||||
vec![],
|
|
||||||
vec![(
|
|
||||||
winner_npk.clone(),
|
|
||||||
winner_ipk.clone(),
|
|
||||||
eph_holder_winner.generate_ephemeral_public_key(),
|
|
||||||
)],
|
|
||||||
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,
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok((
|
|
||||||
self.sequencer_client.send_tx_private(tx).await?,
|
|
||||||
[shared_secret_winner],
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn claim_pinata_private_owned_account_not_initialized(
|
|
||||||
&self,
|
|
||||||
pinata_account_id: AccountId,
|
|
||||||
winner_account_id: AccountId,
|
|
||||||
solution: u128,
|
|
||||||
) -> Result<(SendTxResponse, [SharedSecretKey; 1]), ExecutionFailureKind> {
|
|
||||||
let AccountPreparedData {
|
|
||||||
nsk: _,
|
|
||||||
npk: winner_npk,
|
|
||||||
ipk: winner_ipk,
|
|
||||||
auth_acc: winner_pre,
|
|
||||||
proof: _,
|
|
||||||
} = self
|
|
||||||
.private_acc_preparation(winner_account_id, false, false)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let pinata_acc = self.get_account_public(pinata_account_id).await.unwrap();
|
|
||||||
|
|
||||||
let program = nssa::program::Program::pinata();
|
|
||||||
|
|
||||||
let pinata_pre = AccountWithMetadata::new(pinata_acc.clone(), false, pinata_account_id);
|
|
||||||
|
|
||||||
let eph_holder_winner = EphemeralKeyHolder::new(&winner_npk);
|
|
||||||
let shared_secret_winner = eph_holder_winner.calculate_shared_secret_sender(&winner_ipk);
|
|
||||||
|
|
||||||
let (output, proof) = circuit::execute_and_prove(
|
|
||||||
&[pinata_pre, winner_pre],
|
|
||||||
&nssa::program::Program::serialize_instruction(solution).unwrap(),
|
|
||||||
&[0, 2],
|
|
||||||
&produce_random_nonces(1),
|
|
||||||
&[(winner_npk.clone(), shared_secret_winner.clone())],
|
|
||||||
&[],
|
|
||||||
&program,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let message =
|
|
||||||
nssa::privacy_preserving_transaction::message::Message::try_from_circuit_output(
|
|
||||||
vec![pinata_account_id],
|
|
||||||
vec![],
|
|
||||||
vec![(
|
|
||||||
winner_npk.clone(),
|
|
||||||
winner_ipk.clone(),
|
|
||||||
eph_holder_winner.generate_ephemeral_public_key(),
|
|
||||||
)],
|
|
||||||
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,
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok((
|
|
||||||
self.sequencer_client.send_tx_private(tx).await?,
|
|
||||||
[shared_secret_winner],
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,290 +0,0 @@
|
|||||||
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
|
||||||
use nssa::{Account, AccountId, program::Program};
|
|
||||||
use nssa_core::{
|
|
||||||
NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey,
|
|
||||||
program::InstructionData,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{PrivacyPreservingAccount, WalletCore};
|
|
||||||
|
|
||||||
impl WalletCore {
|
|
||||||
pub fn token_program_preparation_transfer(
|
|
||||||
amount: u128,
|
|
||||||
) -> (
|
|
||||||
InstructionData,
|
|
||||||
Program,
|
|
||||||
impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>,
|
|
||||||
) {
|
|
||||||
// Instruction must be: [0x01 || amount (little-endian 16 bytes) || 0x00 || 0x00 || 0x00 ||
|
|
||||||
// 0x00 || 0x00 || 0x00].
|
|
||||||
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]| Ok(());
|
|
||||||
|
|
||||||
(instruction_data, program, tx_pre_check)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn token_program_preparation_definition(
|
|
||||||
name: [u8; 6],
|
|
||||||
total_supply: u128,
|
|
||||||
) -> (
|
|
||||||
InstructionData,
|
|
||||||
Program,
|
|
||||||
impl FnOnce(&[&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]| Ok(());
|
|
||||||
|
|
||||||
(instruction_data, program, tx_pre_check)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_new_token_definition(
|
|
||||||
&self,
|
|
||||||
definition_account_id: AccountId,
|
|
||||||
supply_account_id: AccountId,
|
|
||||||
name: [u8; 6],
|
|
||||||
total_supply: u128,
|
|
||||||
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
|
||||||
let account_ids = vec![definition_account_id, supply_account_id];
|
|
||||||
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);
|
|
||||||
let message = nssa::public_transaction::Message::try_new(
|
|
||||||
program_id,
|
|
||||||
account_ids,
|
|
||||||
vec![],
|
|
||||||
instruction,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
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,
|
|
||||||
definition_account_id: AccountId,
|
|
||||||
supply_account_id: AccountId,
|
|
||||||
name: [u8; 6],
|
|
||||||
total_supply: u128,
|
|
||||||
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
|
||||||
let (instruction_data, program, tx_pre_check) =
|
|
||||||
WalletCore::token_program_preparation_definition(name, total_supply);
|
|
||||||
|
|
||||||
self.send_privacy_preserving_tx(
|
|
||||||
vec![
|
|
||||||
PrivacyPreservingAccount::Public(definition_account_id),
|
|
||||||
PrivacyPreservingAccount::PrivateLocal(supply_account_id),
|
|
||||||
],
|
|
||||||
instruction_data,
|
|
||||||
tx_pre_check,
|
|
||||||
program,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map(|(resp, secrets)| {
|
|
||||||
let first = secrets
|
|
||||||
.into_iter()
|
|
||||||
.next()
|
|
||||||
.expect("expected recipient's secret");
|
|
||||||
(resp, first)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_transfer_token_transaction(
|
|
||||||
&self,
|
|
||||||
sender_account_id: AccountId,
|
|
||||||
recipient_account_id: AccountId,
|
|
||||||
amount: u128,
|
|
||||||
) -> Result<SendTxResponse, ExecutionFailureKind> {
|
|
||||||
let account_ids = vec![sender_account_id, recipient_account_id];
|
|
||||||
let program_id = nssa::program::Program::token().id();
|
|
||||||
// Instruction must be: [0x01 || amount (little-endian 16 bytes) || 0x00 || 0x00 || 0x00 ||
|
|
||||||
// 0x00 || 0x00 || 0x00].
|
|
||||||
let mut instruction = [0; 23];
|
|
||||||
instruction[0] = 0x01;
|
|
||||||
instruction[1..17].copy_from_slice(&amount.to_le_bytes());
|
|
||||||
let Ok(nonces) = self.get_accounts_nonces(vec![sender_account_id]).await else {
|
|
||||||
return Err(ExecutionFailureKind::SequencerError);
|
|
||||||
};
|
|
||||||
let message = nssa::public_transaction::Message::try_new(
|
|
||||||
program_id,
|
|
||||||
account_ids,
|
|
||||||
nonces,
|
|
||||||
instruction,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let Some(signing_key) = self
|
|
||||||
.storage
|
|
||||||
.user_data
|
|
||||||
.get_pub_account_signing_key(&sender_account_id)
|
|
||||||
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(
|
|
||||||
&self,
|
|
||||||
sender_account_id: AccountId,
|
|
||||||
recipient_account_id: AccountId,
|
|
||||||
amount: u128,
|
|
||||||
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
|
||||||
let (instruction_data, program, tx_pre_check) =
|
|
||||||
WalletCore::token_program_preparation_transfer(amount);
|
|
||||||
|
|
||||||
self.send_privacy_preserving_tx(
|
|
||||||
vec![
|
|
||||||
PrivacyPreservingAccount::PrivateLocal(sender_account_id),
|
|
||||||
PrivacyPreservingAccount::PrivateLocal(recipient_account_id),
|
|
||||||
],
|
|
||||||
instruction_data,
|
|
||||||
tx_pre_check,
|
|
||||||
program,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map(|(resp, secrets)| {
|
|
||||||
let mut iter = secrets.into_iter();
|
|
||||||
let first = iter.next().expect("expected sender's secret");
|
|
||||||
let second = iter.next().expect("expected recipient's secret");
|
|
||||||
(resp, [first, second])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_transfer_token_transaction_private_foreign_account(
|
|
||||||
&self,
|
|
||||||
sender_account_id: AccountId,
|
|
||||||
recipient_npk: NullifierPublicKey,
|
|
||||||
recipient_ipk: IncomingViewingPublicKey,
|
|
||||||
amount: u128,
|
|
||||||
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
|
||||||
let (instruction_data, program, tx_pre_check) =
|
|
||||||
WalletCore::token_program_preparation_transfer(amount);
|
|
||||||
|
|
||||||
self.send_privacy_preserving_tx(
|
|
||||||
vec![
|
|
||||||
PrivacyPreservingAccount::PrivateLocal(sender_account_id),
|
|
||||||
PrivacyPreservingAccount::PrivateForeign {
|
|
||||||
npk: recipient_npk,
|
|
||||||
ipk: recipient_ipk,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
instruction_data,
|
|
||||||
tx_pre_check,
|
|
||||||
program,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map(|(resp, secrets)| {
|
|
||||||
let mut iter = secrets.into_iter();
|
|
||||||
let first = iter.next().expect("expected sender's secret");
|
|
||||||
let second = iter.next().expect("expected recipient's secret");
|
|
||||||
(resp, [first, second])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_transfer_token_transaction_deshielded(
|
|
||||||
&self,
|
|
||||||
sender_account_id: AccountId,
|
|
||||||
recipient_account_id: AccountId,
|
|
||||||
amount: u128,
|
|
||||||
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
|
||||||
let (instruction_data, program, tx_pre_check) =
|
|
||||||
WalletCore::token_program_preparation_transfer(amount);
|
|
||||||
|
|
||||||
self.send_privacy_preserving_tx(
|
|
||||||
vec![
|
|
||||||
PrivacyPreservingAccount::PrivateLocal(sender_account_id),
|
|
||||||
PrivacyPreservingAccount::Public(recipient_account_id),
|
|
||||||
],
|
|
||||||
instruction_data,
|
|
||||||
tx_pre_check,
|
|
||||||
program,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map(|(resp, secrets)| {
|
|
||||||
let first = secrets
|
|
||||||
.into_iter()
|
|
||||||
.next()
|
|
||||||
.expect("expected sender's secret");
|
|
||||||
(resp, first)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_transfer_token_transaction_shielded_owned_account(
|
|
||||||
&self,
|
|
||||||
sender_account_id: AccountId,
|
|
||||||
recipient_account_id: AccountId,
|
|
||||||
amount: u128,
|
|
||||||
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
|
||||||
let (instruction_data, program, tx_pre_check) =
|
|
||||||
WalletCore::token_program_preparation_transfer(amount);
|
|
||||||
|
|
||||||
self.send_privacy_preserving_tx(
|
|
||||||
vec![
|
|
||||||
PrivacyPreservingAccount::Public(sender_account_id),
|
|
||||||
PrivacyPreservingAccount::PrivateLocal(recipient_account_id),
|
|
||||||
],
|
|
||||||
instruction_data,
|
|
||||||
tx_pre_check,
|
|
||||||
program,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map(|(resp, secrets)| {
|
|
||||||
let first = secrets
|
|
||||||
.into_iter()
|
|
||||||
.next()
|
|
||||||
.expect("expected recipient's secret");
|
|
||||||
(resp, first)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_transfer_token_transaction_shielded_foreign_account(
|
|
||||||
&self,
|
|
||||||
sender_account_id: AccountId,
|
|
||||||
recipient_npk: NullifierPublicKey,
|
|
||||||
recipient_ipk: IncomingViewingPublicKey,
|
|
||||||
amount: u128,
|
|
||||||
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
|
||||||
let (instruction_data, program, tx_pre_check) =
|
|
||||||
WalletCore::token_program_preparation_transfer(amount);
|
|
||||||
|
|
||||||
self.send_privacy_preserving_tx(
|
|
||||||
vec![
|
|
||||||
PrivacyPreservingAccount::Public(sender_account_id),
|
|
||||||
PrivacyPreservingAccount::PrivateForeign {
|
|
||||||
npk: recipient_npk,
|
|
||||||
ipk: recipient_ipk,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
instruction_data,
|
|
||||||
tx_pre_check,
|
|
||||||
program,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map(|(resp, secrets)| {
|
|
||||||
let first = secrets
|
|
||||||
.into_iter()
|
|
||||||
.next()
|
|
||||||
.expect("expected recipient's secret");
|
|
||||||
(resp, first)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
|
||||||
use nssa::AccountId;
|
|
||||||
|
|
||||||
use crate::{PrivacyPreservingAccount, WalletCore};
|
|
||||||
|
|
||||||
impl WalletCore {
|
|
||||||
pub async fn send_deshielded_native_token_transfer(
|
|
||||||
&self,
|
|
||||||
from: AccountId,
|
|
||||||
to: AccountId,
|
|
||||||
balance_to_move: u128,
|
|
||||||
) -> Result<(SendTxResponse, nssa_core::SharedSecretKey), ExecutionFailureKind> {
|
|
||||||
let (instruction_data, program, tx_pre_check) =
|
|
||||||
WalletCore::auth_transfer_preparation(balance_to_move);
|
|
||||||
|
|
||||||
self.send_privacy_preserving_tx(
|
|
||||||
vec![
|
|
||||||
PrivacyPreservingAccount::PrivateLocal(from),
|
|
||||||
PrivacyPreservingAccount::Public(to),
|
|
||||||
],
|
|
||||||
instruction_data,
|
|
||||||
tx_pre_check,
|
|
||||||
program,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map(|(resp, secrets)| {
|
|
||||||
let first = secrets
|
|
||||||
.into_iter()
|
|
||||||
.next()
|
|
||||||
.expect("expected sender's secret");
|
|
||||||
(resp, first)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
use common::error::ExecutionFailureKind;
|
|
||||||
use nssa::{Account, program::Program};
|
|
||||||
use nssa_core::program::InstructionData;
|
|
||||||
|
|
||||||
use crate::WalletCore;
|
|
||||||
|
|
||||||
pub mod deshielded;
|
|
||||||
pub mod private;
|
|
||||||
pub mod public;
|
|
||||||
pub mod shielded;
|
|
||||||
|
|
||||||
impl WalletCore {
|
|
||||||
pub fn auth_transfer_preparation(
|
|
||||||
balance_to_move: u128,
|
|
||||||
) -> (
|
|
||||||
InstructionData,
|
|
||||||
Program,
|
|
||||||
impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>,
|
|
||||||
) {
|
|
||||||
let instruction_data = Program::serialize_instruction(balance_to_move).unwrap();
|
|
||||||
let program = Program::authenticated_transfer_program();
|
|
||||||
let tx_pre_check = move |accounts: &[&Account]| {
|
|
||||||
let from = accounts[0];
|
|
||||||
if from.balance >= balance_to_move {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(ExecutionFailureKind::InsufficientFundsError)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
(instruction_data, program, tx_pre_check)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
use std::vec;
|
|
||||||
|
|
||||||
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
|
||||||
use nssa::AccountId;
|
|
||||||
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey};
|
|
||||||
|
|
||||||
use crate::{PrivacyPreservingAccount, WalletCore};
|
|
||||||
|
|
||||||
impl WalletCore {
|
|
||||||
pub async fn send_private_native_token_transfer_outer_account(
|
|
||||||
&self,
|
|
||||||
from: AccountId,
|
|
||||||
to_npk: NullifierPublicKey,
|
|
||||||
to_ipk: IncomingViewingPublicKey,
|
|
||||||
balance_to_move: u128,
|
|
||||||
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
|
||||||
let (instruction_data, program, tx_pre_check) =
|
|
||||||
WalletCore::auth_transfer_preparation(balance_to_move);
|
|
||||||
|
|
||||||
self.send_privacy_preserving_tx(
|
|
||||||
vec![
|
|
||||||
PrivacyPreservingAccount::PrivateLocal(from),
|
|
||||||
PrivacyPreservingAccount::PrivateForeign {
|
|
||||||
npk: to_npk,
|
|
||||||
ipk: to_ipk,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
instruction_data,
|
|
||||||
tx_pre_check,
|
|
||||||
program,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map(|(resp, secrets)| {
|
|
||||||
let mut secrets_iter = secrets.into_iter();
|
|
||||||
let first = secrets_iter.next().expect("expected sender's secret");
|
|
||||||
let second = secrets_iter.next().expect("expected receiver's secret");
|
|
||||||
(resp, [first, second])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_private_native_token_transfer_owned_account(
|
|
||||||
&self,
|
|
||||||
from: AccountId,
|
|
||||||
to: AccountId,
|
|
||||||
balance_to_move: u128,
|
|
||||||
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
|
|
||||||
let (instruction_data, program, tx_pre_check) =
|
|
||||||
WalletCore::auth_transfer_preparation(balance_to_move);
|
|
||||||
|
|
||||||
self.send_privacy_preserving_tx(
|
|
||||||
vec![
|
|
||||||
PrivacyPreservingAccount::PrivateLocal(from),
|
|
||||||
PrivacyPreservingAccount::PrivateLocal(to),
|
|
||||||
],
|
|
||||||
instruction_data,
|
|
||||||
tx_pre_check,
|
|
||||||
program,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map(|(resp, secrets)| {
|
|
||||||
let mut secrets_iter = secrets.into_iter();
|
|
||||||
let first = secrets_iter.next().expect("expected sender's secret");
|
|
||||||
let second = secrets_iter.next().expect("expected receiver's secret");
|
|
||||||
(resp, [first, second])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
use common::{error::ExecutionFailureKind, sequencer_client::json::SendTxResponse};
|
|
||||||
use nssa::AccountId;
|
|
||||||
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey};
|
|
||||||
|
|
||||||
use crate::{PrivacyPreservingAccount, WalletCore};
|
|
||||||
|
|
||||||
impl WalletCore {
|
|
||||||
pub async fn send_shielded_native_token_transfer(
|
|
||||||
&self,
|
|
||||||
from: AccountId,
|
|
||||||
to: AccountId,
|
|
||||||
balance_to_move: u128,
|
|
||||||
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
|
||||||
let (instruction_data, program, tx_pre_check) =
|
|
||||||
WalletCore::auth_transfer_preparation(balance_to_move);
|
|
||||||
|
|
||||||
self.send_privacy_preserving_tx(
|
|
||||||
vec![
|
|
||||||
PrivacyPreservingAccount::Public(from),
|
|
||||||
PrivacyPreservingAccount::PrivateLocal(to),
|
|
||||||
],
|
|
||||||
instruction_data,
|
|
||||||
tx_pre_check,
|
|
||||||
program,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map(|(resp, secrets)| {
|
|
||||||
let first = secrets
|
|
||||||
.into_iter()
|
|
||||||
.next()
|
|
||||||
.expect("expected sender's secret");
|
|
||||||
(resp, first)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_shielded_native_token_transfer_outer_account(
|
|
||||||
&self,
|
|
||||||
from: AccountId,
|
|
||||||
to_npk: NullifierPublicKey,
|
|
||||||
to_ipk: IncomingViewingPublicKey,
|
|
||||||
balance_to_move: u128,
|
|
||||||
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
|
|
||||||
let (instruction_data, program, tx_pre_check) =
|
|
||||||
WalletCore::auth_transfer_preparation(balance_to_move);
|
|
||||||
|
|
||||||
self.send_privacy_preserving_tx(
|
|
||||||
vec![
|
|
||||||
PrivacyPreservingAccount::Public(from),
|
|
||||||
PrivacyPreservingAccount::PrivateForeign {
|
|
||||||
npk: to_npk,
|
|
||||||
ipk: to_ipk,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
instruction_data,
|
|
||||||
tx_pre_check,
|
|
||||||
program,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map(|(resp, secrets)| {
|
|
||||||
let first = secrets
|
|
||||||
.into_iter()
|
|
||||||
.next()
|
|
||||||
.expect("expected sender's secret");
|
|
||||||
(resp, first)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user