From 4dcc767f56adc2e2b5d15279fd8dcd12fdf95972 Mon Sep 17 00:00:00 2001 From: cavemanloverboy Date: Sun, 14 Dec 2025 00:34:47 -0500 Subject: [PATCH] add optional fee payer to all commands --- cli/Cargo.lock | 26 +++++++++++------ cli/src/command/config_transaction_create.rs | 27 +++++++++++------ cli/src/command/config_transaction_execute.rs | 25 +++++++++++----- cli/src/command/initiate_program_upgrade.rs | 27 +++++++++++------ cli/src/command/initiate_transfer.rs | 27 +++++++++++------ cli/src/command/multisig_create.rs | 29 ++++++++++++------- cli/src/command/program_config_init.rs | 23 ++++++++++----- cli/src/command/proposal_vote.rs | 18 +++++------- .../vault_transaction_accounts_close.rs | 23 ++++++++++----- cli/src/command/vault_transaction_create.rs | 27 +++++++++++------ cli/src/command/vault_transaction_execute.rs | 18 +++++------- 11 files changed, 171 insertions(+), 99 deletions(-) diff --git a/cli/Cargo.lock b/cli/Cargo.lock index 0a606bb9..72d8d889 100644 --- a/cli/Cargo.lock +++ b/cli/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "Inflector" @@ -1322,9 +1322,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" dependencies = [ "powerfmt", ] @@ -2362,6 +2362,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-derive" version = "0.3.3" @@ -4643,12 +4649,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -4657,16 +4664,17 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ + "num-conv", "time-core", ] diff --git a/cli/src/command/config_transaction_create.rs b/cli/src/command/config_transaction_create.rs index 2f2c88c1..b9735a64 100644 --- a/cli/src/command/config_transaction_create.rs +++ b/cli/src/command/config_transaction_create.rs @@ -41,6 +41,10 @@ pub struct ConfigTransactionCreate { #[arg(long)] keypair: String, + /// Path to the Fee Payer Keypair + #[arg(long)] + fee_payer_keypair: Option, + /// The multisig where the transaction has been proposed #[arg(long)] multisig_pubkey: String, @@ -63,6 +67,7 @@ impl ConfigTransactionCreate { rpc_url, program_id, keypair, + fee_payer_keypair, multisig_pubkey, action, memo, @@ -75,8 +80,9 @@ impl ConfigTransactionCreate { let program_id = Pubkey::from_str(&program_id).expect("Invalid program ID"); let transaction_creator_keypair = create_signer_from_path(keypair).unwrap(); - let transaction_creator = transaction_creator_keypair.pubkey(); + let fee_payer_keypair = fee_payer_keypair.map(|path| create_signer_from_path(path).unwrap()); + let fee_payer = fee_payer_keypair.as_ref().map(|kp| kp.pubkey()); let rpc_url = rpc_url.unwrap_or_else(|| "https://api.mainnet-beta.solana.com".to_string()); let rpc_url_clone = rpc_url.clone(); @@ -128,8 +134,9 @@ impl ConfigTransactionCreate { .await .expect("Failed to get blockhash"); + let payer = fee_payer.unwrap_or(transaction_creator); let message = Message::try_compile( - &transaction_creator, + &payer, &[ ComputeBudgetInstruction::set_compute_unit_price( priority_fee_lamports.unwrap_or(5000), @@ -138,7 +145,7 @@ impl ConfigTransactionCreate { accounts: ConfigTransactionCreateAccounts { creator: transaction_creator, multisig, - rent_payer: transaction_creator, + rent_payer: fee_payer.unwrap_or(transaction_creator), transaction: transaction_pda.0, system_program: solana_sdk::system_program::id(), } @@ -156,7 +163,7 @@ impl ConfigTransactionCreate { accounts: ProposalCreateAccounts { creator: transaction_creator, multisig, - rent_payer: transaction_creator, + rent_payer: fee_payer.unwrap_or(transaction_creator), proposal: proposal_pda.0, system_program: solana_sdk::system_program::id(), } @@ -176,11 +183,13 @@ impl ConfigTransactionCreate { ) .unwrap(); - let transaction = VersionedTransaction::try_new( - VersionedMessage::V0(message), - &[&*transaction_creator_keypair], - ) - .expect("Failed to create transaction"); + let mut signers = vec![&*transaction_creator_keypair]; + if let Some(ref fee_payer_kp) = fee_payer_keypair { + signers.push(&**fee_payer_kp); + } + + let transaction = VersionedTransaction::try_new(VersionedMessage::V0(message), &signers) + .expect("Failed to create transaction"); let signature = send_and_confirm_transaction(&transaction, &rpc_client).await?; diff --git a/cli/src/command/config_transaction_execute.rs b/cli/src/command/config_transaction_execute.rs index 4fb54fe0..9245eefa 100644 --- a/cli/src/command/config_transaction_execute.rs +++ b/cli/src/command/config_transaction_execute.rs @@ -34,6 +34,10 @@ pub struct ConfigTransactionExecute { #[arg(long)] keypair: String, + /// Path to the Fee Payer Keypair + #[arg(long)] + fee_payer_keypair: Option, + /// The multisig where the transaction has been proposed #[arg(long)] multisig_pubkey: String, @@ -52,6 +56,7 @@ impl ConfigTransactionExecute { rpc_url, program_id, keypair, + fee_payer_keypair, multisig_pubkey, transaction_index, priority_fee_lamports, @@ -63,8 +68,9 @@ impl ConfigTransactionExecute { let program_id = Pubkey::from_str(&program_id).expect("Invalid program ID"); let transaction_creator_keypair = create_signer_from_path(keypair).unwrap(); - let transaction_creator = transaction_creator_keypair.pubkey(); + let fee_payer_keypair = fee_payer_keypair.map(|path| create_signer_from_path(path).unwrap()); + let fee_payer = fee_payer_keypair.as_ref().map(|kp| kp.pubkey()); let rpc_url = rpc_url.unwrap_or_else(|| "https://api.mainnet-beta.solana.com".to_string()); let rpc_url_clone = rpc_url.clone(); @@ -109,8 +115,9 @@ impl ConfigTransactionExecute { .await .expect("Failed to get blockhash"); + let payer = fee_payer.unwrap_or(transaction_creator); let message = Message::try_compile( - &transaction_creator, + &payer, &[ ComputeBudgetInstruction::set_compute_unit_price( priority_fee_lamports.unwrap_or(5000), @@ -119,7 +126,7 @@ impl ConfigTransactionExecute { accounts: ConfigTransactionExecuteAccounts { member: transaction_creator, transaction: transaction_pda.0, - rent_payer: Some(transaction_creator), + rent_payer: Some(fee_payer.unwrap_or(transaction_creator)), multisig, proposal: proposal_pda.0, system_program: Some(solana_sdk::system_program::id()), @@ -134,11 +141,13 @@ impl ConfigTransactionExecute { ) .unwrap(); - let transaction = VersionedTransaction::try_new( - VersionedMessage::V0(message), - &[&*transaction_creator_keypair], - ) - .expect("Failed to create transaction"); + let mut signers = vec![&*transaction_creator_keypair]; + if let Some(ref fee_payer_kp) = fee_payer_keypair { + signers.push(&**fee_payer_kp); + } + + let transaction = VersionedTransaction::try_new(VersionedMessage::V0(message), &signers) + .expect("Failed to create transaction"); let signature = send_and_confirm_transaction(&transaction, &rpc_client).await?; diff --git a/cli/src/command/initiate_program_upgrade.rs b/cli/src/command/initiate_program_upgrade.rs index 393d879b..9fc6fe63 100644 --- a/cli/src/command/initiate_program_upgrade.rs +++ b/cli/src/command/initiate_program_upgrade.rs @@ -45,6 +45,10 @@ pub struct InitiateProgramUpgrade { #[arg(long)] keypair: String, + /// Path to the Fee Payer Keypair + #[arg(long)] + fee_payer_keypair: Option, + /// The multisig where the transaction has been proposed #[arg(long)] multisig_pubkey: String, @@ -74,6 +78,7 @@ impl InitiateProgramUpgrade { rpc_url, squads_program_id, keypair, + fee_payer_keypair, multisig_pubkey, memo, vault_index, @@ -89,8 +94,9 @@ impl InitiateProgramUpgrade { let program_id = Pubkey::from_str(&program_id).expect("Invalid program ID"); let transaction_creator_keypair = create_signer_from_path(keypair).unwrap(); - let transaction_creator = transaction_creator_keypair.pubkey(); + let fee_payer_keypair = fee_payer_keypair.map(|path| create_signer_from_path(path).unwrap()); + let fee_payer = fee_payer_keypair.as_ref().map(|kp| kp.pubkey()); let program_to_upgrade = Pubkey::from_str(&program_to_upgrade_id).expect("Invalid to upgrade program ID"); @@ -158,8 +164,9 @@ impl InitiateProgramUpgrade { let upgrade_program_message = Message::try_compile(&vault_pda.0, &[instruction], &[], blockhash).unwrap(); + let payer = fee_payer.unwrap_or(transaction_creator); let message = Message::try_compile( - &transaction_creator, + &payer, &[ ComputeBudgetInstruction::set_compute_unit_price( priority_fee_lamports.unwrap_or(200_000), @@ -167,7 +174,7 @@ impl InitiateProgramUpgrade { Instruction { accounts: VaultTransactionCreateAccounts { creator: transaction_creator, - rent_payer: transaction_creator, + rent_payer: fee_payer.unwrap_or(transaction_creator), transaction: transaction_pda.0, multisig, system_program: solana_sdk::system_program::id(), @@ -187,7 +194,7 @@ impl InitiateProgramUpgrade { Instruction { accounts: ProposalCreateAccounts { creator: transaction_creator, - rent_payer: transaction_creator, + rent_payer: fee_payer.unwrap_or(transaction_creator), proposal: proposal_pda.0, multisig, system_program: solana_sdk::system_program::id(), @@ -208,11 +215,13 @@ impl InitiateProgramUpgrade { ) .unwrap(); - let transaction = VersionedTransaction::try_new( - VersionedMessage::V0(message), - &[&*transaction_creator_keypair], - ) - .expect("Failed to create transaction"); + let mut signers = vec![&*transaction_creator_keypair]; + if let Some(ref fee_payer_kp) = fee_payer_keypair { + signers.push(&**fee_payer_kp); + } + + let transaction = VersionedTransaction::try_new(VersionedMessage::V0(message), &signers) + .expect("Failed to create transaction"); let signature = send_and_confirm_transaction(&transaction, &rpc_client).await?; diff --git a/cli/src/command/initiate_transfer.rs b/cli/src/command/initiate_transfer.rs index 9ab1a6cd..9dcaba8e 100644 --- a/cli/src/command/initiate_transfer.rs +++ b/cli/src/command/initiate_transfer.rs @@ -59,6 +59,10 @@ pub struct InitiateTransfer { #[arg(long)] keypair: String, + /// Path to the Fee Payer Keypair + #[arg(long)] + fee_payer_keypair: Option, + /// The multisig where the transaction has been proposed #[arg(long)] multisig_pubkey: String, @@ -81,6 +85,7 @@ impl InitiateTransfer { program_id, token_program_id, keypair, + fee_payer_keypair, multisig_pubkey, memo, vault_index, @@ -100,8 +105,9 @@ impl InitiateTransfer { let token_program_id = Pubkey::from_str(&token_program_id).expect("Invalid program ID"); let transaction_creator_keypair = create_signer_from_path(keypair).unwrap(); - let transaction_creator = transaction_creator_keypair.pubkey(); + let fee_payer_keypair = fee_payer_keypair.map(|path| create_signer_from_path(path).unwrap()); + let fee_payer = fee_payer_keypair.as_ref().map(|kp| kp.pubkey()); let rpc_url = rpc_url.unwrap_or_else(|| "https://api.mainnet-beta.solana.com".to_string()); let rpc_url_clone = rpc_url.clone(); @@ -182,8 +188,9 @@ impl InitiateTransfer { ) .unwrap(); + let payer = fee_payer.unwrap_or(transaction_creator); let message = Message::try_compile( - &transaction_creator, + &payer, &[ ComputeBudgetInstruction::set_compute_unit_price( priority_fee_lamports.unwrap_or(200_000), @@ -191,7 +198,7 @@ impl InitiateTransfer { Instruction { accounts: VaultTransactionCreateAccounts { creator: transaction_creator, - rent_payer: transaction_creator, + rent_payer: fee_payer.unwrap_or(transaction_creator), transaction: transaction_pda.0, multisig, system_program: solana_sdk::system_program::id(), @@ -211,7 +218,7 @@ impl InitiateTransfer { Instruction { accounts: ProposalCreateAccounts { creator: transaction_creator, - rent_payer: transaction_creator, + rent_payer: fee_payer.unwrap_or(transaction_creator), proposal: proposal_pda.0, multisig, system_program: solana_sdk::system_program::id(), @@ -232,11 +239,13 @@ impl InitiateTransfer { ) .unwrap(); - let transaction = VersionedTransaction::try_new( - VersionedMessage::V0(message), - &[&*transaction_creator_keypair], - ) - .expect("Failed to create transaction"); + let mut signers = vec![&*transaction_creator_keypair]; + if let Some(ref fee_payer_kp) = fee_payer_keypair { + signers.push(&**fee_payer_kp); + } + + let transaction = VersionedTransaction::try_new(VersionedMessage::V0(message), &signers) + .expect("Failed to create transaction"); let signature = send_and_confirm_transaction(&transaction, &rpc_client).await?; diff --git a/cli/src/command/multisig_create.rs b/cli/src/command/multisig_create.rs index 601473ab..dfc35e43 100644 --- a/cli/src/command/multisig_create.rs +++ b/cli/src/command/multisig_create.rs @@ -40,6 +40,10 @@ pub struct MultisigCreate { #[arg(long)] keypair: String, + /// Path to the Fee Payer Keypair + #[arg(long)] + fee_payer_keypair: Option, + /// Address of the Program Config Authority that will be set to control the Program Config #[arg(long)] config_authority: Option, @@ -63,6 +67,7 @@ impl MultisigCreate { rpc_url, program_id, keypair, + fee_payer_keypair, config_authority, members, threshold, @@ -76,8 +81,9 @@ impl MultisigCreate { let program_id = Pubkey::from_str(&program_id).expect("Invalid program ID"); let transaction_creator_keypair = create_signer_from_path(keypair).unwrap(); - let transaction_creator = transaction_creator_keypair.pubkey(); + let fee_payer_keypair = fee_payer_keypair.map(|path| create_signer_from_path(path).unwrap()); + let fee_payer = fee_payer_keypair.as_ref().map(|kp| kp.pubkey()); let rpc_url = rpc_url.unwrap_or_else(|| "https://api.mainnet-beta.solana.com".to_string()); @@ -151,8 +157,9 @@ impl MultisigCreate { .unwrap() .treasury; + let payer = fee_payer.unwrap_or(transaction_creator); let message = Message::try_compile( - &transaction_creator, + &payer, &[ ComputeBudgetInstruction::set_compute_unit_price( priority_fee_lamports.unwrap_or(5000), @@ -186,14 +193,16 @@ impl MultisigCreate { ) .unwrap(); - let transaction = VersionedTransaction::try_new( - VersionedMessage::V0(message), - &[ - &*transaction_creator_keypair, - &random_keypair as &dyn Signer, - ], - ) - .expect("Failed to create transaction"); + let mut signers: Vec<&dyn Signer> = vec![ + &*transaction_creator_keypair, + &random_keypair as &dyn Signer, + ]; + if let Some(ref fee_payer_kp) = fee_payer_keypair { + signers.push(&**fee_payer_kp); + } + + let transaction = VersionedTransaction::try_new(VersionedMessage::V0(message), &signers) + .expect("Failed to create transaction"); let signature = send_and_confirm_transaction(&transaction, &rpc_client).await?; diff --git a/cli/src/command/program_config_init.rs b/cli/src/command/program_config_init.rs index c91984dc..fd0331e0 100644 --- a/cli/src/command/program_config_init.rs +++ b/cli/src/command/program_config_init.rs @@ -36,6 +36,10 @@ pub struct ProgramConfigInit { #[arg(long)] initializer_keypair: String, + /// Path to the Fee Payer Keypair + #[arg(long)] + fee_payer_keypair: Option, + /// Address of the Program Config Authority that will be set to control the Program Config #[arg(long)] program_config_authority: String, @@ -58,6 +62,7 @@ impl ProgramConfigInit { rpc_url, program_id, initializer_keypair, + fee_payer_keypair, program_config_authority, treasury, multisig_creation_fee, @@ -73,8 +78,9 @@ impl ProgramConfigInit { let treasury = Pubkey::from_str(&treasury).expect("Invalid treasury address"); let transaction_creator_keypair = create_signer_from_path(initializer_keypair).unwrap(); - let transaction_creator = transaction_creator_keypair.pubkey(); + let fee_payer_keypair = fee_payer_keypair.map(|path| create_signer_from_path(path).unwrap()); + let fee_payer = fee_payer_keypair.as_ref().map(|kp| kp.pubkey()); let program_config = get_program_config_pda(Some(&program_id)).0; @@ -117,8 +123,9 @@ impl ProgramConfigInit { .await .expect("Failed to get blockhash"); + let payer = fee_payer.unwrap_or(transaction_creator); let message = Message::try_compile( - &transaction_creator, + &payer, &[ ComputeBudgetInstruction::set_compute_unit_price( priority_fee_lamports.unwrap_or(5000), @@ -146,11 +153,13 @@ impl ProgramConfigInit { ) .unwrap(); - let transaction = VersionedTransaction::try_new( - VersionedMessage::V0(message), - &[&*transaction_creator_keypair], - ) - .expect("Failed to create transaction"); + let mut signers = vec![&*transaction_creator_keypair]; + if let Some(ref fee_payer_kp) = fee_payer_keypair { + signers.push(&**fee_payer_kp); + } + + let transaction = VersionedTransaction::try_new(VersionedMessage::V0(message), &signers) + .expect("Failed to create transaction"); let signature = send_and_confirm_transaction(&transaction, &rpc_client).await?; diff --git a/cli/src/command/proposal_vote.rs b/cli/src/command/proposal_vote.rs index be8d0b11..6dd0a1ec 100644 --- a/cli/src/command/proposal_vote.rs +++ b/cli/src/command/proposal_vote.rs @@ -57,6 +57,7 @@ pub struct ProposalVote { #[arg(long)] priority_fee_lamports: Option, + /// Path to the Fee Payer Keypair #[arg(long)] fee_payer_keypair: Option, } @@ -90,8 +91,8 @@ impl ProposalVote { let rpc_url = rpc_url.unwrap_or_else(|| "https://api.mainnet-beta.solana.com".to_string()); - let transaction_fee_payer_keypair = - fee_payer_keypair.map(|path| create_signer_from_path(path).unwrap()); + let fee_payer_keypair = fee_payer_keypair.map(|path| create_signer_from_path(path).unwrap()); + let fee_payer = fee_payer_keypair.as_ref().map(|kp| kp.pubkey()); println!(); println!( @@ -148,13 +149,10 @@ impl ProposalVote { } }; - let fee_payer = transaction_fee_payer_keypair - .as_ref() - .map(|kp| kp.pubkey()) - .unwrap_or(transaction_creator); + let payer = fee_payer.unwrap_or(transaction_creator); let message = Message::try_compile( - &fee_payer, + &payer, &[ ComputeBudgetInstruction::set_compute_unit_price( priority_fee_lamports.unwrap_or(5000), @@ -176,10 +174,8 @@ impl ProposalVote { .unwrap(); let mut signers = vec![&*transaction_creator_keypair]; - if let Some(ref fee_payer_kp) = transaction_fee_payer_keypair { - if fee_payer_kp.pubkey() != transaction_creator { - signers.push(&**fee_payer_kp); - } + if let Some(ref fee_payer_kp) = fee_payer_keypair { + signers.push(&**fee_payer_kp); } let transaction = VersionedTransaction::try_new(VersionedMessage::V0(message), &signers) diff --git a/cli/src/command/vault_transaction_accounts_close.rs b/cli/src/command/vault_transaction_accounts_close.rs index f4a0e1b2..86016f28 100644 --- a/cli/src/command/vault_transaction_accounts_close.rs +++ b/cli/src/command/vault_transaction_accounts_close.rs @@ -36,6 +36,10 @@ pub struct VaultTransactionAccountsClose { #[arg(long)] keypair: String, + /// Path to the Fee Payer Keypair + #[arg(long)] + fee_payer_keypair: Option, + /// The multisig key #[arg(long)] multisig_pubkey: String, @@ -58,6 +62,7 @@ impl VaultTransactionAccountsClose { rpc_url, program_id, keypair, + fee_payer_keypair, multisig_pubkey, transaction_index, rent_collector, @@ -75,8 +80,9 @@ impl VaultTransactionAccountsClose { Pubkey::from_str(&rent_collector).expect("Invalid rent collector key"); let transaction_creator_keypair = create_signer_from_path(keypair).unwrap(); - let transaction_creator = transaction_creator_keypair.pubkey(); + let fee_payer_keypair = fee_payer_keypair.map(|path| create_signer_from_path(path).unwrap()); + let fee_payer = fee_payer_keypair.as_ref().map(|kp| kp.pubkey()); let rpc_url = rpc_url.unwrap_or_else(|| "https://api.mainnet-beta.solana.com".to_string()); @@ -117,8 +123,9 @@ impl VaultTransactionAccountsClose { .await .expect("Failed to get blockhash"); + let payer = fee_payer.unwrap_or(transaction_creator); let message = Message::try_compile( - &transaction_creator, + &payer, &[ ComputeBudgetInstruction::set_compute_unit_price( priority_fee_lamports.unwrap_or(5000), @@ -141,11 +148,13 @@ impl VaultTransactionAccountsClose { ) .unwrap(); - let transaction = VersionedTransaction::try_new( - VersionedMessage::V0(message), - &[&*transaction_creator_keypair], - ) - .expect("Failed to create transaction"); + let mut signers = vec![&*transaction_creator_keypair]; + if let Some(ref fee_payer_kp) = fee_payer_keypair { + signers.push(&**fee_payer_kp); + } + + let transaction = VersionedTransaction::try_new(VersionedMessage::V0(message), &signers) + .expect("Failed to create transaction"); let signature = send_and_confirm_transaction(&transaction, &rpc_client).await?; diff --git a/cli/src/command/vault_transaction_create.rs b/cli/src/command/vault_transaction_create.rs index 15eab1fc..47469c2c 100644 --- a/cli/src/command/vault_transaction_create.rs +++ b/cli/src/command/vault_transaction_create.rs @@ -40,6 +40,10 @@ pub struct VaultTransactionCreate { #[arg(long)] keypair: String, + /// Path to the Fee Payer Keypair + #[arg(long)] + fee_payer_keypair: Option, + /// The multisig where the transaction has been proposed #[arg(long)] multisig_pubkey: String, @@ -64,6 +68,7 @@ impl VaultTransactionCreate { rpc_url, program_id, keypair, + fee_payer_keypair, multisig_pubkey, memo, transaction_message, @@ -77,8 +82,9 @@ impl VaultTransactionCreate { let program_id = Pubkey::from_str(&program_id).expect("Invalid program ID"); let transaction_creator_keypair = create_signer_from_path(keypair).unwrap(); - let transaction_creator = transaction_creator_keypair.pubkey(); + let fee_payer_keypair = fee_payer_keypair.map(|path| create_signer_from_path(path).unwrap()); + let fee_payer = fee_payer_keypair.as_ref().map(|kp| kp.pubkey()); let rpc_url = rpc_url.unwrap_or_else(|| "https://api.mainnet-beta.solana.com".to_string()); let rpc_url_clone = rpc_url.clone(); @@ -126,8 +132,9 @@ impl VaultTransactionCreate { .await .expect("Failed to get blockhash"); + let payer = fee_payer.unwrap_or(transaction_creator); let message = Message::try_compile( - &transaction_creator, + &payer, &[ ComputeBudgetInstruction::set_compute_unit_price( priority_fee_lamports.unwrap_or(5000), @@ -135,7 +142,7 @@ impl VaultTransactionCreate { Instruction { accounts: VaultTransactionCreateAccounts { creator: transaction_creator, - rent_payer: transaction_creator, + rent_payer: fee_payer.unwrap_or(transaction_creator), transaction: transaction_pda.0, multisig, system_program: solana_sdk::system_program::id(), @@ -155,7 +162,7 @@ impl VaultTransactionCreate { Instruction { accounts: ProposalCreateAccounts { creator: transaction_creator, - rent_payer: transaction_creator, + rent_payer: fee_payer.unwrap_or(transaction_creator), proposal: proposal_pda.0, multisig, system_program: solana_sdk::system_program::id(), @@ -176,11 +183,13 @@ impl VaultTransactionCreate { ) .unwrap(); - let transaction = VersionedTransaction::try_new( - VersionedMessage::V0(message), - &[&*transaction_creator_keypair], - ) - .expect("Failed to create transaction"); + let mut signers = vec![&*transaction_creator_keypair]; + if let Some(ref fee_payer_kp) = fee_payer_keypair { + signers.push(&**fee_payer_kp); + } + + let transaction = VersionedTransaction::try_new(VersionedMessage::V0(message), &signers) + .expect("Failed to create transaction"); let signature = send_and_confirm_transaction(&transaction, &rpc_client).await?; diff --git a/cli/src/command/vault_transaction_execute.rs b/cli/src/command/vault_transaction_execute.rs index c710b471..7a5ed0c1 100644 --- a/cli/src/command/vault_transaction_execute.rs +++ b/cli/src/command/vault_transaction_execute.rs @@ -56,6 +56,7 @@ pub struct VaultTransactionExecute { #[arg(long)] extra_keypair: Option, + /// Path to the Fee Payer Keypair #[arg(long)] fee_payer_keypair: Option, } @@ -94,8 +95,8 @@ impl VaultTransactionExecute { let transaction_extra_signer_keypair = extra_keypair.map(|path| create_signer_from_path(path).unwrap()); - let transaction_fee_payer_keypair = - fee_payer_keypair.map(|path| create_signer_from_path(path).unwrap()); + let fee_payer_keypair = fee_payer_keypair.map(|path| create_signer_from_path(path).unwrap()); + let fee_payer = fee_payer_keypair.as_ref().map(|kp| kp.pubkey()); println!(); println!( @@ -168,13 +169,10 @@ impl VaultTransactionExecute { .await .expect("Failed to get blockhash"); - let fee_payer = transaction_fee_payer_keypair - .as_ref() - .map(|kp| kp.pubkey()) - .unwrap_or(transaction_creator); + let payer = fee_payer.unwrap_or(transaction_creator); let message = Message::try_compile( - &fee_payer, + &payer, &[ ComputeBudgetInstruction::set_compute_unit_limit( compute_unit_limit.unwrap_or(200_000), @@ -194,10 +192,8 @@ impl VaultTransactionExecute { .unwrap(); let mut signers = vec![&*transaction_creator_keypair]; - if let Some(ref fee_payer_kp) = transaction_fee_payer_keypair { - if fee_payer_kp.pubkey() != transaction_creator { - signers.push(&**fee_payer_kp); - } + if let Some(ref fee_payer_kp) = fee_payer_keypair { + signers.push(&**fee_payer_kp); } if let Some(ref extra_signer) = transaction_extra_signer_keypair { signers.push(&**extra_signer);