From 67e833e948716bee0b170adc2375e15e624337d2 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Sun, 15 Oct 2023 11:12:58 -0700 Subject: [PATCH 01/12] add `configure-confidential-transfer-account` command --- token/cli/src/main.rs | 156 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 2 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index b470169fb48..b8b3b3c3bd9 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -38,7 +38,7 @@ use solana_sdk::{ use spl_associated_token_account::get_associated_token_address_with_program_id; use spl_token_2022::{ extension::{ - confidential_transfer::ConfidentialTransferMint, + confidential_transfer::{ConfidentialTransferAccount, ConfidentialTransferMint}, confidential_transfer_fee::ConfidentialTransferFeeConfig, cpi_guard::CpiGuard, default_account_state::DefaultAccountState, @@ -52,7 +52,10 @@ use spl_token_2022::{ BaseStateWithExtensions, ExtensionType, StateWithExtensionsOwned, }, instruction::*, - solana_zk_token_sdk::zk_token_elgamal::pod::ElGamalPubkey, + solana_zk_token_sdk::{ + encryption::{auth_encryption::AeKey, elgamal::ElGamalKeypair}, + zk_token_elgamal::pod::ElGamalPubkey, + }, state::{Account, AccountState, Mint}, }; use spl_token_client::{ @@ -166,6 +169,7 @@ pub enum CommandName { InitializeMetadata, UpdateMetadata, UpdateConfidentialTransferSettings, + ConfigureConfidentialTransferAccount, } impl fmt::Display for CommandName { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -2875,6 +2879,66 @@ async fn command_update_confidential_transfer_settings( }) } +async fn command_configure_confidential_transfer_account( + config: &Config<'_>, + token_account_address: Pubkey, + owner: Pubkey, + maximum_credit_counter: Option, + elgamal_keypair: &ElGamalKeypair, + aes_key: &AeKey, + bulk_signers: BulkSigners, +) -> CommandResult { + if config.sign_only { + panic!("Sign-only is not yet supported."); + } + + let account = config.get_account_checked(&token_account_address).await?; + let current_account_len = account.data.len(); + + let state_with_extension = StateWithExtensionsOwned::::unpack(account.data)?; + let token = token_client_from_config(config, &state_with_extension.base.mint, None)?; + + // Reallocation (if needed) + let mut existing_extensions: Vec = state_with_extension.get_extension_types()?; + if !existing_extensions.contains(&ExtensionType::ConfidentialTransferAccount) { + existing_extensions.push(ExtensionType::ConfidentialTransferAccount); + let needed_account_len = + ExtensionType::try_calculate_account_len::(&existing_extensions)?; + if needed_account_len > current_account_len { + token + .reallocate( + &token_account_address, + &owner, + &[ExtensionType::ConfidentialTransferAccount], + &bulk_signers, + ) + .await?; + } + } + + let res = token + .confidential_transfer_configure_token_account( + &token_account_address, + &owner, + None, + maximum_credit_counter, + elgamal_keypair, + aes_key, + &bulk_signers, + ) + .await?; + + let tx_return = finish_tx(config, &res, false).await?; + Ok(match tx_return { + TransactionReturnData::CliSignature(signature) => { + config.output_format.formatted_string(&signature) + } + TransactionReturnData::CliSignOnlyData(sign_only_data) => { + config.output_format.formatted_string(&sign_only_data) + } + }) +} + struct SignOnlyNeedsFullMintSpec {} impl offline::ArgsConfig for SignOnlyNeedsFullMintSpec { fn sign_only_arg<'a, 'b>(&self, arg: Arg<'a, 'b>) -> Arg<'a, 'b> { @@ -4459,6 +4523,36 @@ fn app<'a, 'b>( .nonce_args(true) .offline_args(), ) + .subcommand( + SubCommand::with_name(CommandName::ConfigureConfidentialTransferAccount.into()) + .about("Enable confidential transfers for token account") + .arg( + Arg::with_name("account") + .validator(is_valid_pubkey) + .value_name("TOKEN_ACCOUNT_ADDRESS") + .takes_value(true) + .index(1) + .required(true) + .help("The address of the token account to enable confidential transfers for") + ) + .arg( + owner_address_arg() + ) + .arg( + Arg::with_name("maximum_pending_balance_credit_counter") + .long("maximum-pending-balance-credit-counter") + .value_name("MAXIMUM-CREDIT-COUNTER") + .takes_value(true) + .help( + "The maximum pending balance credit counter. \ + This parameter limits the number of confidential transfers that a token account \ + can receive to facilitate decryption of the encrypted balance. \ + Defaults to 65536 (2^16)" + ) + ) + .arg(multisig_signer_arg()) + .nonce_args(true) + ) } #[tokio::main] @@ -5308,6 +5402,39 @@ async fn process_command<'a>( ) .await } + (CommandName::ConfigureConfidentialTransferAccount, arg_matches) => { + let (owner_signer, owner) = + config.signer_or_default(arg_matches, "owner", &mut wallet_manager); + + let token_account = + config.pubkey_or_default(arg_matches, "account", &mut wallet_manager)?; + + // Deriving ElGamal and AES key from signer. Custom ElGamal and AES keys will be + // supported in the future once upgrading to clap-v3. + let elgamal_keypair = ElGamalKeypair::new_from_signer(&*owner_signer, &token_account.to_bytes()).unwrap(); + let aes_key = AeKey::new_from_signer(&*owner_signer, &token_account.to_bytes()).unwrap(); + + if config.multisigner_pubkeys.is_empty() { + push_signer_with_dedup(owner_signer, &mut bulk_signers); + } + + let maximum_credit_counter = value_t!( + arg_matches.value_of("maximum_pending_balance_credit_counter"), + u64 + ) + .ok(); + + command_configure_confidential_transfer_account( + config, + token_account, + owner, + maximum_credit_counter, + &elgamal_keypair, + &aes_key, + bulk_signers, + ) + .await + } } } @@ -7922,6 +8049,31 @@ mod tests { Some(auditor_pubkey), ); + // create a confidential transfer account + let token_account = + create_associated_account(&config, &payer, &token_pubkey, &payer.pubkey()).await; + + process_test_command( + &config, + &payer, + &[ + "spl-token", + CommandName::ConfigureConfidentialTransferAccount.into(), + &token_account.to_string(), + ], + ) + .await + .unwrap(); + + let account = config.rpc_client.get_account(&token_account).await.unwrap(); + let account_state = StateWithExtensionsOwned::::unpack(account.data).unwrap(); + let extension = account_state + .get_extension::() + .unwrap(); + assert_eq!(bool::from(extension.approved), false); + assert_eq!(bool::from(extension.allow_confidential_credits), true); + assert_eq!(bool::from(extension.allow_non_confidential_credits), true); + // disable confidential transfers process_test_command( &config, From bd3a513b61fdf5697963504fb387c613d63b91c8 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Sun, 15 Oct 2023 11:14:00 -0700 Subject: [PATCH 02/12] add `enable-confidential-transfers` and `disable-confidential-transfers` commands --- token/cli/src/main.rs | 214 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 211 insertions(+), 3 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index b8b3b3c3bd9..f2a8014d27b 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -170,6 +170,8 @@ pub enum CommandName { UpdateMetadata, UpdateConfidentialTransferSettings, ConfigureConfidentialTransferAccount, + EnableConfidentialTransfers, + DisableConfidentialTransfers, } impl fmt::Display for CommandName { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -2939,6 +2941,94 @@ async fn command_configure_confidential_transfer_account( }) } +async fn command_enable_disable_confidential_transfers( + config: &Config<'_>, + token_account_address: Pubkey, + owner: Pubkey, + bulk_signers: BulkSigners, + allow_confidential_credits: Option, + allow_non_confidential_credits: Option, +) -> CommandResult { + if config.sign_only { + panic!("Sign-only is not yet supported."); + } + + let account = config.get_account_checked(&token_account_address).await?; + let current_account_len = account.data.len(); + + let state_with_extension = StateWithExtensionsOwned::::unpack(account.data)?; + let token = token_client_from_config(config, &state_with_extension.base.mint, None)?; + + let existing_extensions: Vec = state_with_extension.get_extension_types()?; + if !existing_extensions.contains(&ExtensionType::ConfidentialTransferAccount) { + panic!("Confidential transfer is not yet configured for this account. \ + Use `configure-confidential-transfer-account` command instead."); + } + + // Reallocation (if needed) + let mut existing_extensions: Vec = state_with_extension.get_extension_types()?; + if !existing_extensions.contains(&ExtensionType::ConfidentialTransferAccount) { + existing_extensions.push(ExtensionType::ConfidentialTransferAccount); + let needed_account_len = + ExtensionType::try_calculate_account_len::(&existing_extensions)?; + if needed_account_len > current_account_len { + token + .reallocate( + &token_account_address, + &owner, + &[ExtensionType::ConfidentialTransferAccount], + &bulk_signers, + ) + .await?; + } + } + + let res = if let Some(allow_confidential_credits) = allow_confidential_credits { + let extension_state = state_with_extension + .get_extension::()? + .allow_confidential_credits + .into(); + + if extension_state == allow_confidential_credits { + return Ok(format!( + "Confidential transfers are already {}", + if extension_state { + "enabled" + } else { + "disabled" + } + )); + } + + if allow_confidential_credits { + token.confidential_transfer_enable_confidential_credits( + &token_account_address, + &owner, + &bulk_signers, + ).await + } else { + token.confidential_transfer_disable_confidential_credits( + &token_account_address, + &owner, + &bulk_signers, + ).await + } + + } else { + unimplemented!() + }?; + + let tx_return = finish_tx(config, &res, false).await?; + Ok(match tx_return { + TransactionReturnData::CliSignature(signature) => { + config.output_format.formatted_string(&signature) + } + TransactionReturnData::CliSignOnlyData(sign_only_data) => { + config.output_format.formatted_string(&sign_only_data) + } + }) +} + struct SignOnlyNeedsFullMintSpec {} impl offline::ArgsConfig for SignOnlyNeedsFullMintSpec { fn sign_only_arg<'a, 'b>(&self, arg: Arg<'a, 'b>) -> Arg<'a, 'b> { @@ -4525,7 +4615,7 @@ fn app<'a, 'b>( ) .subcommand( SubCommand::with_name(CommandName::ConfigureConfidentialTransferAccount.into()) - .about("Enable confidential transfers for token account") + .about("Configure confidential transfers for token account") .arg( Arg::with_name("account") .validator(is_valid_pubkey) @@ -4533,7 +4623,7 @@ fn app<'a, 'b>( .takes_value(true) .index(1) .required(true) - .help("The address of the token account to enable confidential transfers for") + .help("The address of the token account to configure confidential transfers for") ) .arg( owner_address_arg() @@ -4553,6 +4643,43 @@ fn app<'a, 'b>( .arg(multisig_signer_arg()) .nonce_args(true) ) + .subcommand( + SubCommand::with_name(CommandName::EnableConfidentialTransfers.into()) + .about("Enable confidential transfers for token account. To enable confidential transfers \ + for the first time, use `configure-confidential-transfer-account` instead.") + .arg( + Arg::with_name("account") + .validator(is_valid_pubkey) + .value_name("TOKEN_ACCOUNT_ADDRESS") + .takes_value(true) + .index(1) + .required(true) + .help("The address of the token account to enable confidential transfers for") + ) + .arg( + owner_address_arg() + ) + .arg(multisig_signer_arg()) + .nonce_args(true) + ) + .subcommand( + SubCommand::with_name(CommandName::DisableConfidentialTransfers.into()) + .about("Disable confidential transfers for token account") + .arg( + Arg::with_name("account") + .validator(is_valid_pubkey) + .value_name("TOKEN_ACCOUNT_ADDRESS") + .takes_value(true) + .index(1) + .required(true) + .help("The address of the token account to disable confidential transfers for") + ) + .arg( + owner_address_arg() + ) + .arg(multisig_signer_arg()) + .nonce_args(true) + ) } #[tokio::main] @@ -5435,6 +5562,48 @@ async fn process_command<'a>( ) .await } + (CommandName::EnableConfidentialTransfers, arg_matches) => { + let (owner_signer, owner) = + config.signer_or_default(arg_matches, "owner", &mut wallet_manager); + + let token_account = + config.pubkey_or_default(arg_matches, "account", &mut wallet_manager)?; + + if config.multisigner_pubkeys.is_empty() { + push_signer_with_dedup(owner_signer, &mut bulk_signers); + } + + command_enable_disable_confidential_transfers( + config, + token_account, + owner, + bulk_signers, + Some(true), + None, + ) + .await + } + (CommandName::DisableConfidentialTransfers, arg_matches) => { + let (owner_signer, owner) = + config.signer_or_default(arg_matches, "owner", &mut wallet_manager); + + let token_account = + config.pubkey_or_default(arg_matches, "account", &mut wallet_manager)?; + + if config.multisigner_pubkeys.is_empty() { + push_signer_with_dedup(owner_signer, &mut bulk_signers); + } + + command_enable_disable_confidential_transfers( + config, + token_account, + owner, + bulk_signers, + Some(false), + None, + ) + .await + } } } @@ -8074,7 +8243,46 @@ mod tests { assert_eq!(bool::from(extension.allow_confidential_credits), true); assert_eq!(bool::from(extension.allow_non_confidential_credits), true); - // disable confidential transfers + // disable and enable confidential trnasfers for an account + process_test_command( + &config, + &payer, + &[ + "spl-token", + CommandName::DisableConfidentialTransfers.into(), + &token_account.to_string(), + ], + ) + .await + .unwrap(); + + let account = config.rpc_client.get_account(&token_account).await.unwrap(); + let account_state = StateWithExtensionsOwned::::unpack(account.data).unwrap(); + let extension = account_state + .get_extension::() + .unwrap(); + assert_eq!(bool::from(extension.allow_confidential_credits), false); + + process_test_command( + &config, + &payer, + &[ + "spl-token", + CommandName::EnableConfidentialTransfers.into(), + &token_account.to_string(), + ], + ) + .await + .unwrap(); + + let account = config.rpc_client.get_account(&token_account).await.unwrap(); + let account_state = StateWithExtensionsOwned::::unpack(account.data).unwrap(); + let extension = account_state + .get_extension::() + .unwrap(); + assert_eq!(bool::from(extension.allow_confidential_credits), true); + + // disable confidential transfers for mint process_test_command( &config, &payer, From de0801c4923ca32b07e92ad88d522224f0b5d8cc Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Sun, 15 Oct 2023 11:14:11 -0700 Subject: [PATCH 03/12] add `enable-non-confidential-transfers` and `disable-non-confidential-transfers` commands --- token/cli/src/main.rs | 194 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 177 insertions(+), 17 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index f2a8014d27b..10a5a020aca 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -172,6 +172,8 @@ pub enum CommandName { ConfigureConfidentialTransferAccount, EnableConfidentialTransfers, DisableConfidentialTransfers, + EnableNonConfidentialTransfers, + DisableNonConfidentialTransfers, } impl fmt::Display for CommandName { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -2961,8 +2963,10 @@ async fn command_enable_disable_confidential_transfers( let existing_extensions: Vec = state_with_extension.get_extension_types()?; if !existing_extensions.contains(&ExtensionType::ConfidentialTransferAccount) { - panic!("Confidential transfer is not yet configured for this account. \ - Use `configure-confidential-transfer-account` command instead."); + panic!( + "Confidential transfer is not yet configured for this account. \ + Use `configure-confidential-transfer-account` command instead." + ); } // Reallocation (if needed) @@ -3001,21 +3005,58 @@ async fn command_enable_disable_confidential_transfers( } if allow_confidential_credits { - token.confidential_transfer_enable_confidential_credits( - &token_account_address, - &owner, - &bulk_signers, - ).await + token + .confidential_transfer_enable_confidential_credits( + &token_account_address, + &owner, + &bulk_signers, + ) + .await } else { - token.confidential_transfer_disable_confidential_credits( - &token_account_address, - &owner, - &bulk_signers, - ).await + token + .confidential_transfer_disable_confidential_credits( + &token_account_address, + &owner, + &bulk_signers, + ) + .await } - } else { - unimplemented!() + let allow_non_confidential_credits = + allow_non_confidential_credits.expect("Nothing to be done"); + let extension_state = state_with_extension + .get_extension::()? + .allow_non_confidential_credits + .into(); + + if extension_state == allow_non_confidential_credits { + return Ok(format!( + "Non-confidential transfers are already {}", + if extension_state { + "enabled" + } else { + "disabled" + } + )); + } + + if allow_non_confidential_credits { + token + .confidential_transfer_enable_non_confidential_credits( + &token_account_address, + &owner, + &bulk_signers, + ) + .await + } else { + token + .confidential_transfer_disable_non_confidential_credits( + &token_account_address, + &owner, + &bulk_signers, + ) + .await + } }?; let tx_return = finish_tx(config, &res, false).await?; @@ -4680,6 +4721,42 @@ fn app<'a, 'b>( .arg(multisig_signer_arg()) .nonce_args(true) ) + .subcommand( + SubCommand::with_name(CommandName::EnableNonConfidentialTransfers.into()) + .about("Enable non-confidential transfers for token account.") + .arg( + Arg::with_name("account") + .validator(is_valid_pubkey) + .value_name("TOKEN_ACCOUNT_ADDRESS") + .takes_value(true) + .index(1) + .required(true) + .help("The address of the token account to enable non-confidential transfers for") + ) + .arg( + owner_address_arg() + ) + .arg(multisig_signer_arg()) + .nonce_args(true) + ) + .subcommand( + SubCommand::with_name(CommandName::DisableNonConfidentialTransfers.into()) + .about("Disable non-confidential transfers for token account") + .arg( + Arg::with_name("account") + .validator(is_valid_pubkey) + .value_name("TOKEN_ACCOUNT_ADDRESS") + .takes_value(true) + .index(1) + .required(true) + .help("The address of the token account to disable non-confidential transfers for") + ) + .arg( + owner_address_arg() + ) + .arg(multisig_signer_arg()) + .nonce_args(true) + ) } #[tokio::main] @@ -5538,8 +5615,10 @@ async fn process_command<'a>( // Deriving ElGamal and AES key from signer. Custom ElGamal and AES keys will be // supported in the future once upgrading to clap-v3. - let elgamal_keypair = ElGamalKeypair::new_from_signer(&*owner_signer, &token_account.to_bytes()).unwrap(); - let aes_key = AeKey::new_from_signer(&*owner_signer, &token_account.to_bytes()).unwrap(); + let elgamal_keypair = + ElGamalKeypair::new_from_signer(&*owner_signer, &token_account.to_bytes()).unwrap(); + let aes_key = + AeKey::new_from_signer(&*owner_signer, &token_account.to_bytes()).unwrap(); if config.multisigner_pubkeys.is_empty() { push_signer_with_dedup(owner_signer, &mut bulk_signers); @@ -5604,6 +5683,48 @@ async fn process_command<'a>( ) .await } + (CommandName::EnableNonConfidentialTransfers, arg_matches) => { + let (owner_signer, owner) = + config.signer_or_default(arg_matches, "owner", &mut wallet_manager); + + let token_account = + config.pubkey_or_default(arg_matches, "account", &mut wallet_manager)?; + + if config.multisigner_pubkeys.is_empty() { + push_signer_with_dedup(owner_signer, &mut bulk_signers); + } + + command_enable_disable_confidential_transfers( + config, + token_account, + owner, + bulk_signers, + None, + Some(true), + ) + .await + } + (CommandName::DisableNonConfidentialTransfers, arg_matches) => { + let (owner_signer, owner) = + config.signer_or_default(arg_matches, "owner", &mut wallet_manager); + + let token_account = + config.pubkey_or_default(arg_matches, "account", &mut wallet_manager)?; + + if config.multisigner_pubkeys.is_empty() { + push_signer_with_dedup(owner_signer, &mut bulk_signers); + } + + command_enable_disable_confidential_transfers( + config, + token_account, + owner, + bulk_signers, + None, + Some(false), + ) + .await + } } } @@ -8243,7 +8364,7 @@ mod tests { assert_eq!(bool::from(extension.allow_confidential_credits), true); assert_eq!(bool::from(extension.allow_non_confidential_credits), true); - // disable and enable confidential trnasfers for an account + // disable and enable confidential transfers for an account process_test_command( &config, &payer, @@ -8282,6 +8403,45 @@ mod tests { .unwrap(); assert_eq!(bool::from(extension.allow_confidential_credits), true); + // disable and eanble non-confidential transfers for an account + process_test_command( + &config, + &payer, + &[ + "spl-token", + CommandName::DisableNonConfidentialTransfers.into(), + &token_account.to_string(), + ], + ) + .await + .unwrap(); + + let account = config.rpc_client.get_account(&token_account).await.unwrap(); + let account_state = StateWithExtensionsOwned::::unpack(account.data).unwrap(); + let extension = account_state + .get_extension::() + .unwrap(); + assert_eq!(bool::from(extension.allow_non_confidential_credits), false); + + process_test_command( + &config, + &payer, + &[ + "spl-token", + CommandName::EnableNonConfidentialTransfers.into(), + &token_account.to_string(), + ], + ) + .await + .unwrap(); + + let account = config.rpc_client.get_account(&token_account).await.unwrap(); + let account_state = StateWithExtensionsOwned::::unpack(account.data).unwrap(); + let extension = account_state + .get_extension::() + .unwrap(); + assert_eq!(bool::from(extension.allow_non_confidential_credits), true); + // disable confidential transfers for mint process_test_command( &config, From e27cd6fbf58b69bdc702a7cdef66323755913f0e Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Sun, 15 Oct 2023 11:17:25 -0700 Subject: [PATCH 04/12] rename `confidential-transfers` to `confidential-credits` for confidential account configure commands --- token/cli/src/main.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index 10a5a020aca..e9197165440 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -170,10 +170,10 @@ pub enum CommandName { UpdateMetadata, UpdateConfidentialTransferSettings, ConfigureConfidentialTransferAccount, - EnableConfidentialTransfers, - DisableConfidentialTransfers, - EnableNonConfidentialTransfers, - DisableNonConfidentialTransfers, + EnableConfidentialCredits, + DisableConfidentialCredits, + EnableNonConfidentialCredits, + DisableNonConfidentialCredits, } impl fmt::Display for CommandName { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -4685,7 +4685,7 @@ fn app<'a, 'b>( .nonce_args(true) ) .subcommand( - SubCommand::with_name(CommandName::EnableConfidentialTransfers.into()) + SubCommand::with_name(CommandName::EnableConfidentialCredits.into()) .about("Enable confidential transfers for token account. To enable confidential transfers \ for the first time, use `configure-confidential-transfer-account` instead.") .arg( @@ -4704,7 +4704,7 @@ fn app<'a, 'b>( .nonce_args(true) ) .subcommand( - SubCommand::with_name(CommandName::DisableConfidentialTransfers.into()) + SubCommand::with_name(CommandName::DisableConfidentialCredits.into()) .about("Disable confidential transfers for token account") .arg( Arg::with_name("account") @@ -4722,7 +4722,7 @@ fn app<'a, 'b>( .nonce_args(true) ) .subcommand( - SubCommand::with_name(CommandName::EnableNonConfidentialTransfers.into()) + SubCommand::with_name(CommandName::EnableNonConfidentialCredits.into()) .about("Enable non-confidential transfers for token account.") .arg( Arg::with_name("account") @@ -4740,7 +4740,7 @@ fn app<'a, 'b>( .nonce_args(true) ) .subcommand( - SubCommand::with_name(CommandName::DisableNonConfidentialTransfers.into()) + SubCommand::with_name(CommandName::DisableNonConfidentialCredits.into()) .about("Disable non-confidential transfers for token account") .arg( Arg::with_name("account") @@ -5641,7 +5641,7 @@ async fn process_command<'a>( ) .await } - (CommandName::EnableConfidentialTransfers, arg_matches) => { + (CommandName::EnableConfidentialCredits, arg_matches) => { let (owner_signer, owner) = config.signer_or_default(arg_matches, "owner", &mut wallet_manager); @@ -5662,7 +5662,7 @@ async fn process_command<'a>( ) .await } - (CommandName::DisableConfidentialTransfers, arg_matches) => { + (CommandName::DisableConfidentialCredits, arg_matches) => { let (owner_signer, owner) = config.signer_or_default(arg_matches, "owner", &mut wallet_manager); @@ -5683,7 +5683,7 @@ async fn process_command<'a>( ) .await } - (CommandName::EnableNonConfidentialTransfers, arg_matches) => { + (CommandName::EnableNonConfidentialCredits, arg_matches) => { let (owner_signer, owner) = config.signer_or_default(arg_matches, "owner", &mut wallet_manager); @@ -5704,7 +5704,7 @@ async fn process_command<'a>( ) .await } - (CommandName::DisableNonConfidentialTransfers, arg_matches) => { + (CommandName::DisableNonConfidentialCredits, arg_matches) => { let (owner_signer, owner) = config.signer_or_default(arg_matches, "owner", &mut wallet_manager); @@ -8370,7 +8370,7 @@ mod tests { &payer, &[ "spl-token", - CommandName::DisableConfidentialTransfers.into(), + CommandName::DisableConfidentialCredits.into(), &token_account.to_string(), ], ) @@ -8389,7 +8389,7 @@ mod tests { &payer, &[ "spl-token", - CommandName::EnableConfidentialTransfers.into(), + CommandName::EnableConfidentialCredits.into(), &token_account.to_string(), ], ) @@ -8409,7 +8409,7 @@ mod tests { &payer, &[ "spl-token", - CommandName::DisableNonConfidentialTransfers.into(), + CommandName::DisableNonConfidentialCredits.into(), &token_account.to_string(), ], ) @@ -8428,7 +8428,7 @@ mod tests { &payer, &[ "spl-token", - CommandName::EnableNonConfidentialTransfers.into(), + CommandName::EnableNonConfidentialCredits.into(), &token_account.to_string(), ], ) From fa70750e500e3fd5c62eea1ec455ec50900b963d Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Sun, 15 Oct 2023 11:41:22 -0700 Subject: [PATCH 05/12] clippy --- token/cli/src/main.rs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index e9197165440..2e4a6888d6b 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -2852,13 +2852,10 @@ async fn command_update_confidential_transfer_settings( if let Some(new_auditor_pubkey) = new_auditor_pubkey { println_display( config, - format!( - " auditor encryption pubkey set to {}", - new_auditor_pubkey.to_string(), - ), + format!(" auditor encryption pubkey set to {}", new_auditor_pubkey,), ); } else { - println_display(config, format!(" auditability disabled",)) + println_display(config, " auditability disabled".to_string()) } } @@ -5060,7 +5057,7 @@ async fn process_command<'a>( let no_recipient_is_ata_owner = arg_matches.is_present("no_recipient_is_ata_owner") || !recipient_is_ata_owner; if recipient_is_ata_owner { - println_display(config, format!("recipient-is-ata-owner is now the default behavior. The option has been deprecated and will be removed in a future release.")); + println_display(config, "recipient-is-ata-owner is now the default behavior. The option has been deprecated and will be removed in a future release.".to_string()); } let use_unchecked_instruction = arg_matches.is_present("use_unchecked_instruction"); let expected_fee = value_of::(arg_matches, "expected_fee"); @@ -8360,9 +8357,9 @@ mod tests { let extension = account_state .get_extension::() .unwrap(); - assert_eq!(bool::from(extension.approved), false); - assert_eq!(bool::from(extension.allow_confidential_credits), true); - assert_eq!(bool::from(extension.allow_non_confidential_credits), true); + assert!(!bool::from(extension.approved)); + assert!(bool::from(extension.allow_confidential_credits)); + assert!(bool::from(extension.allow_non_confidential_credits)); // disable and enable confidential transfers for an account process_test_command( @@ -8382,7 +8379,7 @@ mod tests { let extension = account_state .get_extension::() .unwrap(); - assert_eq!(bool::from(extension.allow_confidential_credits), false); + assert!(!bool::from(extension.allow_confidential_credits)); process_test_command( &config, @@ -8401,7 +8398,7 @@ mod tests { let extension = account_state .get_extension::() .unwrap(); - assert_eq!(bool::from(extension.allow_confidential_credits), true); + assert!(bool::from(extension.allow_confidential_credits)); // disable and eanble non-confidential transfers for an account process_test_command( @@ -8421,7 +8418,7 @@ mod tests { let extension = account_state .get_extension::() .unwrap(); - assert_eq!(bool::from(extension.allow_non_confidential_credits), false); + assert!(!bool::from(extension.allow_non_confidential_credits)); process_test_command( &config, @@ -8440,7 +8437,7 @@ mod tests { let extension = account_state .get_extension::() .unwrap(); - assert_eq!(bool::from(extension.allow_non_confidential_credits), true); + assert!(bool::from(extension.allow_non_confidential_credits)); // disable confidential transfers for mint process_test_command( From ae1f1cedb68a79e1cfc7f2b732518a07aee85e42 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Tue, 17 Oct 2023 17:04:26 -0700 Subject: [PATCH 06/12] remove unnecessary realloc logic --- token/cli/src/main.rs | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index 2e4a6888d6b..827719e344f 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -2966,24 +2966,6 @@ async fn command_enable_disable_confidential_transfers( ); } - // Reallocation (if needed) - let mut existing_extensions: Vec = state_with_extension.get_extension_types()?; - if !existing_extensions.contains(&ExtensionType::ConfidentialTransferAccount) { - existing_extensions.push(ExtensionType::ConfidentialTransferAccount); - let needed_account_len = - ExtensionType::try_calculate_account_len::(&existing_extensions)?; - if needed_account_len > current_account_len { - token - .reallocate( - &token_account_address, - &owner, - &[ExtensionType::ConfidentialTransferAccount], - &bulk_signers, - ) - .await?; - } - } - let res = if let Some(allow_confidential_credits) = allow_confidential_credits { let extension_state = state_with_extension .get_extension::()? From f4ff948e496bbb3af41123e7783dc4fb80ceea3f Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Tue, 17 Oct 2023 17:20:51 -0700 Subject: [PATCH 07/12] use match bindings to remove duplicate code --- token/cli/src/main.rs | 79 +++++++------------------------------------ 1 file changed, 13 insertions(+), 66 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index 827719e344f..63f5c074e4b 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -2953,7 +2953,6 @@ async fn command_enable_disable_confidential_transfers( } let account = config.get_account_checked(&token_account_address).await?; - let current_account_len = account.data.len(); let state_with_extension = StateWithExtensionsOwned::::unpack(account.data)?; let token = token_client_from_config(config, &state_with_extension.base.mint, None)?; @@ -5620,28 +5619,10 @@ async fn process_command<'a>( ) .await } - (CommandName::EnableConfidentialCredits, arg_matches) => { - let (owner_signer, owner) = - config.signer_or_default(arg_matches, "owner", &mut wallet_manager); - - let token_account = - config.pubkey_or_default(arg_matches, "account", &mut wallet_manager)?; - - if config.multisigner_pubkeys.is_empty() { - push_signer_with_dedup(owner_signer, &mut bulk_signers); - } - - command_enable_disable_confidential_transfers( - config, - token_account, - owner, - bulk_signers, - Some(true), - None, - ) - .await - } - (CommandName::DisableConfidentialCredits, arg_matches) => { + (c @ CommandName::EnableConfidentialCredits, arg_matches) + | (c @ CommandName::DisableConfidentialCredits, arg_matches) + | (c @ CommandName::EnableNonConfidentialCredits, arg_matches) + | (c @ CommandName::DisableNonConfidentialCredits, arg_matches) => { let (owner_signer, owner) = config.signer_or_default(arg_matches, "owner", &mut wallet_manager); @@ -5652,55 +5633,21 @@ async fn process_command<'a>( push_signer_with_dedup(owner_signer, &mut bulk_signers); } - command_enable_disable_confidential_transfers( - config, - token_account, - owner, - bulk_signers, - Some(false), - None, - ) - .await - } - (CommandName::EnableNonConfidentialCredits, arg_matches) => { - let (owner_signer, owner) = - config.signer_or_default(arg_matches, "owner", &mut wallet_manager); - - let token_account = - config.pubkey_or_default(arg_matches, "account", &mut wallet_manager)?; - - if config.multisigner_pubkeys.is_empty() { - push_signer_with_dedup(owner_signer, &mut bulk_signers); - } - - command_enable_disable_confidential_transfers( - config, - token_account, - owner, - bulk_signers, - None, - Some(true), - ) - .await - } - (CommandName::DisableNonConfidentialCredits, arg_matches) => { - let (owner_signer, owner) = - config.signer_or_default(arg_matches, "owner", &mut wallet_manager); - - let token_account = - config.pubkey_or_default(arg_matches, "account", &mut wallet_manager)?; - - if config.multisigner_pubkeys.is_empty() { - push_signer_with_dedup(owner_signer, &mut bulk_signers); - } + let (allow_confidential_credits, allow_non_confidential_credits) = match c { + CommandName::EnableConfidentialCredits => (Some(true), None), + CommandName::DisableConfidentialCredits => (Some(false), None), + CommandName::EnableNonConfidentialCredits => (None, Some(true)), + CommandName::DisableNonConfidentialCredits => (None, Some(false)), + _ => (None, None), + }; command_enable_disable_confidential_transfers( config, token_account, owner, bulk_signers, - None, - Some(false), + allow_confidential_credits, + allow_non_confidential_credits, ) .await } From d77a914be2db98b94533920b732530d7cbe5db20 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Tue, 17 Oct 2023 17:27:17 -0700 Subject: [PATCH 08/12] prevent `maximum_credit_counter` from being initialized to default on invalid number --- token/cli/src/main.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index 63f5c074e4b..afa4ee1252a 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -5602,11 +5602,16 @@ async fn process_command<'a>( push_signer_with_dedup(owner_signer, &mut bulk_signers); } - let maximum_credit_counter = value_t!( - arg_matches.value_of("maximum_pending_balance_credit_counter"), - u64 - ) - .ok(); + let maximum_credit_counter = + if arg_matches.is_present("maximum_pending_balance_credit_counter") { + let maximum_credit_counter = value_t_or_exit!( + arg_matches.value_of("maximum_pending_balance_credit_counter"), + u64 + ); + Some(maximum_credit_counter) + } else { + None + }; command_configure_confidential_transfer_account( config, From 624a51d777dcdaef0af3c04dba3e8c20a7e1812d Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Tue, 17 Oct 2023 18:25:52 -0700 Subject: [PATCH 09/12] add optional mint address argument to derive ATA --- token/cli/src/main.rs | 95 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 78 insertions(+), 17 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index afa4ee1252a..8c58e85331c 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -2880,10 +2880,12 @@ async fn command_update_confidential_transfer_settings( }) } +#[allow(clippy::too_many_arguments)] async fn command_configure_confidential_transfer_account( config: &Config<'_>, - token_account_address: Pubkey, + maybe_token: Option, owner: Pubkey, + maybe_account: Option, maximum_credit_counter: Option, elgamal_keypair: &ElGamalKeypair, aes_key: &AeKey, @@ -2893,6 +2895,15 @@ async fn command_configure_confidential_transfer_account( panic!("Sign-only is not yet supported."); } + let token_account_address = if let Some(account) = maybe_account { + account + } else { + let token_pubkey = + maybe_token.expect("Either a valid token or account address must be provided"); + let token = token_client_from_config(config, &token_pubkey, None)?; + token.get_associated_token_address(&owner) + }; + let account = config.get_account_checked(&token_account_address).await?; let current_account_len = account.data.len(); @@ -2942,8 +2953,9 @@ async fn command_configure_confidential_transfer_account( async fn command_enable_disable_confidential_transfers( config: &Config<'_>, - token_account_address: Pubkey, + maybe_token: Option, owner: Pubkey, + maybe_account: Option, bulk_signers: BulkSigners, allow_confidential_credits: Option, allow_non_confidential_credits: Option, @@ -2952,6 +2964,15 @@ async fn command_enable_disable_confidential_transfers( panic!("Sign-only is not yet supported."); } + let token_account_address = if let Some(account) = maybe_account { + account + } else { + let token_pubkey = + maybe_token.expect("Either a valid token or account address must be provided"); + let token = token_client_from_config(config, &token_pubkey, None)?; + token.get_associated_token_address(&owner) + }; + let account = config.get_account_checked(&token_account_address).await?; let state_with_extension = StateWithExtensionsOwned::::unpack(account.data)?; @@ -4641,12 +4662,19 @@ fn app<'a, 'b>( .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) - .required(true) .help("The address of the token account to configure confidential transfers for") ) .arg( owner_address_arg() ) + .arg( + Arg::with_name("token") + .long("token") + .validator(is_valid_pubkey) + .value_name("TOKEN_MINT_ADDRESS") + .takes_value(true) + .help("The token address with confidential transfers enabled"), + ) .arg( Arg::with_name("maximum_pending_balance_credit_counter") .long("maximum-pending-balance-credit-counter") @@ -4672,9 +4700,16 @@ fn app<'a, 'b>( .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) - .required(true) .help("The address of the token account to enable confidential transfers for") ) + .arg( + Arg::with_name("token") + .long("token") + .validator(is_valid_pubkey) + .value_name("TOKEN_MINT_ADDRESS") + .takes_value(true) + .help("The token address with confidential transfers enabled"), + ) .arg( owner_address_arg() ) @@ -4690,9 +4725,16 @@ fn app<'a, 'b>( .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) - .required(true) .help("The address of the token account to disable confidential transfers for") ) + .arg( + Arg::with_name("token") + .long("token") + .validator(is_valid_pubkey) + .value_name("TOKEN_MINT_ADDRESS") + .takes_value(true) + .help("The token address with confidential transfers enabled"), + ) .arg( owner_address_arg() ) @@ -4708,9 +4750,16 @@ fn app<'a, 'b>( .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) - .required(true) .help("The address of the token account to enable non-confidential transfers for") ) + .arg( + Arg::with_name("token") + .long("token") + .validator(is_valid_pubkey) + .value_name("TOKEN_MINT_ADDRESS") + .takes_value(true) + .help("The token address with confidential transfers enabled"), + ) .arg( owner_address_arg() ) @@ -4726,9 +4775,16 @@ fn app<'a, 'b>( .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .index(1) - .required(true) .help("The address of the token account to disable non-confidential transfers for") ) + .arg( + Arg::with_name("token") + .long("token") + .validator(is_valid_pubkey) + .value_name("TOKEN_MINT_ADDRESS") + .takes_value(true) + .help("The token address with confidential transfers enabled"), + ) .arg( owner_address_arg() ) @@ -5585,18 +5641,20 @@ async fn process_command<'a>( .await } (CommandName::ConfigureConfidentialTransferAccount, arg_matches) => { + let token = pubkey_of_signer(arg_matches, "token", &mut wallet_manager).unwrap(); + let (owner_signer, owner) = config.signer_or_default(arg_matches, "owner", &mut wallet_manager); - let token_account = - config.pubkey_or_default(arg_matches, "account", &mut wallet_manager)?; + let account = pubkey_of_signer(arg_matches, "account", &mut wallet_manager).unwrap(); // Deriving ElGamal and AES key from signer. Custom ElGamal and AES keys will be // supported in the future once upgrading to clap-v3. - let elgamal_keypair = - ElGamalKeypair::new_from_signer(&*owner_signer, &token_account.to_bytes()).unwrap(); - let aes_key = - AeKey::new_from_signer(&*owner_signer, &token_account.to_bytes()).unwrap(); + // + // NOTE:: Seed bytes are hardcoded to be empty bytes for now. They will be updated + // once custom ElGamal and AES keys are supported. + let elgamal_keypair = ElGamalKeypair::new_from_signer(&*owner_signer, b"").unwrap(); + let aes_key = AeKey::new_from_signer(&*owner_signer, b"").unwrap(); if config.multisigner_pubkeys.is_empty() { push_signer_with_dedup(owner_signer, &mut bulk_signers); @@ -5615,8 +5673,9 @@ async fn process_command<'a>( command_configure_confidential_transfer_account( config, - token_account, + token, owner, + account, maximum_credit_counter, &elgamal_keypair, &aes_key, @@ -5628,11 +5687,12 @@ async fn process_command<'a>( | (c @ CommandName::DisableConfidentialCredits, arg_matches) | (c @ CommandName::EnableNonConfidentialCredits, arg_matches) | (c @ CommandName::DisableNonConfidentialCredits, arg_matches) => { + let token = pubkey_of_signer(arg_matches, "token", &mut wallet_manager).unwrap(); + let (owner_signer, owner) = config.signer_or_default(arg_matches, "owner", &mut wallet_manager); - let token_account = - config.pubkey_or_default(arg_matches, "account", &mut wallet_manager)?; + let account = pubkey_of_signer(arg_matches, "account", &mut wallet_manager).unwrap(); if config.multisigner_pubkeys.is_empty() { push_signer_with_dedup(owner_signer, &mut bulk_signers); @@ -5648,8 +5708,9 @@ async fn process_command<'a>( command_enable_disable_confidential_transfers( config, - token_account, + token, owner, + account, bulk_signers, allow_confidential_credits, allow_non_confidential_credits, From 669a6c671f6f1a60b073212f2d4fa37ba65e93c4 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Wed, 18 Oct 2023 09:10:09 -0700 Subject: [PATCH 10/12] Apply suggestions from code review Co-authored-by: Jon Cinque --- token/cli/src/main.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index 8c58e85331c..2fc8df7536d 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -4657,12 +4657,14 @@ fn app<'a, 'b>( SubCommand::with_name(CommandName::ConfigureConfidentialTransferAccount.into()) .about("Configure confidential transfers for token account") .arg( - Arg::with_name("account") + Arg::with_name("address") + .long("address") .validator(is_valid_pubkey) .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) - .index(1) - .help("The address of the token account to configure confidential transfers for") + .conflicts_with("token") + .help("The address of the token account to configure confidential transfers for \ + [default: owner's associated token account]") ) .arg( owner_address_arg() @@ -4673,6 +4675,8 @@ fn app<'a, 'b>( .validator(is_valid_pubkey) .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) + .index(1) + .required_unless("address") .help("The token address with confidential transfers enabled"), ) .arg( From 01ed6ef7137695a93ac9dcec6e36219e17ec8d70 Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Wed, 18 Oct 2023 14:28:52 -0700 Subject: [PATCH 11/12] make token and address arguments consistent for confidential transfer commands --- token/cli/src/main.rs | 106 ++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 45 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index 2fc8df7536d..fec66e99467 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -4656,6 +4656,16 @@ fn app<'a, 'b>( .subcommand( SubCommand::with_name(CommandName::ConfigureConfidentialTransferAccount.into()) .about("Configure confidential transfers for token account") + .arg( + Arg::with_name("token") + .long("token") + .validator(is_valid_pubkey) + .value_name("TOKEN_MINT_ADDRESS") + .takes_value(true) + .index(1) + .required_unless("address") + .help("The token address with confidential transfers enabled"), + ) .arg( Arg::with_name("address") .long("address") @@ -4669,16 +4679,6 @@ fn app<'a, 'b>( .arg( owner_address_arg() ) - .arg( - Arg::with_name("token") - .long("token") - .validator(is_valid_pubkey) - .value_name("TOKEN_MINT_ADDRESS") - .takes_value(true) - .index(1) - .required_unless("address") - .help("The token address with confidential transfers enabled"), - ) .arg( Arg::with_name("maximum_pending_balance_credit_counter") .long("maximum-pending-balance-credit-counter") @@ -4699,20 +4699,24 @@ fn app<'a, 'b>( .about("Enable confidential transfers for token account. To enable confidential transfers \ for the first time, use `configure-confidential-transfer-account` instead.") .arg( - Arg::with_name("account") + Arg::with_name("token") + .long("token") .validator(is_valid_pubkey) - .value_name("TOKEN_ACCOUNT_ADDRESS") + .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .index(1) - .help("The address of the token account to enable confidential transfers for") + .required_unless("address") + .help("The token address with confidential transfers enabled"), ) .arg( - Arg::with_name("token") - .long("token") + Arg::with_name("address") + .long("address") .validator(is_valid_pubkey) - .value_name("TOKEN_MINT_ADDRESS") + .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) - .help("The token address with confidential transfers enabled"), + .conflicts_with("token") + .help("The address of the token account to configure confidential transfers for \ + [default: owner's associated token account]") ) .arg( owner_address_arg() @@ -4724,20 +4728,24 @@ fn app<'a, 'b>( SubCommand::with_name(CommandName::DisableConfidentialCredits.into()) .about("Disable confidential transfers for token account") .arg( - Arg::with_name("account") + Arg::with_name("token") + .long("token") .validator(is_valid_pubkey) - .value_name("TOKEN_ACCOUNT_ADDRESS") + .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .index(1) - .help("The address of the token account to disable confidential transfers for") + .required_unless("address") + .help("The token address with confidential transfers enabled"), ) .arg( - Arg::with_name("token") - .long("token") + Arg::with_name("address") + .long("address") .validator(is_valid_pubkey) - .value_name("TOKEN_MINT_ADDRESS") + .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) - .help("The token address with confidential transfers enabled"), + .conflicts_with("token") + .help("The address of the token account to configure confidential transfers for \ + [default: owner's associated token account]") ) .arg( owner_address_arg() @@ -4749,20 +4757,24 @@ fn app<'a, 'b>( SubCommand::with_name(CommandName::EnableNonConfidentialCredits.into()) .about("Enable non-confidential transfers for token account.") .arg( - Arg::with_name("account") + Arg::with_name("token") + .long("token") .validator(is_valid_pubkey) - .value_name("TOKEN_ACCOUNT_ADDRESS") + .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .index(1) - .help("The address of the token account to enable non-confidential transfers for") + .required_unless("address") + .help("The token address with confidential transfers enabled"), ) .arg( - Arg::with_name("token") - .long("token") + Arg::with_name("address") + .long("address") .validator(is_valid_pubkey) - .value_name("TOKEN_MINT_ADDRESS") + .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) - .help("The token address with confidential transfers enabled"), + .conflicts_with("token") + .help("The address of the token account to configure confidential transfers for \ + [default: owner's associated token account]") ) .arg( owner_address_arg() @@ -4774,20 +4786,24 @@ fn app<'a, 'b>( SubCommand::with_name(CommandName::DisableNonConfidentialCredits.into()) .about("Disable non-confidential transfers for token account") .arg( - Arg::with_name("account") + Arg::with_name("token") + .long("token") .validator(is_valid_pubkey) - .value_name("TOKEN_ACCOUNT_ADDRESS") + .value_name("TOKEN_MINT_ADDRESS") .takes_value(true) .index(1) - .help("The address of the token account to disable non-confidential transfers for") + .required_unless("address") + .help("The token address with confidential transfers enabled"), ) .arg( - Arg::with_name("token") - .long("token") + Arg::with_name("address") + .long("address") .validator(is_valid_pubkey) - .value_name("TOKEN_MINT_ADDRESS") + .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) - .help("The token address with confidential transfers enabled"), + .conflicts_with("token") + .help("The address of the token account to configure confidential transfers for \ + [default: owner's associated token account]") ) .arg( owner_address_arg() @@ -5650,7 +5666,7 @@ async fn process_command<'a>( let (owner_signer, owner) = config.signer_or_default(arg_matches, "owner", &mut wallet_manager); - let account = pubkey_of_signer(arg_matches, "account", &mut wallet_manager).unwrap(); + let account = pubkey_of_signer(arg_matches, "address", &mut wallet_manager).unwrap(); // Deriving ElGamal and AES key from signer. Custom ElGamal and AES keys will be // supported in the future once upgrading to clap-v3. @@ -5696,7 +5712,7 @@ async fn process_command<'a>( let (owner_signer, owner) = config.signer_or_default(arg_matches, "owner", &mut wallet_manager); - let account = pubkey_of_signer(arg_matches, "account", &mut wallet_manager).unwrap(); + let account = pubkey_of_signer(arg_matches, "address", &mut wallet_manager).unwrap(); if config.multisigner_pubkeys.is_empty() { push_signer_with_dedup(owner_signer, &mut bulk_signers); @@ -8345,7 +8361,7 @@ mod tests { &[ "spl-token", CommandName::ConfigureConfidentialTransferAccount.into(), - &token_account.to_string(), + &token_pubkey.to_string(), ], ) .await @@ -8367,7 +8383,7 @@ mod tests { &[ "spl-token", CommandName::DisableConfidentialCredits.into(), - &token_account.to_string(), + &token_pubkey.to_string(), ], ) .await @@ -8386,7 +8402,7 @@ mod tests { &[ "spl-token", CommandName::EnableConfidentialCredits.into(), - &token_account.to_string(), + &token_pubkey.to_string(), ], ) .await @@ -8406,7 +8422,7 @@ mod tests { &[ "spl-token", CommandName::DisableNonConfidentialCredits.into(), - &token_account.to_string(), + &token_pubkey.to_string(), ], ) .await @@ -8425,7 +8441,7 @@ mod tests { &[ "spl-token", CommandName::EnableNonConfidentialCredits.into(), - &token_account.to_string(), + &token_pubkey.to_string(), ], ) .await From cb28d62a3ee2705166ebe0d0d3cf5f730a425baa Mon Sep 17 00:00:00 2001 From: samkim-crypto Date: Wed, 18 Oct 2023 15:16:59 -0700 Subject: [PATCH 12/12] Apply suggestions from code review Co-authored-by: Jon Cinque --- token/cli/src/main.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/token/cli/src/main.rs b/token/cli/src/main.rs index fec66e99467..cbd89e16d9e 100644 --- a/token/cli/src/main.rs +++ b/token/cli/src/main.rs @@ -4715,7 +4715,7 @@ fn app<'a, 'b>( .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .conflicts_with("token") - .help("The address of the token account to configure confidential transfers for \ + .help("The address of the token account to enable confidential transfers for \ [default: owner's associated token account]") ) .arg( @@ -4744,7 +4744,7 @@ fn app<'a, 'b>( .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .conflicts_with("token") - .help("The address of the token account to configure confidential transfers for \ + .help("The address of the token account to disable confidential transfers for \ [default: owner's associated token account]") ) .arg( @@ -4773,7 +4773,7 @@ fn app<'a, 'b>( .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .conflicts_with("token") - .help("The address of the token account to configure confidential transfers for \ + .help("The address of the token account to enable non-confidential transfers for \ [default: owner's associated token account]") ) .arg( @@ -4802,7 +4802,7 @@ fn app<'a, 'b>( .value_name("TOKEN_ACCOUNT_ADDRESS") .takes_value(true) .conflicts_with("token") - .help("The address of the token account to configure confidential transfers for \ + .help("The address of the token account to disable non-confidential transfers for \ [default: owner's associated token account]") ) .arg(