Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions governance/xc_admin/packages/xc_admin_cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@
"@sqds/mesh": "^1.0.6",
"commander": "^9.5.0",
"typescript": "^4.9.4"
},
"dev-dependencies": {
"ts-node": "^10.9.2"
}
}
25 changes: 25 additions & 0 deletions governance/xc_admin/packages/xc_admin_cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
findDetermisticStakeAccountAddress,
getMultisigCluster,
getProposalInstructions,
idlSetBuffer,
isPriceStorePublisherInitialized,
} from "@pythnetwork/xc-admin-common";

Expand Down Expand Up @@ -284,6 +285,30 @@ multisigCommand("upgrade-program", "Upgrade a program from a buffer")
);
});

multisigCommand("upgrade-idl", "Upgrade an Anchor Idl from a bufffer")
.requiredOption(
"-p, --program-id <pubkey>",
"program whose idl you want to upgrade"
)
.requiredOption("-b, --buffer <pubkey>", "buffer account")
.action(async (options: any) => {
const vault = await loadVaultFromOptions(options);
const cluster: PythCluster = options.cluster;
const programId: PublicKey = new PublicKey(options.programId);
const buffer: PublicKey = new PublicKey(options.buffer);

const proposalInstruction: TransactionInstruction = await idlSetBuffer(
programId,
buffer,
await vault.getVaultAuthorityPDA(cluster)
);

await vault.proposeInstructions(
[proposalInstruction],
cluster,
DEFAULT_PRIORITY_FEE_CONFIG
);
});
async function closeProgramOrBuffer(
vault: MultisigVault,
cluster: PythCluster,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import {
UNRECOGNIZED_INSTRUCTION,
UnrecognizedProgram,
} from ".";
import { AnchorAccounts, resolveAccountNames } from "./anchor";
import {
AnchorAccounts,
IDL_SET_BUFFER_DISCRIMINATOR,
resolveAccountNames,
} from "./anchor";
import messageBufferIdl from "message_buffer/idl/message_buffer.json";
import { PublicKey, TransactionInstruction } from "@solana/web3.js";
import { Idl, BorshCoder } from "@coral-xyz/anchor";
Expand Down Expand Up @@ -66,6 +70,23 @@ export class AnchorMultisigInstruction implements MultisigInstruction {
default:
return UnrecognizedProgram.fromTransactionInstruction(instruction);
}

/// Special case for IDL instructions that all programs have
if (instruction.data.equals(IDL_SET_BUFFER_DISCRIMINATOR)) {
return new AnchorMultisigInstruction(
program,
"IdlSetBuffer",
{},
{
named: {
buffer: instruction.keys[0],
idlAccount: instruction.keys[1],
idlAuthority: instruction.keys[2],
},
remaining: instruction.keys.slice(3),
}
);
}
const instructionCoder = new BorshCoder(idl).instruction;

const deserializedData = instructionCoder.decode(instruction.data);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { Idl } from "@coral-xyz/anchor";
import { AccountMeta, TransactionInstruction } from "@solana/web3.js";
import {
AccountMeta,
PublicKey,
TransactionInstruction,
} from "@solana/web3.js";

type NamedAccounts = Record<string, AccountMeta>;
type RemainingAccounts = AccountMeta[];
Expand Down Expand Up @@ -28,3 +32,34 @@ export function resolveAccountNames(
});
return { named, remaining };
}

export const IDL_SET_BUFFER_DISCRIMINATOR = Buffer.from(
"40f4bc78a7e9690a03",
"hex"
);

async function getIdlAddress(programId: PublicKey): Promise<PublicKey> {
const programSigner = PublicKey.findProgramAddressSync([], programId)[0];
return PublicKey.createWithSeed(programSigner, "anchor:idl", programId);
}

export async function idlSetBuffer(
programId: PublicKey,
buffer: PublicKey,
idlAuthority: PublicKey
): Promise<TransactionInstruction> {
let idlAddress = await getIdlAddress(programId);
return {
programId,
data: IDL_SET_BUFFER_DISCRIMINATOR,
keys: [
{ pubkey: buffer, isSigner: false, isWritable: true },
{ pubkey: idlAddress, isSigner: false, isWritable: true },
{
pubkey: idlAuthority,
isSigner: true,
isWritable: true,
},
],
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ export class MultisigParser {
}
}

export { idlSetBuffer } from "./anchor";
export { WormholeMultisigInstruction } from "./WormholeMultisigInstruction";
export { PythMultisigInstruction } from "./PythMultisigInstruction";
export { AnchorMultisigInstruction } from "./MessageBufferMultisigInstruction";
Expand Down
47 changes: 24 additions & 23 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading