1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#![cfg(not(target_os = "solana"))]
use account_compression::{self, utils::constants::GROUP_AUTHORITY_SEED, ID};
use anchor_lang::{system_program, InstructionData};
use solana_sdk::{
    instruction::{AccountMeta, Instruction},
    pubkey::Pubkey,
};
pub fn create_initialize_group_authority_instruction(
    signer_pubkey: Pubkey,
    group_accounts: Pubkey,
    seed: [u8; 32],
) -> Instruction {
    let cpi_authority_pda = get_cpi_authority_pda();
    let instruction_data = account_compression::instruction::InitializeGroupAuthority {
        _seed: seed,
        authority: cpi_authority_pda.0,
    };

    Instruction {
        program_id: ID,
        accounts: vec![
            AccountMeta::new(signer_pubkey, true),
            AccountMeta::new(group_accounts, false),
            AccountMeta::new_readonly(system_program::ID, false),
        ],
        data: instruction_data.data(),
    }
}

pub fn create_update_authority_instruction(
    signer_pubkey: Pubkey,
    new_authority: Pubkey,
) -> Instruction {
    let authority_pda = get_governance_authority_pda();
    let update_authority_ix = crate::instruction::UpdateGovernanceAuthority {
        bump: authority_pda.1,
        new_authority,
    };

    // update with new authority
    Instruction {
        program_id: crate::ID,
        accounts: vec![
            AccountMeta::new(signer_pubkey, true),
            AccountMeta::new(authority_pda.0, false),
        ],
        data: update_authority_ix.data(),
    }
}

pub fn create_register_program_instruction(
    signer_pubkey: Pubkey,
    authority_pda: (Pubkey, u8),
    group_account: Pubkey,
    program_id_to_be_registered: Pubkey,
) -> (Instruction, Pubkey) {
    let cpi_authority_pda = get_cpi_authority_pda();
    let registered_program_pda =
        Pubkey::find_program_address(&[program_id_to_be_registered.to_bytes().as_slice()], &ID).0;

    let register_program_ix = crate::instruction::RegisterSystemProgram {
        bump: cpi_authority_pda.1,
        program_id: program_id_to_be_registered,
    };

    let instruction = Instruction {
        program_id: crate::ID,
        accounts: vec![
            AccountMeta::new(signer_pubkey, true),
            AccountMeta::new(authority_pda.0, false),
            AccountMeta::new(cpi_authority_pda.0, false),
            AccountMeta::new(group_account, false),
            AccountMeta::new_readonly(ID, false),
            AccountMeta::new_readonly(system_program::ID, false),
            AccountMeta::new(registered_program_pda, false),
        ],
        data: register_program_ix.data(),
    };
    (instruction, registered_program_pda)
}

pub fn get_governance_authority_pda() -> (Pubkey, u8) {
    Pubkey::find_program_address(
        &[crate::AUTHORITY_PDA_SEED, crate::ID.to_bytes().as_slice()],
        &crate::ID,
    )
}

pub fn get_cpi_authority_pda() -> (Pubkey, u8) {
    Pubkey::find_program_address(
        &[
            crate::CPI_AUTHORITY_PDA_SEED,
            crate::ID.to_bytes().as_slice(),
        ],
        &crate::ID,
    )
}

pub fn create_initialize_governance_authority_instruction(
    signer_pubkey: Pubkey,
    authority: Pubkey,
) -> Instruction {
    let authority_pda = get_governance_authority_pda();
    let ix = crate::instruction::InitializeGovernanceAuthority {
        bump: authority_pda.1,
        authority,
        rewards: vec![],
    };

    Instruction {
        program_id: crate::ID,
        accounts: vec![
            AccountMeta::new(signer_pubkey, true),
            AccountMeta::new(authority_pda.0, false),
            AccountMeta::new_readonly(system_program::ID, false),
        ],
        data: ix.data(),
    }
}
pub fn get_group_account() -> (Pubkey, [u8; 32]) {
    let seed = [1u8; 32];
    let group_account = Pubkey::find_program_address(&[GROUP_AUTHORITY_SEED, seed.as_slice()], &ID);
    (group_account.0, seed)
}