1use borsh::{BorshDeserialize, BorshSerialize};
2use solana_program::pubkey::Pubkey;
3use solana_program::secp256k1_recover::{SECP256K1_PUBLIC_KEY_LENGTH, SECP256K1_SIGNATURE_LENGTH};
4use solana_program::instruction::{Instruction, AccountMeta};
5use crate::PDA_ADMIN_SEED;
6
7#[repr(C)]
8#[derive(BorshSerialize, BorshDeserialize, PartialEq, Debug, Clone)]
9pub struct InitializeAdminArgs {
10 pub public_key: [u8; SECP256K1_PUBLIC_KEY_LENGTH],
12 pub contract: Pubkey,
14}
15
16#[repr(C)]
17#[derive(BorshSerialize, BorshDeserialize, PartialEq, Debug, Clone)]
18pub struct ChangePublicKeyArgs {
19 pub new_public_key: [u8; SECP256K1_PUBLIC_KEY_LENGTH],
21 pub signature: [u8; SECP256K1_SIGNATURE_LENGTH],
23 pub recovery_id: u8,
25}
26
27#[repr(C)]
28#[derive(BorshSerialize, BorshDeserialize, PartialEq, Debug, Clone)]
29pub struct ChangeAuthorityArgs {
30 pub signature: [u8; SECP256K1_SIGNATURE_LENGTH],
32 pub recovery_id: u8,
34}
35
36#[repr(C)]
37#[derive(BorshSerialize, BorshDeserialize, PartialEq, Debug, Clone)]
38pub struct UpgradeArgs {
39 pub signature: [u8; SECP256K1_PUBLIC_KEY_LENGTH],
41 pub recovery_id: u8,
43}
44
45#[repr(C)]
46#[derive(BorshSerialize, BorshDeserialize, Clone)]
47pub enum UpgradeInstruction {
48 InitializeAdmin(InitializeAdminArgs),
57
58 ChangePublicKey(ChangePublicKeyArgs),
65
66 ChangeAuthority(ChangeAuthorityArgs),
76
77 Upgrade(UpgradeArgs),
93}
94
95pub fn initialize_admin(
96 program_id: Pubkey,
97 contract: Pubkey,
98 fee_payer: Pubkey,
99 public_key: [u8; SECP256K1_PUBLIC_KEY_LENGTH],
100) -> Instruction {
101 let (admin, _) = Pubkey::find_program_address(&[PDA_ADMIN_SEED.as_bytes(), contract.as_ref()], &program_id);
102 Instruction{
103 program_id,
104 data: UpgradeInstruction::InitializeAdmin(
105 InitializeAdminArgs {
106 public_key,
107 contract: Default::default(),
108 }
109 ).try_to_vec().unwrap(),
110 accounts: vec![
111 AccountMeta::new(admin, false),
112 AccountMeta::new(fee_payer, true),
113 AccountMeta::new_readonly(solana_program::system_program::id(), false),
114 AccountMeta::new_readonly(solana_program::sysvar::clock::id(), false),
115 ],
116 }
117}
118
119
120pub fn change_public_key(
121 program_id: Pubkey,
122 contract: Pubkey,
123 new_public_key: [u8; SECP256K1_PUBLIC_KEY_LENGTH],
124 signature: [u8; SECP256K1_SIGNATURE_LENGTH],
125 recovery_id: u8,
126) -> Instruction {
127 let (admin, _) = Pubkey::find_program_address(&[PDA_ADMIN_SEED.as_bytes(), contract.as_ref()], &program_id);
128 Instruction{
129 program_id,
130 data: UpgradeInstruction::ChangePublicKey(
131 ChangePublicKeyArgs {
132 new_public_key,
133 signature,
134 recovery_id,
135 }
136 ).try_to_vec().unwrap(),
137 accounts: vec![
138 AccountMeta::new(admin, false),
139 ],
140 }
141}
142
143pub fn change_authority(
144 program_id: Pubkey,
145 contract: Pubkey,
146 new_authority: Pubkey,
147 signature: [u8; SECP256K1_SIGNATURE_LENGTH],
148 recovery_id: u8,
149) -> Instruction {
150 let (admin, _) = Pubkey::find_program_address(&[PDA_ADMIN_SEED.as_bytes(), contract.as_ref()], &program_id);
151 let (program_data, _) = Pubkey::find_program_address(&[contract.as_ref()], &solana_program::bpf_loader_upgradeable::id());
152
153 Instruction{
154 program_id,
155 data: UpgradeInstruction::ChangeAuthority(
156 ChangeAuthorityArgs {
157 signature,
158 recovery_id,
159 }
160 ).try_to_vec().unwrap(),
161 accounts: vec![
162 AccountMeta::new(admin, false),
163 AccountMeta::new(program_data, false),
164 AccountMeta::new(new_authority, false),
165 AccountMeta::new(solana_program::bpf_loader_upgradeable::id(), false),
166 ],
167 }
168}
169
170pub fn upgrade(
171 program_id: Pubkey,
172 contract: Pubkey,
173 buffer: Pubkey,
174 spill: Pubkey,
175 signature: [u8; SECP256K1_SIGNATURE_LENGTH],
176 recovery_id: u8,
177) -> Instruction {
178 let (admin, _) = Pubkey::find_program_address(&[PDA_ADMIN_SEED.as_bytes(), contract.as_ref()], &program_id);
179 let (program_data, _) = Pubkey::find_program_address(&[contract.as_ref()], &solana_program::bpf_loader_upgradeable::id());
180
181 Instruction {
182 program_id,
183 data: UpgradeInstruction::Upgrade(
184 UpgradeArgs {
185 signature,
186 recovery_id,
187 }
188 ).try_to_vec().unwrap(),
189 accounts: vec![
190 AccountMeta::new(admin, false),
191 AccountMeta::new(program_data, false),
192 AccountMeta::new(contract, false),
193 AccountMeta::new(buffer, false),
194 AccountMeta::new(spill, false),
195 AccountMeta::new(solana_program::sysvar::rent::id(), false),
196 AccountMeta::new(solana_program::sysvar::clock::id(), false),
197 AccountMeta::new(solana_program::bpf_loader_upgradeable::id(), false),
198 ],
199 }
200}