mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-06-02 07:09:29 +00:00
Merge remote-tracking branch 'origin/main' into marvin/pq-public-keys
This commit is contained in:
commit
39163f942e
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -3655,7 +3655,7 @@ dependencies = [
|
||||
"libc",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"socket2 0.6.3",
|
||||
"socket2 0.5.10",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
@ -7465,7 +7465,7 @@ dependencies = [
|
||||
"quinn-udp",
|
||||
"rustc-hash",
|
||||
"rustls",
|
||||
"socket2 0.6.3",
|
||||
"socket2 0.5.10",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
@ -7502,9 +7502,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]]
|
||||
@ -8476,7 +8476,7 @@ dependencies = [
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"webpki-root-certs 0.26.11",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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
|
||||
|
||||
@ -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<u8> = 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
|
||||
|
||||
@ -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 = ();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -32,7 +32,7 @@ use nssa_core::{
|
||||
use sequencer_service_rpc::RpcClient as _;
|
||||
use tokio::test;
|
||||
use wallet::{
|
||||
PrivacyPreservingAccount, WalletCore,
|
||||
AccountIdentity, WalletCore,
|
||||
cli::{Command, account::AccountSubcommand},
|
||||
};
|
||||
|
||||
@ -129,8 +129,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,
|
||||
|
||||
@ -7,8 +7,9 @@ use crate::account::{Account, AccountId};
|
||||
/// A commitment to all zero data.
|
||||
/// ```python
|
||||
/// from hashlib import sha256
|
||||
/// prefix = b"/LEE/v0.3/Commitment/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
/// hasher = sha256()
|
||||
/// hasher.update(bytes([0] * 32 + [0] * 32 + [0] * 16 + [0] * 16 + list(sha256().digest())))
|
||||
/// hasher.update(prefix + bytes([0] * 32 + [0] * 32 + [0] * 16 + [0] * 16 + list(sha256().digest())))
|
||||
/// DUMMY_COMMITMENT = hasher.digest()
|
||||
/// ```
|
||||
pub const DUMMY_COMMITMENT: Commitment = Commitment([
|
||||
|
||||
@ -96,6 +96,9 @@ pub enum InvalidProgramBehaviorError {
|
||||
#[error("Unauthorized account marked as authorized")]
|
||||
InvalidAccountAuthorization { account_id: AccountId },
|
||||
|
||||
#[error("Authorized account marked as not authorized")]
|
||||
AuthorizedAccountMarkedAsNotAuthorized { account_id: AccountId },
|
||||
|
||||
#[error("Program ID mismatch: expected {expected:?}, actual {actual:?}")]
|
||||
MismatchedProgramId {
|
||||
expected: ProgramId,
|
||||
|
||||
@ -173,12 +173,18 @@ impl ValidatedStateDiff {
|
||||
);
|
||||
|
||||
// Check that the program output pre_states marked as authorized are indeed
|
||||
// authorized.
|
||||
// authorized, and vice-versa.
|
||||
let is_indeed_authorized = is_authorized(&account_id);
|
||||
ensure!(
|
||||
!pre.is_authorized || is_indeed_authorized,
|
||||
InvalidProgramBehaviorError::InvalidAccountAuthorization { account_id }
|
||||
);
|
||||
ensure!(
|
||||
pre.is_authorized || !is_indeed_authorized,
|
||||
InvalidProgramBehaviorError::AuthorizedAccountMarkedAsNotAuthorized {
|
||||
account_id
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Verify that the program output's self_program_id matches the expected program ID.
|
||||
@ -269,11 +275,20 @@ impl ValidatedStateDiff {
|
||||
// the loop above already gates program_output's `is_authorized` via the
|
||||
// `!pre.is_authorized || is_indeed_authorized` check, while `chained_call.
|
||||
// pre_states` is caller-controlled and can be forged (audit-issue 91).
|
||||
let authorized_accounts: HashSet<_> = program_output
|
||||
.pre_states
|
||||
.iter()
|
||||
.filter(|pre| pre.is_authorized)
|
||||
.map(|pre| pre.account_id)
|
||||
//
|
||||
// Union with the caller's authorized set so that authorization is monotonically
|
||||
// growing: once an account is authorized at any point in the chain it remains
|
||||
// authorized for all subsequent calls.
|
||||
let authorized_accounts: HashSet<_> = caller_data
|
||||
.authorized_accounts
|
||||
.into_iter()
|
||||
.chain(
|
||||
program_output
|
||||
.pre_states
|
||||
.iter()
|
||||
.filter(|pre| pre.is_authorized)
|
||||
.map(|pre| pre.account_id),
|
||||
)
|
||||
.collect();
|
||||
for new_call in program_output.chained_calls.into_iter().rev() {
|
||||
chained_calls.push_front((
|
||||
@ -341,7 +356,13 @@ impl ValidatedStateDiff {
|
||||
|
||||
// Check there are no duplicate nullifiers in the new_nullifiers list
|
||||
ensure!(
|
||||
n_unique(&message.new_nullifiers) == message.new_nullifiers.len(),
|
||||
n_unique(
|
||||
&message
|
||||
.new_nullifiers
|
||||
.iter()
|
||||
.map(|(n, _)| n)
|
||||
.collect::<Vec<_>>()
|
||||
) == message.new_nullifiers.len(),
|
||||
NssaError::InvalidInput("Duplicate nullifiers found in message".into())
|
||||
);
|
||||
|
||||
|
||||
@ -62,7 +62,7 @@ pub fn compute_circuit_output(
|
||||
Nullifier::for_account_initialization(&account_id),
|
||||
DUMMY_COMMITMENT_HASH,
|
||||
);
|
||||
let new_nonce = pre_state.account.nonce.private_account_nonce_increment(nsk);
|
||||
let new_nonce = Nonce::private_account_nonce_init(&account_id);
|
||||
|
||||
emit_private_output(
|
||||
&mut output,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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<PrivacyPreservingAccount>,
|
||||
accounts: Vec<AccountIdentity>,
|
||||
) -> Result<Self, ExecutionFailureKind> {
|
||||
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,
|
||||
@ -412,7 +427,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]),
|
||||
@ -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 signing;
|
||||
pub mod storage;
|
||||
@ -273,13 +273,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<PrivacyPreservingAccount> {
|
||||
pub fn resolve_private_account(&self, account_id: nssa::AccountId) -> Option<AccountIdentity> {
|
||||
// Check key tree first
|
||||
if self
|
||||
.storage
|
||||
@ -287,7 +284,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
|
||||
@ -302,7 +299,7 @@ impl WalletCore {
|
||||
|
||||
if let (Some(pda_seed), Some(program_id)) = (entry.pda_seed, entry.authority_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(),
|
||||
@ -319,7 +316,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(),
|
||||
@ -544,7 +541,7 @@ impl WalletCore {
|
||||
|
||||
pub async fn send_privacy_preserving_tx(
|
||||
&self,
|
||||
accounts: Vec<PrivacyPreservingAccount>,
|
||||
accounts: Vec<AccountIdentity>,
|
||||
instruction_data: InstructionData,
|
||||
program: &ProgramWithDependencies,
|
||||
) -> Result<(HashType, Vec<SharedSecretKey>), ExecutionFailureKind> {
|
||||
@ -556,12 +553,12 @@ impl WalletCore {
|
||||
|
||||
pub async fn send_privacy_preserving_tx_with_pre_check(
|
||||
&self,
|
||||
accounts: Vec<PrivacyPreservingAccount>,
|
||||
accounts: Vec<AccountIdentity>,
|
||||
instruction_data: InstructionData,
|
||||
program: &ProgramWithDependencies,
|
||||
tx_pre_check: impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>,
|
||||
) -> Result<(HashType, Vec<SharedSecretKey>), 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(
|
||||
@ -613,6 +610,65 @@ impl WalletCore {
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn send_pub_tx(
|
||||
&self,
|
||||
accounts: Vec<AccountIdentity>,
|
||||
instruction_data: InstructionData,
|
||||
program: &ProgramWithDependencies,
|
||||
) -> Result<HashType, ExecutionFailureKind> {
|
||||
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<AccountIdentity>,
|
||||
instruction_data: InstructionData,
|
||||
program: &ProgramWithDependencies,
|
||||
tx_pre_check: impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>,
|
||||
) -> Result<HashType, ExecutionFailureKind> {
|
||||
// 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::<Vec<_>>(),
|
||||
)?;
|
||||
|
||||
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<u64> {
|
||||
let latest_block_id = self.sequencer_client.get_last_block_id().await?;
|
||||
println!("Latest block is {latest_block_id}");
|
||||
|
||||
@ -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<HashType, ExecutionFailureKind> {
|
||||
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<HashType, ExecutionFailureKind> {
|
||||
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<HashType, ExecutionFailureKind> {
|
||||
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<HashType, ExecutionFailureKind> {
|
||||
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<HashType, ExecutionFailureKind> {
|
||||
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?)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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<HashType, 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 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)?,
|
||||
|
||||
@ -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<HashType, ExecutionFailureKind> {
|
||||
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<HashType, ExecutionFailureKind> {
|
||||
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<HashType, ExecutionFailureKind> {
|
||||
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<HashType, ExecutionFailureKind> {
|
||||
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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user