@@ -7,6 +7,7 @@ pub use squads_multisig_program::accounts::ProposalCreate as ProposalCreateAccou
77pub use squads_multisig_program:: accounts:: ProposalVote as ProposalVoteAccounts ;
88pub use squads_multisig_program:: accounts:: SpendingLimitUse as SpendingLimitUseAccounts ;
99pub use squads_multisig_program:: accounts:: VaultTransactionCreate as VaultTransactionCreateAccounts ;
10+ pub use squads_multisig_program:: accounts:: VaultTransactionExecute as VaultTransactionExecuteAccounts ;
1011use squads_multisig_program:: anchor_lang:: AnchorSerialize ;
1112pub use squads_multisig_program:: instruction:: ConfigTransactionCreate as ConfigTransactionCreateData ;
1213pub use squads_multisig_program:: instruction:: ConfigTransactionExecute as ConfigTransactionExecuteData ;
@@ -15,13 +16,14 @@ pub use squads_multisig_program::instruction::ProposalApprove as ProposalApprove
1516pub use squads_multisig_program:: instruction:: ProposalCreate as ProposalCreateData ;
1617pub use squads_multisig_program:: instruction:: SpendingLimitUse as SpendingLimitUseData ;
1718pub use squads_multisig_program:: instruction:: VaultTransactionCreate as VaultTransactionCreateData ;
19+ pub use squads_multisig_program:: instruction:: VaultTransactionExecute as VaultTransactionExecuteData ;
1820pub use squads_multisig_program:: instructions:: ConfigTransactionCreateArgs ;
1921pub use squads_multisig_program:: instructions:: MultisigCreateArgs ;
2022pub use squads_multisig_program:: instructions:: ProposalCreateArgs ;
2123pub use squads_multisig_program:: instructions:: ProposalVoteArgs ;
2224pub use squads_multisig_program:: instructions:: SpendingLimitUseArgs ;
2325pub use squads_multisig_program:: instructions:: VaultTransactionCreateArgs ;
24- use squads_multisig_program:: TransactionMessage ;
26+ use squads_multisig_program:: { TransactionMessage , VaultTransaction } ;
2527
2628use crate :: anchor_lang:: prelude:: Pubkey ;
2729use crate :: anchor_lang:: AccountDeserialize ;
@@ -30,9 +32,11 @@ use crate::anchor_lang::{
3032} ;
3133use crate :: error:: ClientError ;
3234use crate :: pda:: get_vault_pda;
35+ use crate :: solana_program:: address_lookup_table_account:: AddressLookupTableAccount ;
3336use crate :: solana_program:: instruction:: AccountMeta ;
3437use crate :: state:: { Multisig , SpendingLimit } ;
35- use crate :: vault_transaction_message:: VaultTransactionMessageExt ;
38+
39+ use crate :: vault_transaction:: { AccountsForExecute , Error , VaultTransactionMessageExt } ;
3640use crate :: ClientResult ;
3741
3842/// Gets a `Multisig` account from the chain.
@@ -324,7 +328,6 @@ pub fn spending_limit_use(
324328/// vault_transaction_create,
325329/// };
326330/// use squads_multisig::pda::get_vault_pda;
327- /// use squads_multisig::vault_transaction_message::VaultTransactionMessageExt;
328331/// use squads_multisig_program::TransactionMessage;
329332///
330333/// let multisig = Pubkey::new_unique();
@@ -375,3 +378,71 @@ pub fn vault_transaction_create(
375378 program_id : program_id. unwrap_or ( squads_multisig_program:: ID ) ,
376379 }
377380}
381+
382+ /// Executes a vault transaction.
383+ /// Example:
384+ /// ```
385+ /// use solana_client::nonblocking::rpc_client::RpcClient;
386+ /// use squads_multisig::anchor_lang::AnchorSerialize;
387+ /// use squads_multisig::solana_program::pubkey::Pubkey;
388+ /// use squads_multisig::solana_program::{system_instruction, system_program};
389+ /// use squads_multisig::client::{
390+ /// VaultTransactionExecuteAccounts,
391+ /// vault_transaction_execute
392+ /// };
393+ ///
394+ /// let rpc_client = RpcClient::new("https://api.devnet.solana.com".to_string());
395+ ///
396+ /// let future = vault_transaction_execute(
397+ /// &rpc_client,
398+ /// VaultTransactionExecuteAccounts {
399+ /// multisig: Pubkey::new_unique(),
400+ /// transaction: Pubkey::new_unique(),
401+ /// member: Pubkey::new_unique(),
402+ /// proposal: Pubkey::new_unique(),
403+ /// },
404+ /// 0,
405+ /// None,
406+ /// );
407+ ///
408+ /// // TODO: await the `future`.
409+ /// ```
410+ pub async fn vault_transaction_execute (
411+ rpc_client : & RpcClient ,
412+ accounts : VaultTransactionExecuteAccounts ,
413+ vault_index : u8 ,
414+ program_id : Option < Pubkey > ,
415+ ) -> ClientResult < ( Instruction , Vec < AddressLookupTableAccount > ) > {
416+ let vault_pda = get_vault_pda ( & accounts. multisig , vault_index, None ) . 0 ;
417+
418+ let transaction_account_data = rpc_client. get_account_data ( & accounts. transaction ) . await ?;
419+ let transaction_account =
420+ VaultTransaction :: try_deserialize ( & mut transaction_account_data. as_slice ( ) )
421+ . map_err ( |_| ClientError :: DeserializationError ) ?;
422+
423+ let accounts_for_execute = AccountsForExecute :: load (
424+ rpc_client,
425+ & vault_pda,
426+ & accounts. transaction ,
427+ & transaction_account. message ,
428+ & transaction_account. ephemeral_signer_bumps ,
429+ & program_id. unwrap_or ( squads_multisig_program:: ID ) ,
430+ )
431+ . await
432+ . map_err ( |err| match err {
433+ Error :: FailedToLoadAccount => ClientError :: AccountNotFound ,
434+ } ) ?;
435+
436+ let mut accounts = accounts. to_account_metas ( Some ( false ) ) ;
437+ // Append the accounts required for executing the inner instructions.
438+ accounts. extend ( accounts_for_execute. account_metas . into_iter ( ) ) ;
439+
440+ Ok ( (
441+ Instruction {
442+ accounts,
443+ data : VaultTransactionExecuteData { } . data ( ) ,
444+ program_id : program_id. unwrap_or ( squads_multisig_program:: ID ) ,
445+ } ,
446+ accounts_for_execute. lookup_table_accounts ,
447+ ) )
448+ }
0 commit comments