Skip to main content

dlp_api/instruction_builder/
delegate.rs

1use borsh::to_vec;
2use dlp::{
3    args::DelegateArgs,
4    discriminator::DlpDiscriminator,
5    pda::{
6        delegate_buffer_pda_from_delegated_account_and_owner_program,
7        delegation_metadata_pda_from_delegated_account,
8        delegation_record_pda_from_delegated_account,
9    },
10    total_size_budget, AccountSizeClass, DLP_PROGRAM_DATA_SIZE_CLASS,
11};
12use solana_program::{
13    instruction::{AccountMeta, Instruction},
14    pubkey::Pubkey,
15    system_program,
16};
17
18/// Builds a delegate instruction
19/// See [dlp::processor::process_delegate] for docs.
20pub fn delegate(
21    payer: Pubkey,
22    delegated_account: Pubkey,
23    owner: Option<Pubkey>,
24    args: DelegateArgs,
25) -> Instruction {
26    build_delegate_instruction(
27        DlpDiscriminator::Delegate,
28        payer,
29        delegated_account,
30        owner,
31        args,
32    )
33}
34
35/// Builds a delegate instruction that allows any validator identity.
36/// See [dlp::processor::process_delegate_with_any_validator] for docs.
37pub fn delegate_with_any_validator(
38    payer: Pubkey,
39    delegated_account: Pubkey,
40    owner: Option<Pubkey>,
41    args: DelegateArgs,
42) -> Instruction {
43    build_delegate_instruction(
44        DlpDiscriminator::DelegateWithAnyValidator,
45        payer,
46        delegated_account,
47        owner,
48        args,
49    )
50}
51
52fn build_delegate_instruction(
53    discriminator: DlpDiscriminator,
54    payer: Pubkey,
55    delegated_account: Pubkey,
56    owner: Option<Pubkey>,
57    args: DelegateArgs,
58) -> Instruction {
59    let owner = owner.unwrap_or(system_program::id());
60    let delegate_buffer_pda =
61        delegate_buffer_pda_from_delegated_account_and_owner_program(
62            &delegated_account,
63            &owner,
64        );
65    let delegation_record_pda =
66        delegation_record_pda_from_delegated_account(&delegated_account);
67    let delegation_metadata_pda =
68        delegation_metadata_pda_from_delegated_account(&delegated_account);
69    let mut data = discriminator.to_vec();
70    data.extend_from_slice(&to_vec(&args).unwrap());
71
72    Instruction {
73        program_id: dlp::id(),
74        accounts: vec![
75            AccountMeta::new(payer, true),
76            AccountMeta::new(delegated_account, true),
77            AccountMeta::new_readonly(owner, false),
78            AccountMeta::new(delegate_buffer_pda, false),
79            AccountMeta::new(delegation_record_pda, false),
80            AccountMeta::new(delegation_metadata_pda, false),
81            AccountMeta::new_readonly(system_program::id(), false),
82        ],
83        data,
84    }
85}
86
87///
88/// Returns accounts-data-size budget for delegate instruction.
89///
90/// This value can be used with ComputeBudgetInstruction::SetLoadedAccountsDataSizeLimit
91///
92pub fn delegate_size_budget(delegated_account: AccountSizeClass) -> u32 {
93    total_size_budget(&[
94        DLP_PROGRAM_DATA_SIZE_CLASS,
95        AccountSizeClass::Tiny, // payer
96        delegated_account,      // delegated_account
97        AccountSizeClass::Tiny, // owner
98        delegated_account,      // delegate_buffer_pda
99        AccountSizeClass::Tiny, // delegation_record_pda
100        AccountSizeClass::Tiny, // delegation_metadata_pda
101        AccountSizeClass::Tiny, // system_program
102    ])
103}