fix: token refactor in progress

This commit is contained in:
Pravdyvy 2025-12-22 15:52:42 +02:00
parent c7c0414a32
commit 21c3d762f4
11 changed files with 951 additions and 2750 deletions

View File

@ -23,8 +23,9 @@ use wallet::{
account::{AccountSubcommand, NewSubcommand}, account::{AccountSubcommand, NewSubcommand},
config::ConfigSubcommand, config::ConfigSubcommand,
programs::{ programs::{
native_token_transfer::AuthTransferSubcommand, pinata::PinataProgramAgnosticSubcommand, ArgsDefinitionOwned, ArgsHolderMaybeUnowned, ArgsHolderOwned, ArgsReceiverMaybeUnowned,
token::TokenProgramAgnosticSubcommand, ArgsSenderOwned, ArgsSupplyOwned, native_token_transfer::AuthTransferSubcommand,
pinata::PinataProgramAgnosticSubcommand, token::TokenProgramAgnosticSubcommand,
}, },
}, },
config::PersistentStorage, config::PersistentStorage,
@ -49,10 +50,14 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
pub async fn test_success() { pub async fn test_success() {
info!("########## test_success ##########"); info!("########## test_success ##########");
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_public_account_input_from_str(ACC_SENDER), sender: ArgsSenderOwned {
to: Some(make_public_account_input_from_str(ACC_RECEIVER)), from: make_public_account_input_from_str(ACC_SENDER),
to_npk: None, },
to_ipk: None, receiver: ArgsReceiverMaybeUnowned {
to: Some(make_public_account_input_from_str(ACC_RECEIVER)),
to_npk: None,
to_ipk: None,
},
amount: 100, amount: 100,
}); });
@ -115,12 +120,16 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
} }
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_public_account_input_from_str(ACC_SENDER), sender: ArgsSenderOwned {
to: Some(make_public_account_input_from_str( from: make_public_account_input_from_str(ACC_SENDER),
&new_persistent_account_id, },
)), receiver: ArgsReceiverMaybeUnowned {
to_npk: None, to: Some(make_public_account_input_from_str(
to_ipk: None, &new_persistent_account_id,
)),
to_npk: None,
to_ipk: None,
},
amount: 100, amount: 100,
}); });
@ -152,10 +161,14 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
pub async fn test_failure() { pub async fn test_failure() {
info!("########## test_failure ##########"); info!("########## test_failure ##########");
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_public_account_input_from_str(ACC_SENDER), sender: ArgsSenderOwned {
to: Some(make_public_account_input_from_str(ACC_RECEIVER)), from: make_public_account_input_from_str(ACC_SENDER),
to_npk: None, },
to_ipk: None, receiver: ArgsReceiverMaybeUnowned {
to: Some(make_public_account_input_from_str(ACC_RECEIVER)),
to_npk: None,
to_ipk: None,
},
amount: 1000000, amount: 1000000,
}); });
@ -193,10 +206,14 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
pub async fn test_success_two_transactions() { pub async fn test_success_two_transactions() {
info!("########## test_success_two_transactions ##########"); info!("########## test_success_two_transactions ##########");
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_public_account_input_from_str(ACC_SENDER), sender: ArgsSenderOwned {
to: Some(make_public_account_input_from_str(ACC_RECEIVER)), from: make_public_account_input_from_str(ACC_SENDER),
to_npk: None, },
to_ipk: None, receiver: ArgsReceiverMaybeUnowned {
to: Some(make_public_account_input_from_str(ACC_RECEIVER)),
to_npk: None,
to_ipk: None,
},
amount: 100, amount: 100,
}); });
@ -228,10 +245,14 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
info!("First TX Success!"); info!("First TX Success!");
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_public_account_input_from_str(ACC_SENDER), sender: ArgsSenderOwned {
to: Some(make_public_account_input_from_str(ACC_RECEIVER)), from: make_public_account_input_from_str(ACC_SENDER),
to_npk: None, },
to_ipk: None, receiver: ArgsReceiverMaybeUnowned {
to: Some(make_public_account_input_from_str(ACC_RECEIVER)),
to_npk: None,
to_ipk: None,
},
amount: 100, amount: 100,
}); });
@ -282,7 +303,7 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
/// This test creates a new token using the token program. After creating the token, the test /// This test creates a new token using the token program. After creating the token, the test
/// executes a token transfer to a new account. /// executes a token transfer to a new account.
#[nssa_integration_test] //#[nssa_integration_test]
pub async fn test_success_token_program() { pub async fn test_success_token_program() {
info!("########## test_success_token_program ##########"); info!("########## test_success_token_program ##########");
let wallet_config = fetch_config().await.unwrap(); let wallet_config = fetch_config().await.unwrap();
@ -323,10 +344,16 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
// Create new token // Create new token
let subcommand = TokenProgramAgnosticSubcommand::New { let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: make_public_account_input_from_str( definition: ArgsDefinitionOwned {
&definition_account_id.to_string(), definition_account_id: make_public_account_input_from_str(
), &definition_account_id.to_string(),
supply_account_id: make_public_account_input_from_str(&supply_account_id.to_string()), ),
},
supply: ArgsSupplyOwned {
supply_account_id: make_public_account_input_from_str(
&supply_account_id.to_string(),
),
},
name: "A NAME".to_string(), name: "A NAME".to_string(),
total_supply: 37, total_supply: 37,
}; };
@ -383,12 +410,16 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
// Transfer 7 tokens from `supply_acc` to the account at account_id `recipient_account_id` // Transfer 7 tokens from `supply_acc` to the account at account_id `recipient_account_id`
let subcommand = TokenProgramAgnosticSubcommand::Send { let subcommand = TokenProgramAgnosticSubcommand::Send {
from: make_public_account_input_from_str(&supply_account_id.to_string()), from: ArgsSenderOwned {
to: Some(make_public_account_input_from_str( from: make_public_account_input_from_str(&supply_account_id.to_string()),
&recipient_account_id.to_string(), },
)), to: ArgsReceiverMaybeUnowned {
to_npk: None, to: Some(make_public_account_input_from_str(
to_ipk: None, &recipient_account_id.to_string(),
)),
to_npk: None,
to_ipk: None,
},
amount: 7, amount: 7,
}; };
@ -437,8 +468,16 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
// Burn 3 tokens from `recipient_acc` // Burn 3 tokens from `recipient_acc`
let subcommand = TokenProgramAgnosticSubcommand::Burn { let subcommand = TokenProgramAgnosticSubcommand::Burn {
definition: make_public_account_input_from_str(&definition_account_id.to_string()), definition: ArgsDefinitionOwned {
holder: make_public_account_input_from_str(&recipient_account_id.to_string()), definition_account_id: make_public_account_input_from_str(
&definition_account_id.to_string(),
),
},
holder: ArgsHolderOwned {
holder_account_id: make_public_account_input_from_str(
&recipient_account_id.to_string(),
),
},
amount: 3, amount: 3,
}; };
@ -477,12 +516,18 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
// Mint 10 tokens at `recipient_acc` // Mint 10 tokens at `recipient_acc`
let subcommand = TokenProgramAgnosticSubcommand::Mint { let subcommand = TokenProgramAgnosticSubcommand::Mint {
definition: make_public_account_input_from_str(&definition_account_id.to_string()), definition: ArgsDefinitionOwned {
holder: Some(make_public_account_input_from_str( definition_account_id: make_public_account_input_from_str(
&recipient_account_id.to_string(), &definition_account_id.to_string(),
)), ),
holder_npk: None, },
holder_ipk: None, holder: ArgsHolderMaybeUnowned {
holder: Some(make_public_account_input_from_str(
&recipient_account_id.to_string(),
)),
holder_npk: None,
holder_ipk: None,
},
amount: 10, amount: 10,
}; };
@ -523,7 +568,7 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
/// This test creates a new private token using the token program. After creating the token, the /// This test creates a new private token using the token program. After creating the token, the
/// test executes a private token transfer to a new account. All accounts are private owned /// test executes a private token transfer to a new account. All accounts are private owned
/// except definition which is public. /// except definition which is public.
#[nssa_integration_test] //#[nssa_integration_test]
pub async fn test_success_token_program_private_owned_supply() { pub async fn test_success_token_program_private_owned_supply() {
info!("########## test_success_token_program_private_owned_supply ##########"); info!("########## test_success_token_program_private_owned_supply ##########");
let wallet_config = fetch_config().await.unwrap(); let wallet_config = fetch_config().await.unwrap();
@ -564,10 +609,16 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
// Create new token // Create new token
let subcommand = TokenProgramAgnosticSubcommand::New { let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: make_public_account_input_from_str( definition: ArgsDefinitionOwned {
&definition_account_id.to_string(), definition_account_id: make_public_account_input_from_str(
), &definition_account_id.to_string(),
supply_account_id: make_private_account_input_from_str(&supply_account_id.to_string()), ),
},
supply: ArgsSupplyOwned {
supply_account_id: make_private_account_input_from_str(
&supply_account_id.to_string(),
),
},
name: "A NAME".to_string(), name: "A NAME".to_string(),
total_supply: 37, total_supply: 37,
}; };
@ -610,12 +661,16 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
// Transfer 7 tokens from `supply_acc` to the account at account_id `recipient_account_id` // Transfer 7 tokens from `supply_acc` to the account at account_id `recipient_account_id`
let subcommand = TokenProgramAgnosticSubcommand::Send { let subcommand = TokenProgramAgnosticSubcommand::Send {
from: make_private_account_input_from_str(&supply_account_id.to_string()), from: ArgsSenderOwned {
to: Some(make_private_account_input_from_str( from: make_private_account_input_from_str(&supply_account_id.to_string()),
&recipient_account_id.to_string(), },
)), to: ArgsReceiverMaybeUnowned {
to_npk: None, to: Some(make_private_account_input_from_str(
to_ipk: None, &recipient_account_id.to_string(),
)),
to_npk: None,
to_ipk: None,
},
amount: 7, amount: 7,
}; };
@ -644,12 +699,16 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
// Transfer additional 7 tokens from `supply_acc` to the account at account_id // Transfer additional 7 tokens from `supply_acc` to the account at account_id
// `recipient_account_id` // `recipient_account_id`
let subcommand = TokenProgramAgnosticSubcommand::Send { let subcommand = TokenProgramAgnosticSubcommand::Send {
from: make_private_account_input_from_str(&supply_account_id.to_string()), from: ArgsSenderOwned {
to: Some(make_private_account_input_from_str( from: make_private_account_input_from_str(&supply_account_id.to_string()),
&recipient_account_id.to_string(), },
)), to: ArgsReceiverMaybeUnowned {
to_npk: None, to: Some(make_private_account_input_from_str(
to_ipk: None, &recipient_account_id.to_string(),
)),
to_npk: None,
to_ipk: None,
},
amount: 7, amount: 7,
}; };
@ -677,8 +736,16 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
// Burn 3 tokens from `recipient_acc` // Burn 3 tokens from `recipient_acc`
let subcommand = TokenProgramAgnosticSubcommand::Burn { let subcommand = TokenProgramAgnosticSubcommand::Burn {
definition: make_public_account_input_from_str(&definition_account_id.to_string()), definition: ArgsDefinitionOwned {
holder: make_private_account_input_from_str(&recipient_account_id.to_string()), definition_account_id: make_public_account_input_from_str(
&definition_account_id.to_string(),
),
},
holder: ArgsHolderOwned {
holder_account_id: make_private_account_input_from_str(
&recipient_account_id.to_string(),
),
},
amount: 3, amount: 3,
}; };
@ -725,12 +792,18 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
// Mint 10 tokens at `recipient_acc` // Mint 10 tokens at `recipient_acc`
let subcommand = TokenProgramAgnosticSubcommand::Mint { let subcommand = TokenProgramAgnosticSubcommand::Mint {
definition: make_public_account_input_from_str(&definition_account_id.to_string()), definition: ArgsDefinitionOwned {
holder: Some(make_private_account_input_from_str( definition_account_id: make_public_account_input_from_str(
&recipient_account_id.to_string(), &definition_account_id.to_string(),
)), ),
holder_npk: None, },
holder_ipk: None, holder: ArgsHolderMaybeUnowned {
holder: Some(make_private_account_input_from_str(
&recipient_account_id.to_string(),
)),
holder_npk: None,
holder_ipk: None,
},
amount: 10, amount: 10,
}; };
@ -802,12 +875,18 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
// Mint 9 tokens at `recipient_acc2` // Mint 9 tokens at `recipient_acc2`
let subcommand = TokenProgramAgnosticSubcommand::Mint { let subcommand = TokenProgramAgnosticSubcommand::Mint {
definition: make_public_account_input_from_str(&definition_account_id.to_string()), definition: ArgsDefinitionOwned {
holder: None, definition_account_id: make_public_account_input_from_str(
holder_npk: Some(hex::encode(holder_keys.nullifer_public_key.0)), &definition_account_id.to_string(),
holder_ipk: Some(hex::encode( ),
holder_keys.incoming_viewing_public_key.0.clone(), },
)), holder: ArgsHolderMaybeUnowned {
holder: None,
holder_npk: Some(hex::encode(holder_keys.nullifer_public_key.0)),
holder_ipk: Some(hex::encode(
holder_keys.incoming_viewing_public_key.0.clone(),
)),
},
amount: 9, amount: 9,
}; };
@ -860,7 +939,7 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
/// This test creates a new private token using the token program. All accounts are private /// This test creates a new private token using the token program. All accounts are private
/// owned except supply which is public. /// owned except supply which is public.
#[nssa_integration_test] //#[nssa_integration_test]
pub async fn test_success_token_program_private_owned_definition() { pub async fn test_success_token_program_private_owned_definition() {
info!("########## test_success_token_program_private_owned_definition ##########"); info!("########## test_success_token_program_private_owned_definition ##########");
let wallet_config = fetch_config().await.unwrap(); let wallet_config = fetch_config().await.unwrap();
@ -1214,7 +1293,7 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
/// This test creates a new private token using the token program. All accounts are private /// This test creates a new private token using the token program. All accounts are private
/// owned. /// owned.
#[nssa_integration_test] //#[nssa_integration_test]
pub async fn test_success_token_program_private_owned_definition_and_supply() { pub async fn test_success_token_program_private_owned_definition_and_supply() {
info!( info!(
"########## test_success_token_program_private_owned_definition_and_supply ##########" "########## test_success_token_program_private_owned_definition_and_supply ##########"
@ -1314,7 +1393,7 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
/// This test creates a new private token using the token program. After creating the token, the /// This test creates a new private token using the token program. After creating the token, the
/// test executes a private token transfer to a new account. /// test executes a private token transfer to a new account.
#[nssa_integration_test] //#[nssa_integration_test]
pub async fn test_success_token_program_private_claiming_path() { pub async fn test_success_token_program_private_claiming_path() {
info!("########## test_success_token_program_private_claiming_path ##########"); info!("########## test_success_token_program_private_claiming_path ##########");
let wallet_config = fetch_config().await.unwrap(); let wallet_config = fetch_config().await.unwrap();
@ -1450,7 +1529,7 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
/// This test creates a new public token using the token program. After creating the token, the /// This test creates a new public token using the token program. After creating the token, the
/// test executes a shielded token transfer to a new account. All accounts are owned except /// test executes a shielded token transfer to a new account. All accounts are owned except
/// definition. /// definition.
#[nssa_integration_test] //#[nssa_integration_test]
pub async fn test_success_token_program_shielded_owned() { pub async fn test_success_token_program_shielded_owned() {
info!("########## test_success_token_program_shielded_owned ##########"); info!("########## test_success_token_program_shielded_owned ##########");
let wallet_config = fetch_config().await.unwrap(); let wallet_config = fetch_config().await.unwrap();
@ -1586,7 +1665,7 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
/// This test creates a new private token using the token program. After creating the token, the /// This test creates a new private token using the token program. After creating the token, the
/// test executes a deshielded token transfer to a new account. All accounts are owned /// test executes a deshielded token transfer to a new account. All accounts are owned
/// except definition. /// except definition.
#[nssa_integration_test] //#[nssa_integration_test]
pub async fn test_success_token_program_deshielded_owned() { pub async fn test_success_token_program_deshielded_owned() {
info!("########## test_success_token_program_deshielded_owned ##########"); info!("########## test_success_token_program_deshielded_owned ##########");
let wallet_config = fetch_config().await.unwrap(); let wallet_config = fetch_config().await.unwrap();
@ -1736,10 +1815,14 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
let to: AccountId = ACC_RECEIVER_PRIVATE.parse().unwrap(); let to: AccountId = ACC_RECEIVER_PRIVATE.parse().unwrap();
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_private_account_input_from_str(&from.to_string()), sender: ArgsSenderOwned {
to: Some(make_private_account_input_from_str(&to.to_string())), from: make_private_account_input_from_str(&from.to_string()),
to_npk: None, },
to_ipk: None, receiver: ArgsReceiverMaybeUnowned {
to: Some(make_private_account_input_from_str(&to.to_string())),
to_npk: None,
to_ipk: None,
},
amount: 100, amount: 100,
}); });
@ -1774,10 +1857,14 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
let to_ipk = Secp256k1Point::from_scalar(to_npk.0); let to_ipk = Secp256k1Point::from_scalar(to_npk.0);
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_private_account_input_from_str(&from.to_string()), sender: ArgsSenderOwned {
to: None, from: make_private_account_input_from_str(&from.to_string()),
to_npk: Some(to_npk_string), },
to_ipk: Some(hex::encode(to_ipk.0)), receiver: ArgsReceiverMaybeUnowned {
to: None,
to_npk: Some(to_npk_string),
to_ipk: Some(hex::encode(to_ipk.0)),
},
amount: 100, amount: 100,
}); });
@ -1843,10 +1930,14 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
.unwrap(); .unwrap();
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_private_account_input_from_str(&from.to_string()), sender: ArgsSenderOwned {
to: None, from: make_private_account_input_from_str(&from.to_string()),
to_npk: Some(hex::encode(to_keys.nullifer_public_key.0)), },
to_ipk: Some(hex::encode(to_keys.incoming_viewing_public_key.0)), receiver: ArgsReceiverMaybeUnowned {
to: None,
to_npk: Some(hex::encode(to_keys.nullifer_public_key.0)),
to_ipk: Some(hex::encode(to_keys.incoming_viewing_public_key.0)),
},
amount: 100, amount: 100,
}); });
@ -1956,10 +2047,14 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
let to: AccountId = ACC_RECEIVER.parse().unwrap(); let to: AccountId = ACC_RECEIVER.parse().unwrap();
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_private_account_input_from_str(&from.to_string()), sender: ArgsSenderOwned {
to: Some(make_public_account_input_from_str(&to.to_string())), from: make_private_account_input_from_str(&from.to_string()),
to_npk: None, },
to_ipk: None, receiver: ArgsReceiverMaybeUnowned {
to: Some(make_public_account_input_from_str(&to.to_string())),
to_npk: None,
to_ipk: None,
},
amount: 100, amount: 100,
}); });
@ -2005,10 +2100,14 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
let to: AccountId = ACC_RECEIVER_PRIVATE.parse().unwrap(); let to: AccountId = ACC_RECEIVER_PRIVATE.parse().unwrap();
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_public_account_input_from_str(&from.to_string()), sender: ArgsSenderOwned {
to: Some(make_private_account_input_from_str(&to.to_string())), from: make_public_account_input_from_str(&from.to_string()),
to_npk: None, },
to_ipk: None, receiver: ArgsReceiverMaybeUnowned {
to: Some(make_private_account_input_from_str(&to.to_string())),
to_npk: None,
to_ipk: None,
},
amount: 100, amount: 100,
}); });
@ -2049,10 +2148,14 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
let from: AccountId = ACC_SENDER.parse().unwrap(); let from: AccountId = ACC_SENDER.parse().unwrap();
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_public_account_input_from_str(&from.to_string()), sender: ArgsSenderOwned {
to: None, from: make_public_account_input_from_str(&from.to_string()),
to_npk: Some(to_npk_string), },
to_ipk: Some(hex::encode(to_ipk.0)), receiver: ArgsReceiverMaybeUnowned {
to: None,
to_npk: Some(to_npk_string),
to_ipk: Some(hex::encode(to_ipk.0)),
},
amount: 100, amount: 100,
}); });
@ -2437,24 +2540,32 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
}; };
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_private_account_input_from_str(&from.to_string()), sender: ArgsSenderOwned {
to: Some(make_private_account_input_from_str( from: make_private_account_input_from_str(&from.to_string()),
&to_account_id1.to_string(), },
)), receiver: ArgsReceiverMaybeUnowned {
to_npk: None, to: Some(make_private_account_input_from_str(
to_ipk: None, &to_account_id1.to_string(),
)),
to_npk: None,
to_ipk: None,
},
amount: 100, amount: 100,
}); });
wallet::cli::execute_subcommand(command).await.unwrap(); wallet::cli::execute_subcommand(command).await.unwrap();
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_private_account_input_from_str(&from.to_string()), sender: ArgsSenderOwned {
to: Some(make_private_account_input_from_str( from: make_private_account_input_from_str(&from.to_string()),
&to_account_id2.to_string(), },
)), receiver: ArgsReceiverMaybeUnowned {
to_npk: None, to: Some(make_private_account_input_from_str(
to_ipk: None, &to_account_id2.to_string(),
)),
to_npk: None,
to_ipk: None,
},
amount: 101, amount: 101,
}); });
@ -2487,24 +2598,32 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
}; };
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_public_account_input_from_str(&from.to_string()), sender: ArgsSenderOwned {
to: Some(make_public_account_input_from_str( from: make_public_account_input_from_str(&from.to_string()),
&to_account_id3.to_string(), },
)), receiver: ArgsReceiverMaybeUnowned {
to_npk: None, to: Some(make_public_account_input_from_str(
to_ipk: None, &to_account_id3.to_string(),
)),
to_npk: None,
to_ipk: None,
},
amount: 102, amount: 102,
}); });
wallet::cli::execute_subcommand(command).await.unwrap(); wallet::cli::execute_subcommand(command).await.unwrap();
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_public_account_input_from_str(&from.to_string()), sender: ArgsSenderOwned {
to: Some(make_public_account_input_from_str( from: make_public_account_input_from_str(&from.to_string()),
&to_account_id4.to_string(), },
)), receiver: ArgsReceiverMaybeUnowned {
to_npk: None, to: Some(make_public_account_input_from_str(
to_ipk: None, &to_account_id4.to_string(),
)),
to_npk: None,
to_ipk: None,
},
amount: 103, amount: 103,
}); });
@ -2564,24 +2683,32 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
info!("########## TREE CHECKS END ##########"); info!("########## TREE CHECKS END ##########");
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_private_account_input_from_str(&to_account_id1.to_string()), sender: ArgsSenderOwned {
to: Some(make_private_account_input_from_str( from: make_private_account_input_from_str(&to_account_id1.to_string()),
&to_account_id2.to_string(), },
)), receiver: ArgsReceiverMaybeUnowned {
to_npk: None, to: Some(make_private_account_input_from_str(
to_ipk: None, &to_account_id2.to_string(),
)),
to_npk: None,
to_ipk: None,
},
amount: 10, amount: 10,
}); });
wallet::cli::execute_subcommand(command).await.unwrap(); wallet::cli::execute_subcommand(command).await.unwrap();
let command = Command::AuthTransfer(AuthTransferSubcommand::Send { let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: make_public_account_input_from_str(&to_account_id3.to_string()), sender: ArgsSenderOwned {
to: Some(make_public_account_input_from_str( from: make_public_account_input_from_str(&to_account_id3.to_string()),
&to_account_id4.to_string(), },
)), receiver: ArgsReceiverMaybeUnowned {
to_npk: None, to: Some(make_public_account_input_from_str(
to_ipk: None, &to_account_id4.to_string(),
)),
to_npk: None,
to_ipk: None,
},
amount: 11, amount: 11,
}); });

View File

@ -4,33 +4,194 @@ pub mod token;
use anyhow::Result; use anyhow::Result;
use clap::Args; use clap::Args;
use nssa::AccountId;
use crate::helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix}; use crate::{
PrivacyPreservingAccount,
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
};
#[derive(Debug, Args)] trait ParsePrivacyPreservingAccount {
struct ArgsSenderOwned { fn parse(&self) -> Result<PrivacyPreservingAccount>;
/// from - valid 32 byte base58 string with privacy prefix
#[arg(long)]
from: String,
} }
impl ArgsSenderOwned { #[derive(Debug, Args, Clone)]
pub fn parse_acc_and_privacy(self) -> Result<(AccountId, AccountPrivacyKind)> { pub struct ArgsSenderOwned {
let (acc_id_raw, privacy) = parse_addr_with_privacy_prefix(&self.from)?; /// from - valid 32 byte base58 string with privacy prefix
Ok((acc_id_raw.parse()?, privacy)) #[arg(long)]
pub from: String,
}
impl ParsePrivacyPreservingAccount for ArgsSenderOwned {
fn parse(&self) -> Result<PrivacyPreservingAccount> {
let (account_id, privacy) = parse_addr_with_privacy_prefix(&self.from)?;
match privacy {
AccountPrivacyKind::Public => Ok(PrivacyPreservingAccount::Public(account_id.parse()?)),
AccountPrivacyKind::Private => {
Ok(PrivacyPreservingAccount::PrivateOwned(account_id.parse()?))
}
}
} }
} }
#[derive(Debug, Args)] #[derive(Debug, Args, Clone)]
struct ArgsReceiverVariableOwnership { pub struct ArgsReceiverMaybeUnowned {
/// to - valid 32 byte base58 string with privacy prefix /// to - valid 32 byte base58 string with privacy prefix
#[arg(long)] #[arg(long)]
to: Option<String>, pub to: Option<String>,
/// to_npk - valid 32 byte hex string /// to_npk - valid 32 byte hex string
#[arg(long)] #[arg(long)]
to_npk: Option<String>, pub to_npk: Option<String>,
/// to_ipk - valid 33 byte hex string /// to_ipk - valid 33 byte hex string
#[arg(long)] #[arg(long)]
to_ipk: Option<String>, pub to_ipk: Option<String>,
}
impl ParsePrivacyPreservingAccount for ArgsReceiverMaybeUnowned {
fn parse(&self) -> Result<PrivacyPreservingAccount> {
match (&self.to, &self.to_npk, &self.to_ipk) {
(None, None, None) => {
anyhow::bail!("Provide either account account_id of receiver or their public keys");
}
(Some(_), Some(_), Some(_)) => {
anyhow::bail!(
"Provide only one variant: either account account_id of receiver or their public keys"
);
}
(_, Some(_), None) | (_, None, Some(_)) => {
anyhow::bail!("List of public keys is uncomplete");
}
(Some(to), None, None) => ArgsSenderOwned { from: to.clone() }.parse(),
(None, Some(to_npk), Some(to_ipk)) => {
let to_npk_res = hex::decode(to_npk)?;
let mut to_npk = [0; 32];
to_npk.copy_from_slice(&to_npk_res);
let to_npk = nssa_core::NullifierPublicKey(to_npk);
let to_ipk_res = hex::decode(to_ipk)?;
let mut to_ipk = [0u8; 33];
to_ipk.copy_from_slice(&to_ipk_res);
let to_ipk =
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_ipk.to_vec());
Ok(PrivacyPreservingAccount::PrivateForeign {
npk: to_npk,
ipk: to_ipk,
})
}
}
}
}
#[derive(Debug, Args, Clone)]
pub struct ArgsDefinitionOwned {
/// definition_account_id - valid 32 byte base58 string with privacy prefix
#[arg(long)]
pub definition_account_id: String,
}
impl ParsePrivacyPreservingAccount for ArgsDefinitionOwned {
fn parse(&self) -> Result<PrivacyPreservingAccount> {
let (account_id, privacy) = parse_addr_with_privacy_prefix(&self.definition_account_id)?;
match privacy {
AccountPrivacyKind::Public => Ok(PrivacyPreservingAccount::Public(account_id.parse()?)),
AccountPrivacyKind::Private => {
Ok(PrivacyPreservingAccount::PrivateOwned(account_id.parse()?))
}
}
}
}
#[derive(Debug, Args, Clone)]
pub struct ArgsSupplyOwned {
/// supply_account_id - valid 32 byte base58 string with privacy prefix
#[arg(long)]
pub supply_account_id: String,
}
impl ParsePrivacyPreservingAccount for ArgsSupplyOwned {
fn parse(&self) -> Result<PrivacyPreservingAccount> {
let (account_id, privacy) = parse_addr_with_privacy_prefix(&self.supply_account_id)?;
match privacy {
AccountPrivacyKind::Public => Ok(PrivacyPreservingAccount::Public(account_id.parse()?)),
AccountPrivacyKind::Private => {
Ok(PrivacyPreservingAccount::PrivateOwned(account_id.parse()?))
}
}
}
}
#[derive(Debug, Args, Clone)]
pub struct ArgsHolderOwned {
/// holder_account_id - valid 32 byte base58 string with privacy prefix
#[arg(long)]
pub holder_account_id: String,
}
impl ParsePrivacyPreservingAccount for ArgsHolderOwned {
fn parse(&self) -> Result<PrivacyPreservingAccount> {
let (account_id, privacy) = parse_addr_with_privacy_prefix(&self.holder_account_id)?;
match privacy {
AccountPrivacyKind::Public => Ok(PrivacyPreservingAccount::Public(account_id.parse()?)),
AccountPrivacyKind::Private => {
Ok(PrivacyPreservingAccount::PrivateOwned(account_id.parse()?))
}
}
}
}
#[derive(Debug, Args, Clone)]
pub struct ArgsHolderMaybeUnowned {
/// holder - valid 32 byte base58 string with privacy prefix
#[arg(long)]
pub holder: Option<String>,
/// holder_npk - valid 32 byte hex string
#[arg(long)]
pub holder_npk: Option<String>,
/// holder_ipk - valid 33 byte hex string
#[arg(long)]
pub holder_ipk: Option<String>,
}
impl ParsePrivacyPreservingAccount for ArgsHolderMaybeUnowned {
fn parse(&self) -> Result<PrivacyPreservingAccount> {
match (&self.holder, &self.holder_npk, &self.holder_ipk) {
(None, None, None) => {
anyhow::bail!("Provide either account account_id of receiver or their public keys");
}
(Some(_), Some(_), Some(_)) => {
anyhow::bail!(
"Provide only one variant: either account account_id of receiver or their public keys"
);
}
(_, Some(_), None) | (_, None, Some(_)) => {
anyhow::bail!("List of public keys is uncomplete");
}
(Some(holder), None, None) => ArgsSenderOwned {
from: holder.clone(),
}
.parse(),
(None, Some(holder_npk), Some(holder_ipk)) => {
let holder_npk_res = hex::decode(holder_npk)?;
let mut holder_npk = [0; 32];
holder_npk.copy_from_slice(&holder_npk_res);
let holder_npk = nssa_core::NullifierPublicKey(holder_npk);
let holder_ipk_res = hex::decode(holder_ipk)?;
let mut holder_ipk = [0u8; 33];
holder_ipk.copy_from_slice(&holder_ipk_res);
let holder_ipk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
holder_ipk.to_vec(),
);
Ok(PrivacyPreservingAccount::PrivateForeign {
npk: holder_npk,
ipk: holder_ipk,
})
}
}
}
} }

View File

@ -4,11 +4,16 @@ use common::transaction::NSSATransaction;
use nssa::AccountId; use nssa::AccountId;
use crate::{ use crate::{
AccDecodeData::Decode, PrivacyPreservingAccount, WalletCore,
WalletCore, cli::{
cli::{SubcommandReturnValue, WalletSubcommand}, SubcommandReturnValue, WalletSubcommand,
programs::{ArgsReceiverMaybeUnowned, ArgsSenderOwned, ParsePrivacyPreservingAccount},
},
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix}, helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
program_facades::native_token_transfer::NativeTokenTransfer, program_facades::{
native_token_transfer::{InitArgs, NativeBalanceToMove, NativeTokenTransfer},
send_privacy_preserving_transaction_unified,
},
}; };
/// 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
@ -27,18 +32,10 @@ pub enum AuthTransferSubcommand {
/// ///
/// First is used for owned accounts, second otherwise. /// First is used for owned accounts, second otherwise.
Send { Send {
/// from - valid 32 byte base58 string with privacy prefix #[command(flatten)]
#[arg(long)] sender: ArgsSenderOwned,
from: String, #[command(flatten)]
/// to - valid 32 byte base58 string with privacy prefix receiver: ArgsReceiverMaybeUnowned,
#[arg(long)]
to: Option<String>,
/// to_npk - valid 32 byte hex string
#[arg(long)]
to_npk: Option<String>,
/// to_ipk - valid 33 byte hex string
#[arg(long)]
to_ipk: Option<String>,
/// amount - amount of balance to move /// amount - amount of balance to move
#[arg(long)] #[arg(long)]
amount: u128, amount: u128,
@ -74,11 +71,16 @@ impl WalletSubcommand for AuthTransferSubcommand {
println!("Stored persistent accounts at {path:#?}"); println!("Stored persistent accounts at {path:#?}");
} }
AccountPrivacyKind::Private => { AccountPrivacyKind::Private => {
let account_id = account_id.parse()?; let mut account_ids = vec![];
let account_id: AccountId = account_id.parse()?;
account_ids.push(PrivacyPreservingAccount::PrivateOwned(account_id));
let (res, secret) = NativeTokenTransfer(wallet_core) let (res, acc_decode_data) = send_privacy_preserving_transaction_unified(
.register_account_private(account_id) wallet_core,
.await?; account_ids,
InitArgs {},
)
.await?;
println!("Results of tx send are {res:#?}"); println!("Results of tx send are {res:#?}");
@ -88,8 +90,6 @@ impl WalletSubcommand for AuthTransferSubcommand {
.await?; .await?;
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx { if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let acc_decode_data = vec![Decode(secret, account_id)];
wallet_core.decode_insert_privacy_preserving_transaction_results( wallet_core.decode_insert_privacy_preserving_transaction_results(
tx, tx,
&acc_decode_data, &acc_decode_data,
@ -105,422 +105,68 @@ impl WalletSubcommand for AuthTransferSubcommand {
Ok(SubcommandReturnValue::Empty) Ok(SubcommandReturnValue::Empty)
} }
AuthTransferSubcommand::Send { AuthTransferSubcommand::Send {
from, sender,
to, receiver,
to_npk,
to_ipk,
amount, amount,
} => { } => {
let underlying_subcommand = match (to, to_npk, to_ipk) { let from = sender.parse()?;
(None, None, None) => { let to = receiver.parse()?;
anyhow::bail!(
"Provide either account account_id of receiver or their public keys"
);
}
(Some(_), Some(_), Some(_)) => {
anyhow::bail!(
"Provide only one variant: either account account_id of receiver or their public keys"
);
}
(_, Some(_), None) | (_, None, Some(_)) => {
anyhow::bail!("List of public keys is uncomplete");
}
(Some(to), None, None) => {
let (from, from_privacy) = parse_addr_with_privacy_prefix(&from)?;
let (to, to_privacy) = parse_addr_with_privacy_prefix(&to)?;
match (from_privacy, to_privacy) { if from.is_private() || to.is_private() {
(AccountPrivacyKind::Public, AccountPrivacyKind::Public) => { let mut acc_vector = vec![];
NativeTokenTransferProgramSubcommand::Public { from, to, amount } acc_vector.push(from);
} acc_vector.push(to);
(AccountPrivacyKind::Private, AccountPrivacyKind::Private) => {
NativeTokenTransferProgramSubcommand::Private(
NativeTokenTransferProgramSubcommandPrivate::PrivateOwned {
from,
to,
amount,
},
)
}
(AccountPrivacyKind::Private, AccountPrivacyKind::Public) => {
NativeTokenTransferProgramSubcommand::Deshielded {
from,
to,
amount,
}
}
(AccountPrivacyKind::Public, AccountPrivacyKind::Private) => {
NativeTokenTransferProgramSubcommand::Shielded(
NativeTokenTransferProgramSubcommandShielded::ShieldedOwned {
from,
to,
amount,
},
)
}
}
}
(None, Some(to_npk), Some(to_ipk)) => {
let (from, from_privacy) = parse_addr_with_privacy_prefix(&from)?;
match from_privacy { let (res, acc_decode_data) = send_privacy_preserving_transaction_unified(
AccountPrivacyKind::Private => { wallet_core,
NativeTokenTransferProgramSubcommand::Private( acc_vector,
NativeTokenTransferProgramSubcommandPrivate::PrivateForeign { NativeBalanceToMove {
from, balance_to_move: amount,
to_npk, },
to_ipk, )
amount, .await?;
},
)
}
AccountPrivacyKind::Public => {
NativeTokenTransferProgramSubcommand::Shielded(
NativeTokenTransferProgramSubcommandShielded::ShieldedForeign {
from,
to_npk,
to_ipk,
amount,
},
)
}
}
}
};
underlying_subcommand.handle_subcommand(wallet_core).await println!("Results of tx send are {res:#?}");
}
} let tx_hash = res.tx_hash;
} let transfer_tx = wallet_core
} .poll_native_token_transfer(tx_hash.clone())
.await?;
/// Represents generic CLI subcommand for a wallet working with native token transfer program
#[derive(Subcommand, Debug, Clone)] if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
pub enum NativeTokenTransferProgramSubcommand { wallet_core.decode_insert_privacy_preserving_transaction_results(
/// Send native token transfer from `from` to `to` for `amount` tx,
/// &acc_decode_data,
/// Public operation )?;
Public { }
/// from - valid 32 byte hex string
#[arg(long)] let path = wallet_core.store_persistent_data().await?;
from: String,
/// to - valid 32 byte hex string println!("Stored persistent accounts at {path:#?}");
#[arg(long)]
to: String, Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
/// amount - amount of balance to move } else {
#[arg(long)] let from = from
amount: u128, .account_id()
}, .expect("Public account can not be unowned");
/// Private execution let to = to.account_id().expect("Public account can not be unowned");
#[command(subcommand)]
Private(NativeTokenTransferProgramSubcommandPrivate), let res = NativeTokenTransfer(wallet_core)
/// Send native token transfer from `from` to `to` for `amount` .send_public_transfer(from, to, amount)
/// .await?;
/// Deshielded operation
Deshielded { println!("Results of tx send are {res:#?}");
/// from - valid 32 byte hex string
#[arg(long)] let transfer_tx = wallet_core.poll_native_token_transfer(res.tx_hash).await?;
from: String,
/// to - valid 32 byte hex string println!("Transaction data is {transfer_tx:?}");
#[arg(long)]
to: String, let path = wallet_core.store_persistent_data().await?;
/// amount - amount of balance to move
#[arg(long)] println!("Stored persistent accounts at {path:#?}");
amount: u128,
}, Ok(SubcommandReturnValue::Empty)
/// Shielded execution }
#[command(subcommand)]
Shielded(NativeTokenTransferProgramSubcommandShielded),
}
/// Represents generic shielded CLI subcommand for a wallet working with native token transfer
/// program
#[derive(Subcommand, Debug, Clone)]
pub enum NativeTokenTransferProgramSubcommandShielded {
/// Send native token transfer from `from` to `to` for `amount`
///
/// Shielded operation
ShieldedOwned {
/// from - valid 32 byte hex string
#[arg(long)]
from: String,
/// to - valid 32 byte hex string
#[arg(long)]
to: String,
/// amount - amount of balance to move
#[arg(long)]
amount: u128,
},
/// Send native token transfer from `from` to `to` for `amount`
///
/// Shielded operation
ShieldedForeign {
/// from - valid 32 byte hex string
#[arg(long)]
from: String,
/// to_npk - valid 32 byte hex string
#[arg(long)]
to_npk: String,
/// to_ipk - valid 33 byte hex string
#[arg(long)]
to_ipk: String,
/// amount - amount of balance to move
#[arg(long)]
amount: u128,
},
}
/// Represents generic private CLI subcommand for a wallet working with native token transfer
/// program
#[derive(Subcommand, Debug, Clone)]
pub enum NativeTokenTransferProgramSubcommandPrivate {
/// Send native token transfer from `from` to `to` for `amount`
///
/// Private operation
PrivateOwned {
/// from - valid 32 byte hex string
#[arg(long)]
from: String,
/// to - valid 32 byte hex string
#[arg(long)]
to: String,
/// amount - amount of balance to move
#[arg(long)]
amount: u128,
},
/// Send native token transfer from `from` to `to` for `amount`
///
/// Private operation
PrivateForeign {
/// from - valid 32 byte hex string
#[arg(long)]
from: String,
/// to_npk - valid 32 byte hex string
#[arg(long)]
to_npk: String,
/// to_ipk - valid 33 byte hex string
#[arg(long)]
to_ipk: String,
/// amount - amount of balance to move
#[arg(long)]
amount: u128,
},
}
impl WalletSubcommand for NativeTokenTransferProgramSubcommandPrivate {
async fn handle_subcommand(
self,
wallet_core: &mut WalletCore,
) -> Result<SubcommandReturnValue> {
match self {
NativeTokenTransferProgramSubcommandPrivate::PrivateOwned { from, to, amount } => {
let from: AccountId = from.parse().unwrap();
let to: AccountId = to.parse().unwrap();
let (res, acc_decode_data) = NativeTokenTransfer(wallet_core)
.send_private_transfer_to_owned_account_gen(from, to, amount)
.await?;
println!("Results of tx send are {res:#?}");
let tx_hash = res.tx_hash;
let transfer_tx = wallet_core
.poll_native_token_transfer(tx_hash.clone())
.await?;
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
wallet_core.decode_insert_privacy_preserving_transaction_results(
tx,
&acc_decode_data,
)?;
}
let path = wallet_core.store_persistent_data().await?;
println!("Stored persistent accounts at {path:#?}");
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
NativeTokenTransferProgramSubcommandPrivate::PrivateForeign {
from,
to_npk,
to_ipk,
amount,
} => {
let from: AccountId = from.parse().unwrap();
let to_npk_res = hex::decode(to_npk)?;
let mut to_npk = [0; 32];
to_npk.copy_from_slice(&to_npk_res);
let to_npk = nssa_core::NullifierPublicKey(to_npk);
let to_ipk_res = hex::decode(to_ipk)?;
let mut to_ipk = [0u8; 33];
to_ipk.copy_from_slice(&to_ipk_res);
let to_ipk =
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_ipk.to_vec());
let (res, acc_decode_data) = NativeTokenTransfer(wallet_core)
.send_private_transfer_to_outer_account_gen(from, to_npk, to_ipk, amount)
.await?;
println!("Results of tx send are {res:#?}");
let tx_hash = res.tx_hash;
let transfer_tx = wallet_core
.poll_native_token_transfer(tx_hash.clone())
.await?;
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
wallet_core.decode_insert_privacy_preserving_transaction_results(
tx,
&acc_decode_data,
)?;
}
let path = wallet_core.store_persistent_data().await?;
println!("Stored persistent accounts at {path:#?}");
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
}
}
}
impl WalletSubcommand for NativeTokenTransferProgramSubcommandShielded {
async fn handle_subcommand(
self,
wallet_core: &mut WalletCore,
) -> Result<SubcommandReturnValue> {
match self {
NativeTokenTransferProgramSubcommandShielded::ShieldedOwned { from, to, amount } => {
let from: AccountId = from.parse().unwrap();
let to: AccountId = to.parse().unwrap();
let (res, secret) = NativeTokenTransfer(wallet_core)
.send_shielded_transfer(from, to, amount)
.await?;
println!("Results of tx send are {res:#?}");
let tx_hash = res.tx_hash;
let transfer_tx = wallet_core
.poll_native_token_transfer(tx_hash.clone())
.await?;
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let acc_decode_data = vec![Decode(secret, to)];
wallet_core.decode_insert_privacy_preserving_transaction_results(
tx,
&acc_decode_data,
)?;
}
let path = wallet_core.store_persistent_data().await?;
println!("Stored persistent accounts at {path:#?}");
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
NativeTokenTransferProgramSubcommandShielded::ShieldedForeign {
from,
to_npk,
to_ipk,
amount,
} => {
let from: AccountId = from.parse().unwrap();
let to_npk_res = hex::decode(to_npk)?;
let mut to_npk = [0; 32];
to_npk.copy_from_slice(&to_npk_res);
let to_npk = nssa_core::NullifierPublicKey(to_npk);
let to_ipk_res = hex::decode(to_ipk)?;
let mut to_ipk = [0u8; 33];
to_ipk.copy_from_slice(&to_ipk_res);
let to_ipk =
nssa_core::encryption::shared_key_derivation::Secp256k1Point(to_ipk.to_vec());
let (res, _) = NativeTokenTransfer(wallet_core)
.send_shielded_transfer_to_outer_account(from, to_npk, to_ipk, amount)
.await?;
println!("Results of tx send are {res:#?}");
let tx_hash = res.tx_hash;
let path = wallet_core.store_persistent_data().await?;
println!("Stored persistent accounts at {path:#?}");
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
}
}
}
impl WalletSubcommand for NativeTokenTransferProgramSubcommand {
async fn handle_subcommand(
self,
wallet_core: &mut WalletCore,
) -> Result<SubcommandReturnValue> {
match self {
NativeTokenTransferProgramSubcommand::Private(private_subcommand) => {
private_subcommand.handle_subcommand(wallet_core).await
}
NativeTokenTransferProgramSubcommand::Shielded(shielded_subcommand) => {
shielded_subcommand.handle_subcommand(wallet_core).await
}
NativeTokenTransferProgramSubcommand::Deshielded { from, to, amount } => {
let from: AccountId = from.parse().unwrap();
let to: AccountId = to.parse().unwrap();
let (res, secret) = NativeTokenTransfer(wallet_core)
.send_deshielded_transfer(from, to, amount)
.await?;
println!("Results of tx send are {res:#?}");
let tx_hash = res.tx_hash;
let transfer_tx = wallet_core
.poll_native_token_transfer(tx_hash.clone())
.await?;
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let acc_decode_data = vec![Decode(secret, from)];
wallet_core.decode_insert_privacy_preserving_transaction_results(
tx,
&acc_decode_data,
)?;
}
let path = wallet_core.store_persistent_data().await?;
println!("Stored persistent accounts at {path:#?}");
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
NativeTokenTransferProgramSubcommand::Public { from, to, amount } => {
let from: AccountId = from.parse().unwrap();
let to: AccountId = to.parse().unwrap();
let res = NativeTokenTransfer(wallet_core)
.send_public_transfer(from, to, amount)
.await?;
println!("Results of tx send are {res:#?}");
let transfer_tx = wallet_core.poll_native_token_transfer(res.tx_hash).await?;
println!("Transaction data is {transfer_tx:?}");
let path = wallet_core.store_persistent_data().await?;
println!("Stored persistent accounts at {path:#?}");
Ok(SubcommandReturnValue::Empty)
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ use nssa_core::{
encryption::{EphemeralPublicKey, IncomingViewingPublicKey}, encryption::{EphemeralPublicKey, IncomingViewingPublicKey},
}; };
use crate::WalletCore; use crate::{WalletCore, helperfunctions::AccountPrivacyKind};
#[derive(Clone)] #[derive(Clone)]
pub enum PrivacyPreservingAccount { pub enum PrivacyPreservingAccount {
@ -33,6 +33,20 @@ impl PrivacyPreservingAccount {
&Self::PrivateOwned(_) | &Self::PrivateForeign { npk: _, ipk: _ } &Self::PrivateOwned(_) | &Self::PrivateForeign { npk: _, ipk: _ }
) )
} }
pub fn prepare_authorized_account(account_id: AccountId, privacy: AccountPrivacyKind) -> Self {
match privacy {
AccountPrivacyKind::Private => Self::PrivateOwned(account_id),
AccountPrivacyKind::Public => Self::Public(account_id),
}
}
pub fn account_id(&self) -> Option<AccountId> {
match &self {
Self::Public(account_id) | Self::PrivateOwned(account_id) => Some(*account_id),
_ => None,
}
}
} }
pub struct PrivateAccountKeys { pub struct PrivateAccountKeys {

View File

@ -1,6 +1,62 @@
//! This module contains [`WalletCore`](crate::WalletCore) facades for interacting with various //! This module contains [`WalletCore`](crate::WalletCore) facades for interacting with various
//! on-chain programs. //! on-chain programs.
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
use nssa::{Account, program::Program};
use nssa_core::program::InstructionData;
use crate::{AccDecodeData, PrivacyPreservingAccount, WalletCore};
pub mod native_token_transfer; pub mod native_token_transfer;
pub mod pinata; pub mod pinata;
pub mod token; pub mod token;
pub trait ProgramArgs {
fn private_transfer_preparation(
&self,
) -> (
InstructionData,
Program,
impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>,
);
}
pub async fn send_privacy_preserving_transaction_unified<PD: ProgramArgs>(
wallet_core: &WalletCore,
acc_vector: Vec<PrivacyPreservingAccount>,
method_data: PD,
) -> Result<(SendTxResponse, Vec<AccDecodeData>), ExecutionFailureKind> {
let (instruction_data, program, tx_pre_check) = method_data.private_transfer_preparation();
wallet_core
.send_privacy_preserving_tx_with_pre_check(
acc_vector.clone(),
&instruction_data,
&program.into(),
tx_pre_check,
)
.await
.map(|(resp, secrets)| {
let mut secrets_iter = secrets.into_iter();
(
resp,
acc_vector
.into_iter()
.filter_map(|acc| {
if acc.is_private() {
let secret = secrets_iter.next().expect("expected next secret");
if let Some(acc_id) = acc.account_id_decode_data() {
Some(AccDecodeData::Decode(secret, acc_id))
} else {
Some(AccDecodeData::Skip)
}
} else {
None
}
})
.collect(),
)
})
}

View File

@ -1,35 +0,0 @@
use common::{error::ExecutionFailureKind, rpc_primitives::requests::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_with_pre_check(
vec![
PrivacyPreservingAccount::PrivateOwned(from),
PrivacyPreservingAccount::Public(to),
],
&instruction_data,
&program.into(),
tx_pre_check,
)
.await
.map(|(resp, secrets)| {
let first = secrets
.into_iter()
.next()
.expect("expected sender's secret");
(resp, first)
})
}
}

View File

@ -1,75 +1,56 @@
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse}; use common::error::ExecutionFailureKind;
use nssa::{Account, program::Program}; use nssa::{Account, program::Program};
use nssa_core::program::InstructionData; use nssa_core::program::InstructionData;
use crate::{AccDecodeData, PrivacyPreservingAccount, WalletCore}; use crate::{WalletCore, program_facades::ProgramArgs};
pub mod deshielded;
pub mod private;
pub mod public; pub mod public;
pub mod shielded;
pub struct NativeTokenTransfer<'w>(pub &'w WalletCore); pub struct NativeTokenTransfer<'w>(pub &'w WalletCore);
fn auth_transfer_preparation( #[derive(Debug, Clone, Copy)]
balance_to_move: u128, pub struct NativeBalanceToMove {
) -> ( pub 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)
} }
impl NativeTokenTransfer<'_> { #[derive(Debug, Clone, Copy)]
pub async fn send_privacy_preserving_transfer_unified( pub struct InitArgs {}
impl ProgramArgs for NativeBalanceToMove {
fn private_transfer_preparation(
&self, &self,
acc_vector: Vec<PrivacyPreservingAccount>, ) -> (
method_data: u128, InstructionData,
) -> Result<(SendTxResponse, Vec<AccDecodeData>), ExecutionFailureKind> { Program,
let (instruction_data, program, tx_pre_check) = auth_transfer_preparation(method_data); impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>,
) {
let instruction_data = Program::serialize_instruction(self.balance_to_move).unwrap();
let program = Program::authenticated_transfer_program();
let tx_pre_check = move |accounts: &[&Account]| {
let from = accounts[0];
if from.balance >= self.balance_to_move {
Ok(())
} else {
Err(ExecutionFailureKind::InsufficientFundsError)
}
};
self.0 (instruction_data, program, tx_pre_check)
.send_privacy_preserving_tx_with_pre_check( }
acc_vector.clone(), }
&instruction_data,
&program, impl ProgramArgs for InitArgs {
tx_pre_check, fn private_transfer_preparation(
) &self,
.await ) -> (
.map(|(resp, secrets)| { InstructionData,
let mut secrets_iter = secrets.into_iter(); Program,
impl FnOnce(&[&Account]) -> Result<(), ExecutionFailureKind>,
( ) {
resp, (
acc_vector Program::serialize_instruction(0u128).unwrap(),
.into_iter() Program::authenticated_transfer_program(),
.filter_map(|acc| { |_| Ok(()),
if acc.is_private() { )
let secret = secrets_iter.next().expect("expected next secret");
if let Some(acc_id) = acc.account_id_decode_data() {
Some(AccDecodeData::Decode(secret, acc_id))
} else {
Some(AccDecodeData::Skip)
}
} else {
None
}
})
.collect(),
)
})
} }
} }

View File

@ -1,125 +0,0 @@
use std::vec;
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
use nssa::{AccountId, program::Program};
use nssa_core::{NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey};
use super::{NativeTokenTransfer, auth_transfer_preparation};
use crate::{AccDecodeData, PrivacyPreservingAccount};
impl NativeTokenTransfer<'_> {
pub async fn register_account_private(
&self,
from: AccountId,
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
let instruction: u128 = 0;
self.0
.send_privacy_preserving_tx_with_pre_check(
vec![PrivacyPreservingAccount::PrivateOwned(from)],
&Program::serialize_instruction(instruction).unwrap(),
&Program::authenticated_transfer_program().into(),
|_| Ok(()),
)
.await
.map(|(resp, secrets)| {
let mut secrets_iter = secrets.into_iter();
let first = secrets_iter.next().expect("expected sender's secret");
(resp, first)
})
}
pub async fn send_private_transfer_to_owned_account_gen(
&self,
from: AccountId,
to: AccountId,
balance_to_move: u128,
) -> Result<(SendTxResponse, Vec<AccDecodeData>), ExecutionFailureKind> {
self.send_privacy_preserving_transfer_unified(
vec![
PrivacyPreservingAccount::PrivateOwned(from),
PrivacyPreservingAccount::PrivateOwned(to),
],
balance_to_move,
)
.await
}
pub async fn send_private_transfer_to_outer_account_gen(
&self,
from: AccountId,
to_npk: NullifierPublicKey,
to_ipk: IncomingViewingPublicKey,
balance_to_move: u128,
) -> Result<(SendTxResponse, Vec<AccDecodeData>), ExecutionFailureKind> {
self.send_privacy_preserving_transfer_unified(
vec![
PrivacyPreservingAccount::PrivateOwned(from),
PrivacyPreservingAccount::PrivateForeign {
npk: to_npk,
ipk: to_ipk,
},
],
balance_to_move,
)
.await
}
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_with_pre_check(
vec![
PrivacyPreservingAccount::PrivateOwned(from),
PrivacyPreservingAccount::PrivateForeign {
npk: to_npk,
ipk: to_ipk,
},
],
&instruction_data,
&program.into(),
tx_pre_check,
)
.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_with_pre_check(
vec![
PrivacyPreservingAccount::PrivateOwned(from),
PrivacyPreservingAccount::PrivateOwned(to),
],
&instruction_data,
&program.into(),
tx_pre_check,
)
.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])
})
}
}

View File

@ -1,68 +0,0 @@
use common::{error::ExecutionFailureKind, rpc_primitives::requests::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_with_pre_check(
vec![
PrivacyPreservingAccount::Public(from),
PrivacyPreservingAccount::PrivateOwned(to),
],
&instruction_data,
&program.into(),
tx_pre_check,
)
.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_with_pre_check(
vec![
PrivacyPreservingAccount::Public(from),
PrivacyPreservingAccount::PrivateForeign {
npk: to_npk,
ipk: to_ipk,
},
],
&instruction_data,
&program.into(),
tx_pre_check,
)
.await
.map(|(resp, secrets)| {
let first = secrets
.into_iter()
.next()
.expect("expected sender's secret");
(resp, first)
})
}
}

View File

@ -1,11 +1,8 @@
use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse}; use common::{error::ExecutionFailureKind, rpc_primitives::requests::SendTxResponse};
use nssa::{AccountId, program::Program}; use nssa::{AccountId, program::Program};
use nssa_core::{ use nssa_core::program::InstructionData;
NullifierPublicKey, SharedSecretKey, encryption::IncomingViewingPublicKey,
program::InstructionData,
};
use crate::{PrivacyPreservingAccount, WalletCore}; use crate::{WalletCore, program_facades::ProgramArgs};
pub struct Token<'w>(pub &'w WalletCore); pub struct Token<'w>(pub &'w WalletCore);
@ -38,89 +35,6 @@ impl Token<'_> {
Ok(self.0.sequencer_client.send_tx_public(tx).await?) Ok(self.0.sequencer_client.send_tx_public(tx).await?)
} }
pub async fn send_new_definition_private_owned_supply(
&self,
definition_account_id: AccountId,
supply_account_id: AccountId,
name: [u8; 6],
total_supply: u128,
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
let (instruction_data, program) = 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,
&program.into(),
)
.await
.map(|(resp, secrets)| {
let first = secrets
.into_iter()
.next()
.expect("expected supply's secret");
(resp, first)
})
}
pub async fn send_new_definition_private_owned_definiton(
&self,
definition_account_id: AccountId,
supply_account_id: AccountId,
name: [u8; 6],
total_supply: u128,
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
let (instruction_data, program) = token_program_preparation_definition(name, total_supply);
self.0
.send_privacy_preserving_tx(
vec![
PrivacyPreservingAccount::PrivateOwned(definition_account_id),
PrivacyPreservingAccount::Public(supply_account_id),
],
&instruction_data,
&program.into(),
)
.await
.map(|(resp, secrets)| {
let first = secrets
.into_iter()
.next()
.expect("expected definition's secret");
(resp, first)
})
}
pub async fn send_new_definition_private_owned_definiton_and_supply(
&self,
definition_account_id: AccountId,
supply_account_id: AccountId,
name: [u8; 6],
total_supply: u128,
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
let (instruction_data, program) = token_program_preparation_definition(name, total_supply);
self.0
.send_privacy_preserving_tx(
vec![
PrivacyPreservingAccount::PrivateOwned(definition_account_id),
PrivacyPreservingAccount::PrivateOwned(supply_account_id),
],
&instruction_data,
&program.into(),
)
.await
.map(|(resp, secrets)| {
let mut iter = secrets.into_iter();
let first = iter.next().expect("expected definition's secret");
let second = iter.next().expect("expected supply's secret");
(resp, [first, second])
})
}
pub async fn send_transfer_transaction( pub async fn send_transfer_transaction(
&self, &self,
sender_account_id: AccountId, sender_account_id: AccountId,
@ -161,147 +75,6 @@ impl Token<'_> {
Ok(self.0.sequencer_client.send_tx_public(tx).await?) 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) = token_program_preparation_transfer(amount);
self.0
.send_privacy_preserving_tx(
vec![
PrivacyPreservingAccount::PrivateOwned(sender_account_id),
PrivacyPreservingAccount::PrivateOwned(recipient_account_id),
],
&instruction_data,
&program.into(),
)
.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) = 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,
&program.into(),
)
.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) = token_program_preparation_transfer(amount);
self.0
.send_privacy_preserving_tx(
vec![
PrivacyPreservingAccount::PrivateOwned(sender_account_id),
PrivacyPreservingAccount::Public(recipient_account_id),
],
&instruction_data,
&program.into(),
)
.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) = token_program_preparation_transfer(amount);
self.0
.send_privacy_preserving_tx(
vec![
PrivacyPreservingAccount::Public(sender_account_id),
PrivacyPreservingAccount::PrivateOwned(recipient_account_id),
],
&instruction_data,
&program.into(),
)
.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) = 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,
&program.into(),
)
.await
.map(|(resp, secrets)| {
let first = secrets
.into_iter()
.next()
.expect("expected recipient's secret");
(resp, first)
})
}
pub async fn send_burn_transaction( pub async fn send_burn_transaction(
&self, &self,
definition_account_id: AccountId, definition_account_id: AccountId,
@ -309,7 +82,7 @@ impl Token<'_> {
amount: u128, amount: u128,
) -> Result<SendTxResponse, ExecutionFailureKind> { ) -> Result<SendTxResponse, ExecutionFailureKind> {
let account_ids = vec![definition_account_id, holder_account_id]; let account_ids = vec![definition_account_id, holder_account_id];
let (instruction, program) = token_program_preparation_burn(amount); let (instruction, program, _) = TokenBurnArgs { amount }.private_transfer_preparation();
// ToDo: Fix this by updating `nssa::public_transaction::Message::try_new` to get raw bytes // ToDo: Fix this by updating `nssa::public_transaction::Message::try_new` to get raw bytes
let instruction: [u32; 23] = instruction let instruction: [u32; 23] = instruction
@ -341,86 +114,6 @@ impl Token<'_> {
Ok(self.0.sequencer_client.send_tx_public(tx).await?) Ok(self.0.sequencer_client.send_tx_public(tx).await?)
} }
pub async fn send_burn_transaction_private_owned_account(
&self,
definition_account_id: AccountId,
holder_account_id: AccountId,
amount: u128,
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
let (instruction_data, program) = token_program_preparation_burn(amount);
self.0
.send_privacy_preserving_tx(
vec![
PrivacyPreservingAccount::PrivateOwned(definition_account_id),
PrivacyPreservingAccount::PrivateOwned(holder_account_id),
],
&instruction_data,
&program.into(),
)
.await
.map(|(resp, secrets)| {
let mut iter = secrets.into_iter();
let first = iter.next().expect("expected definition's secret");
let second = iter.next().expect("expected holder's secret");
(resp, [first, second])
})
}
pub async fn send_burn_transaction_deshielded_owned_account(
&self,
definition_account_id: AccountId,
holder_account_id: AccountId,
amount: u128,
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
let (instruction_data, program) = token_program_preparation_burn(amount);
self.0
.send_privacy_preserving_tx(
vec![
PrivacyPreservingAccount::PrivateOwned(definition_account_id),
PrivacyPreservingAccount::Public(holder_account_id),
],
&instruction_data,
&program.into(),
)
.await
.map(|(resp, secrets)| {
let first = secrets
.into_iter()
.next()
.expect("expected definition's secret");
(resp, first)
})
}
pub async fn send_burn_transaction_shielded(
&self,
definition_account_id: AccountId,
holder_account_id: AccountId,
amount: u128,
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
let (instruction_data, program) = token_program_preparation_burn(amount);
self.0
.send_privacy_preserving_tx(
vec![
PrivacyPreservingAccount::Public(definition_account_id),
PrivacyPreservingAccount::PrivateOwned(holder_account_id),
],
&instruction_data,
&program.into(),
)
.await
.map(|(resp, secrets)| {
let first = secrets
.into_iter()
.next()
.expect("expected holder's secret");
(resp, first)
})
}
pub async fn send_mint_transaction( pub async fn send_mint_transaction(
&self, &self,
definition_account_id: AccountId, definition_account_id: AccountId,
@ -428,7 +121,7 @@ impl Token<'_> {
amount: u128, amount: u128,
) -> Result<SendTxResponse, ExecutionFailureKind> { ) -> Result<SendTxResponse, ExecutionFailureKind> {
let account_ids = vec![definition_account_id, holder_account_id]; let account_ids = vec![definition_account_id, holder_account_id];
let (instruction, program) = token_program_preparation_mint(amount); let (instruction, program, _) = TokenMintArgs { amount }.private_transfer_preparation();
// ToDo: Fix this by updating `nssa::public_transaction::Message::try_new` to get raw bytes // ToDo: Fix this by updating `nssa::public_transaction::Message::try_new` to get raw bytes
let instruction: [u32; 23] = instruction.try_into().unwrap(); let instruction: [u32; 23] = instruction.try_into().unwrap();
@ -463,195 +156,104 @@ impl Token<'_> {
Ok(self.0.sequencer_client.send_tx_public(tx).await?) Ok(self.0.sequencer_client.send_tx_public(tx).await?)
} }
}
pub async fn send_mint_transaction_private_owned_account( #[derive(Debug, Clone, Copy)]
pub struct TokenDefinitionArgs {
pub name: [u8; 6],
pub total_supply: u128,
}
impl ProgramArgs for TokenDefinitionArgs {
fn private_transfer_preparation(
&self, &self,
definition_account_id: AccountId, ) -> (
holder_account_id: AccountId, InstructionData,
amount: u128, Program,
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> { impl FnOnce(&[&nssa::Account]) -> Result<(), ExecutionFailureKind>,
let (instruction_data, program) = token_program_preparation_mint(amount); ) {
// Instruction must be: [0x00 || total_supply (little-endian 16 bytes) || name (6 bytes)]
let mut instruction = [0; 23];
instruction[1..17].copy_from_slice(&self.total_supply.to_le_bytes());
instruction[17..].copy_from_slice(&self.name);
let instruction_data = Program::serialize_instruction(instruction).unwrap();
let program = Program::token();
self.0 (instruction_data, program, |_| Ok(()))
.send_privacy_preserving_tx(
vec![
PrivacyPreservingAccount::PrivateOwned(definition_account_id),
PrivacyPreservingAccount::PrivateOwned(holder_account_id),
],
&instruction_data,
&program.into(),
)
.await
.map(|(resp, secrets)| {
let mut iter = secrets.into_iter();
let first = iter.next().expect("expected definition's secret");
let second = iter.next().expect("expected holder's secret");
(resp, [first, second])
})
}
pub async fn send_mint_transaction_private_foreign_account(
&self,
definition_account_id: AccountId,
holder_npk: NullifierPublicKey,
holder_ipk: IncomingViewingPublicKey,
amount: u128,
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
let (instruction_data, program) = token_program_preparation_mint(amount);
self.0
.send_privacy_preserving_tx(
vec![
PrivacyPreservingAccount::PrivateOwned(definition_account_id),
PrivacyPreservingAccount::PrivateForeign {
npk: holder_npk,
ipk: holder_ipk,
},
],
&instruction_data,
&program.into(),
)
.await
.map(|(resp, secrets)| {
let mut iter = secrets.into_iter();
let first = iter.next().expect("expected definition's secret");
let second = iter.next().expect("expected holder's secret");
(resp, [first, second])
})
}
pub async fn send_mint_transaction_deshielded(
&self,
definition_account_id: AccountId,
holder_account_id: AccountId,
amount: u128,
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
let (instruction_data, program) = token_program_preparation_mint(amount);
self.0
.send_privacy_preserving_tx(
vec![
PrivacyPreservingAccount::PrivateOwned(definition_account_id),
PrivacyPreservingAccount::Public(holder_account_id),
],
&instruction_data,
&program.into(),
)
.await
.map(|(resp, secrets)| {
let first = secrets
.into_iter()
.next()
.expect("expected definition's secret");
(resp, first)
})
}
pub async fn send_mint_transaction_shielded_owned_account(
&self,
definition_account_id: AccountId,
holder_account_id: AccountId,
amount: u128,
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
let (instruction_data, program) = token_program_preparation_mint(amount);
self.0
.send_privacy_preserving_tx(
vec![
PrivacyPreservingAccount::Public(definition_account_id),
PrivacyPreservingAccount::PrivateOwned(holder_account_id),
],
&instruction_data,
&program.into(),
)
.await
.map(|(resp, secrets)| {
let first = secrets
.into_iter()
.next()
.expect("expected holder's secret");
(resp, first)
})
}
pub async fn send_mint_transaction_shielded_foreign_account(
&self,
definition_account_id: AccountId,
holder_npk: NullifierPublicKey,
holder_ipk: IncomingViewingPublicKey,
amount: u128,
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
let (instruction_data, program) = token_program_preparation_mint(amount);
self.0
.send_privacy_preserving_tx(
vec![
PrivacyPreservingAccount::Public(definition_account_id),
PrivacyPreservingAccount::PrivateForeign {
npk: holder_npk,
ipk: holder_ipk,
},
],
&instruction_data,
&program.into(),
)
.await
.map(|(resp, secrets)| {
let first = secrets
.into_iter()
.next()
.expect("expected holder's secret");
(resp, first)
})
} }
} }
fn token_program_preparation_transfer(amount: u128) -> (InstructionData, Program) { #[derive(Debug, Clone, Copy)]
// Instruction must be: [0x01 || amount (little-endian 16 bytes) || 0x00 || 0x00 || 0x00 || pub struct TokenTransferArgs {
// 0x00 || 0x00 || 0x00]. pub amount: u128,
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();
(instruction_data, program)
} }
fn token_program_preparation_definition( impl ProgramArgs for TokenTransferArgs {
name: [u8; 6], fn private_transfer_preparation(
total_supply: u128, &self,
) -> (InstructionData, Program) { ) -> (
// Instruction must be: [0x00 || total_supply (little-endian 16 bytes) || name (6 bytes)] InstructionData,
let mut instruction = [0; 23]; Program,
instruction[1..17].copy_from_slice(&total_supply.to_le_bytes()); impl FnOnce(&[&nssa::Account]) -> Result<(), ExecutionFailureKind>,
instruction[17..].copy_from_slice(&name); ) {
let instruction_data = Program::serialize_instruction(instruction).unwrap(); // Instruction must be: [0x01 || amount (little-endian 16 bytes) || 0x00 || 0x00 || 0x00 ||
let program = Program::token(); // 0x00 || 0x00 || 0x00].
let mut instruction = [0; 23];
instruction[0] = 0x01;
instruction[1..17].copy_from_slice(&self.amount.to_le_bytes());
let instruction_data = Program::serialize_instruction(instruction).unwrap();
let program = Program::token();
(instruction_data, program) (instruction_data, program, |_| Ok(()))
}
} }
fn token_program_preparation_burn(amount: u128) -> (InstructionData, Program) { #[derive(Debug, Clone, Copy)]
// Instruction must be: [0x03 || amount (little-endian 16 bytes) || 0x00 || 0x00 || 0x00 || pub struct TokenBurnArgs {
// 0x00 || 0x00 || 0x00]. pub amount: u128,
let mut instruction = [0; 23];
instruction[0] = 0x03;
instruction[1..17].copy_from_slice(&amount.to_le_bytes());
let instruction_data = Program::serialize_instruction(instruction).unwrap();
let program = Program::token();
(instruction_data, program)
} }
fn token_program_preparation_mint(amount: u128) -> (InstructionData, Program) { impl ProgramArgs for TokenBurnArgs {
// Instruction must be: [0x04 || amount (little-endian 16 bytes) || 0x00 || 0x00 || 0x00 || fn private_transfer_preparation(
// 0x00 || 0x00 || 0x00]. &self,
let mut instruction = [0; 23]; ) -> (
instruction[0] = 0x04; InstructionData,
instruction[1..17].copy_from_slice(&amount.to_le_bytes()); Program,
let instruction_data = Program::serialize_instruction(instruction).unwrap(); impl FnOnce(&[&nssa::Account]) -> Result<(), ExecutionFailureKind>,
let program = Program::token(); ) {
// Instruction must be: [0x03 || amount (little-endian 16 bytes) || 0x00 || 0x00 || 0x00 ||
// 0x00 || 0x00 || 0x00].
let mut instruction = [0; 23];
instruction[0] = 0x03;
instruction[1..17].copy_from_slice(&self.amount.to_le_bytes());
let instruction_data = Program::serialize_instruction(instruction).unwrap();
let program = Program::token();
(instruction_data, program) (instruction_data, program, |_| Ok(()))
}
}
#[derive(Debug, Clone, Copy)]
pub struct TokenMintArgs {
pub amount: u128,
}
impl ProgramArgs for TokenMintArgs {
fn private_transfer_preparation(
&self,
) -> (
InstructionData,
Program,
impl FnOnce(&[&nssa::Account]) -> Result<(), ExecutionFailureKind>,
) {
// Instruction must be: [0x04 || amount (little-endian 16 bytes) || 0x00 || 0x00 || 0x00 ||
// 0x00 || 0x00 || 0x00].
let mut instruction = [0; 23];
instruction[0] = 0x04;
instruction[1..17].copy_from_slice(&self.amount.to_le_bytes());
let instruction_data = Program::serialize_instruction(instruction).unwrap();
let program = Program::token();
(instruction_data, program, |_| Ok(()))
}
} }