Skip to content

Commit d2411b7

Browse files
authored
[xc-admin] CLI command to upgrade solana programs (#522)
* Format checkpoint * Add comment * Add comment
1 parent a69f5fb commit d2411b7

File tree

1 file changed

+56
-1
lines changed
  • governance/xc-admin/packages/xc-admin-cli/src

1 file changed

+56
-1
lines changed

governance/xc-admin/packages/xc-admin-cli/src/index.ts

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { Keypair, PublicKey } from "@solana/web3.js";
1+
import {
2+
Keypair,
3+
PublicKey,
4+
TransactionInstruction,
5+
SYSVAR_RENT_PUBKEY,
6+
SYSVAR_CLOCK_PUBKEY,
7+
} from "@solana/web3.js";
28
import { program } from "commander";
39
import { PythCluster } from "@pythnetwork/client/lib/cluster";
410
import { getPythClusterApiUrl } from "@pythnetwork/client/lib/cluster";
@@ -95,4 +101,53 @@ mutlisigCommand(
95101
await proposeInstructions(squad, vault, [proposalInstruction], false);
96102
});
97103

104+
mutlisigCommand("upgrade-program", "Upgrade a program from a buffer")
105+
.requiredOption(
106+
"-p, --program-id <pubkey>",
107+
"program that you want to upgrade"
108+
)
109+
.requiredOption("-b, --buffer <pubkey>", "buffer account")
110+
111+
.action(async (options: any) => {
112+
const wallet = new NodeWallet(
113+
Keypair.fromSecretKey(
114+
Uint8Array.from(JSON.parse(fs.readFileSync(options.wallet, "ascii")))
115+
)
116+
);
117+
const cluster: PythCluster = options.cluster;
118+
const programId: PublicKey = new PublicKey(options.programId);
119+
const buffer: PublicKey = new PublicKey(options.buffer);
120+
const vault: PublicKey = new PublicKey(options.vault);
121+
122+
const squad = SquadsMesh.endpoint(getPythClusterApiUrl(cluster), wallet);
123+
const msAccount = await squad.getMultisig(vault);
124+
const vaultAuthority = squad.getAuthorityPDA(
125+
msAccount.publicKey,
126+
msAccount.authorityIndex
127+
);
128+
129+
const programDataAccount = PublicKey.findProgramAddressSync(
130+
[programId.toBuffer()],
131+
BPF_UPGRADABLE_LOADER
132+
)[0];
133+
134+
// This is intruction is not in @solana/web3.js, source : https://docs.rs/solana-program/latest/src/solana_program/bpf_loader_upgradeable.rs.html#200
135+
const proposalInstruction: TransactionInstruction = {
136+
programId: BPF_UPGRADABLE_LOADER,
137+
// 4-bytes instruction discriminator, got it from https://docs.rs/solana-program/latest/src/solana_program/loader_upgradeable_instruction.rs.html#104
138+
data: Buffer.from([3, 0, 0, 0]),
139+
keys: [
140+
{ pubkey: programDataAccount, isSigner: false, isWritable: true },
141+
{ pubkey: programId, isSigner: false, isWritable: true },
142+
{ pubkey: buffer, isSigner: false, isWritable: true },
143+
{ pubkey: wallet.publicKey, isSigner: false, isWritable: true },
144+
{ pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
145+
{ pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false },
146+
{ pubkey: vaultAuthority, isSigner: true, isWritable: false },
147+
],
148+
};
149+
150+
await proposeInstructions(squad, vault, [proposalInstruction], false);
151+
});
152+
98153
program.parse();

0 commit comments

Comments
 (0)