|
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"; |
2 | 8 | import { program } from "commander";
|
3 | 9 | import { PythCluster } from "@pythnetwork/client/lib/cluster";
|
4 | 10 | import { getPythClusterApiUrl } from "@pythnetwork/client/lib/cluster";
|
@@ -95,4 +101,53 @@ mutlisigCommand(
|
95 | 101 | await proposeInstructions(squad, vault, [proposalInstruction], false);
|
96 | 102 | });
|
97 | 103 |
|
| 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 | + |
98 | 153 | program.parse();
|
0 commit comments