diff --git a/cli/src/vault.rs b/cli/src/vault.rs index 7ba35e31..9854ca07 100644 --- a/cli/src/vault.rs +++ b/cli/src/vault.rs @@ -180,4 +180,24 @@ pub enum VaultActions { /// The new capacity amount: u64, }, + /// Delegate a token account + DelegateTokenAccount { + /// The vault pubkey + vault: String, + /// The delegate account + delegate: String, + /// The token mint + token_mint: String, + /// The token account + token_account: String, + }, + /// Transfer a token account + DelegatedTokenTransfer { + /// The token account + token_account: String, + /// The recipient pubkey + recipient_pubkey: String, + /// The amount to transfer + amount: u64, + }, } diff --git a/cli/src/vault_handler.rs b/cli/src/vault_handler.rs index 589bed5a..93865d04 100644 --- a/cli/src/vault_handler.rs +++ b/cli/src/vault_handler.rs @@ -10,8 +10,9 @@ use jito_vault_client::{ instructions::{ AddDelegationBuilder, BurnWithdrawalTicketBuilder, CloseVaultUpdateStateTrackerBuilder, CooldownDelegationBuilder, CooldownVaultNcnTicketBuilder, - CrankVaultUpdateStateTrackerBuilder, CreateTokenMetadataBuilder, EnqueueWithdrawalBuilder, - InitializeConfigBuilder, InitializeVaultBuilder, InitializeVaultNcnTicketBuilder, + CrankVaultUpdateStateTrackerBuilder, CreateTokenMetadataBuilder, + DelegateTokenAccountBuilder, EnqueueWithdrawalBuilder, InitializeConfigBuilder, + InitializeVaultBuilder, InitializeVaultNcnTicketBuilder, InitializeVaultOperatorDelegationBuilder, InitializeVaultUpdateStateTrackerBuilder, MintToBuilder, SetConfigAdminBuilder, SetDepositCapacityBuilder, WarmupVaultNcnTicketBuilder, @@ -40,6 +41,7 @@ use solana_sdk::{ use spl_associated_token_account::{ get_associated_token_address, instruction::create_associated_token_account_idempotent, }; +use spl_token::instruction::transfer; use crate::{ vault::{ConfigActions, VaultActions, VaultCommands}, @@ -196,6 +198,29 @@ impl VaultCliHandler { VaultCommands::Vault { action: VaultActions::SetCapacity { vault, amount }, } => self.set_capacity(vault, amount).await, + VaultCommands::Vault { + action: + VaultActions::DelegateTokenAccount { + vault, + delegate, + token_mint, + token_account, + }, + } => { + self.delegate_token_account(vault, delegate, token_mint, token_account) + .await + } + VaultCommands::Vault { + action: + VaultActions::DelegatedTokenTransfer { + token_account, + recipient_pubkey, + amount, + }, + } => { + self.delegated_token_transfer(token_account, recipient_pubkey, amount) + .await + } } } @@ -963,6 +988,101 @@ impl VaultCliHandler { Ok(()) } + pub async fn delegate_token_account( + &self, + vault: String, + delegate: String, + token_mint: String, + token_account: String, + ) -> Result<()> { + let keypair = self + .cli_config + .keypair + .as_ref() + .ok_or_else(|| anyhow!("Keypair not provided"))?; + let rpc_client = self.get_rpc_client(); + + let vault = Pubkey::from_str(&vault)?; + let delegate = Pubkey::from_str(&delegate)?; + let token_mint = Pubkey::from_str(&token_mint)?; + let token_account = Pubkey::from_str(&token_account)?; + + let mut ix_builder = DelegateTokenAccountBuilder::new(); + ix_builder + .config(Config::find_program_address(&self.vault_program_id).0) + .vault(vault) + .delegate_asset_admin(keypair.pubkey()) + .token_mint(token_mint) + .token_account(token_account) + .delegate(delegate) + .token_program(spl_token::ID); + + let blockhash = rpc_client.get_latest_blockhash().await?; + let tx = Transaction::new_signed_with_payer( + &[ix_builder.instruction()], + Some(&keypair.pubkey()), + &[keypair], + blockhash, + ); + info!("Delegating token account: {:?}", tx.get_signature()); + let result = rpc_client.send_and_confirm_transaction(&tx).await; + + if result.is_err() { + return Err(anyhow::anyhow!("Transaction failed: {:?}", result.err())); + } + + info!("Transaction confirmed: {:?}", tx.get_signature()); + info!("Delegated token account: {:?}", token_account); + + Ok(()) + } + + pub async fn delegated_token_transfer( + &self, + token_account: String, + recipient_pubkey: String, + amount: u64, + ) -> Result<()> { + let keypair = self + .cli_config + .keypair + .as_ref() + .ok_or_else(|| anyhow!("Keypair not provided"))?; + let rpc_client = self.get_rpc_client(); + + let token_account = Pubkey::from_str(&token_account)?; + let recipient_pubkey = Pubkey::from_str(&recipient_pubkey)?; + + let transfer_ix = transfer( + &spl_token::id(), + &token_account, + &recipient_pubkey, + &keypair.pubkey(), + &[], + amount, + )?; + + let blockhash = rpc_client.get_latest_blockhash().await?; + let tx = Transaction::new_signed_with_payer( + &[transfer_ix], + Some(&keypair.pubkey()), + &[keypair], + blockhash, + ); + + info!("Delegating token transfer: {:?}", tx.get_signature()); + let result = rpc_client.send_and_confirm_transaction(&tx).await; + + if result.is_err() { + return Err(anyhow::anyhow!("Transaction failed: {:?}", result.err())); + } + + info!("Transaction confirmed: {:?}", tx.get_signature()); + info!("Transferred {} tokens to {}", amount, recipient_pubkey); + + Ok(()) + } + pub async fn enqueue_withdrawal(&self, vault: String, amount: u64) -> Result<()> { let keypair = self .cli_config diff --git a/cli/temp.json b/cli/temp.json new file mode 100644 index 00000000..ce42d300 --- /dev/null +++ b/cli/temp.json @@ -0,0 +1,66 @@ +[ + 44, + 219, + 61, + 113, + 230, + 68, + 251, + 70, + 255, + 75, + 115, + 89, + 144, + 67, + 143, + 87, + 162, + 169, + 182, + 135, + 46, + 41, + 240, + 215, + 124, + 190, + 5, + 224, + 250, + 39, + 22, + 98, + 10, + 254, + 147, + 164, + 47, + 34, + 76, + 116, + 127, + 104, + 225, + 104, + 192, + 135, + 35, + 25, + 56, + 152, + 179, + 26, + 16, + 18, + 167, + 207, + 132, + 134, + 157, + 7, + 177, + 184, + 207, + 128 +] \ No newline at end of file diff --git a/docs/_tools/00_cli.md b/docs/_tools/00_cli.md index 764c7bee..8acd4485 100644 --- a/docs/_tools/00_cli.md +++ b/docs/_tools/00_cli.md @@ -490,6 +490,8 @@ Vault commands * `get` — Gets a vault * `list` — List all vaults * `set-capacity` — Sets the deposit capacity in the vault +* `delegate-token-account` — Delegate a token account +* `delegated-token-transfer` — Transfer a token account @@ -752,6 +754,35 @@ Sets the deposit capacity in the vault +## `jito-restaking-cli vault vault delegate-token-account` + +Delegate a token account + +**Usage:** `jito-restaking-cli vault vault delegate-token-account ` + +###### **Arguments:** + +* `` — The vault pubkey +* `` — The delegate account +* `` — The token mint +* `` — The token account + + + +## `jito-restaking-cli vault vault delegated-token-transfer` + +Transfer a token account + +**Usage:** `jito-restaking-cli vault vault delegated-token-transfer ` + +###### **Arguments:** + +* `` — The token account +* `` — The recipient pubkey +* `` — The amount to transfer + + +