Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
1 change: 1 addition & 0 deletions governance/xc_admin/packages/xc_admin_cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@pythnetwork/pyth-solana-receiver": "workspace:*",
"@pythnetwork/solana-utils": "workspace:^",
"@pythnetwork/xc-admin-common": "workspace:*",
"@pythnetwork/pyth-lazer-sdk": "workspace:*",
"@solana/spl-token": "^0.3.7",
"@solana/web3.js": "^1.73.0",
"@sqds/mesh": "^1.0.6",
Expand Down
54 changes: 53 additions & 1 deletion governance/xc_admin/packages/xc_admin_cli/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Program } from "@coral-xyz/anchor";
import { Program, BN } from "@coral-xyz/anchor";
import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
import { Wallet } from "@coral-xyz/anchor/dist/cjs/provider";
import { TOKEN_PROGRAM_ID } from "@coral-xyz/anchor/dist/cjs/utils/token";
Expand Down Expand Up @@ -54,6 +54,7 @@ import {
getConfigPda,
DEFAULT_RECEIVER_PROGRAM_ID,
} from "@pythnetwork/pyth-solana-receiver";
import { LAZER_PROGRAM_ID, STORAGE_ID } from "@pythnetwork/pyth-lazer-sdk";

import { LedgerNodeWallet } from "./ledger";
import {
Expand Down Expand Up @@ -924,4 +925,55 @@ multisigCommand("execute-add-and-delete", "Execute a roster change proposal")
await vault.squad.executeTransaction(proposal);
});

multisigCommand(
"set-trusted-signer",
"Set a trusted signer for the Lazer program"
)
.requiredOption(
"-s, --signer <pubkey>",
"public key of the trusted signer to add/update"
)
.requiredOption(
"-e, --expiry-time <seconds>",
"expiry time in seconds since Unix epoch. Set to 0 to remove the signer."
)
.action(async (options: any) => {
const vault = await loadVaultFromOptions(options);
const targetCluster: PythCluster = options.cluster;

const trustedSigner = new PublicKey(options.signer);
const expiryTime = new BN(options.expiryTime);

// Create the update instruction
const updateInstruction = new TransactionInstruction({
programId: LAZER_PROGRAM_ID,
keys: [
{
pubkey: await vault.getVaultAuthorityPDA(targetCluster),
isSigner: false,
isWritable: false,
},
{
pubkey: STORAGE_ID,
isSigner: false,
isWritable: true,
},
],
data: Buffer.concat([
// Anchor discriminator for "update"
Buffer.from([219, 200, 88, 176, 158, 63, 253, 127]),
// Trusted signer pubkey
trustedSigner.toBuffer(),
// Expiry time (i64)
Buffer.from(expiryTime.toArray("le", 8)),
]),
});

await vault.proposeInstructions(
[updateInstruction],
targetCluster,
DEFAULT_PRIORITY_FEE_CONFIG
);
});

program.parse();
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"ethers": "^5.7.2",
"lodash": "^4.17.21",
"message_buffer": "workspace:^",
"@pythnetwork/pyth-lazer-sdk": "workspace:*",
"typescript": "^4.9.4"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ import { PublicKey, TransactionInstruction } from "@solana/web3.js";
import { Idl, BorshInstructionCoder } from "@coral-xyz/anchor";
import lazerIdl from "./idl/lazer.json";

export const LAZER_PROGRAM_ID = new PublicKey(
"pytd2yyk641x7ak7mkaasSJVXh6YYZnC7wTmtgAyxPt"
);

export class LazerMultisigInstruction implements MultisigInstruction {
readonly program = MultisigInstructionProgram.Lazer;
readonly name: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@ import {
PRICE_STORE_PROGRAM_ID,
PriceStoreMultisigInstruction,
} from "../price_store";
import {
LazerMultisigInstruction,
LAZER_PROGRAM_ID,
} from "./LazerMultisigInstruction";
import { LazerMultisigInstruction } from "./LazerMultisigInstruction";
import { LAZER_PROGRAM_ID } from "@pythnetwork/pyth-lazer-sdk";

export const UNRECOGNIZED_INSTRUCTION = "unrecognizedInstruction";
export enum MultisigInstructionProgram {
Expand Down
3 changes: 2 additions & 1 deletion lazer/contracts/solana/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"test:anchor": "CARGO_TARGET_DIR=\"$PWD/target\" anchor test",
"test": "pnpm run test:format && pnpm run test:anchor",
"setup": "anchor build && pnpm ts-node scripts/setup.ts",
"migrate_from_0_1_0": "pnpm ts-node scripts/migrate_from_0_1_0.ts"
"migrate_from_0_1_0": "pnpm ts-node scripts/migrate_from_0_1_0.ts",
"check_trusted_signer": "pnpm ts-node scripts/check_trusted_signer.ts"
},
"dependencies": {
"@coral-xyz/anchor": "^0.30.1"
Expand Down
68 changes: 68 additions & 0 deletions lazer/contracts/solana/scripts/check_trusted_signer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import * as anchor from "@coral-xyz/anchor";
import { PythLazerSolanaContract } from "../target/types/pyth_lazer_solana_contract";
import * as pythLazerSolanaContractIdl from "../target/idl/pyth_lazer_solana_contract.json";
import yargs from "yargs/yargs";
import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";

const parser = yargs(process.argv.slice(2)).options({
url: {
type: "string",
demandOption: true,
desc: "RPC URL to use",
},
"storage-id": {
type: "string",
demandOption: true,
desc: "Storage account ID to check",
},
});

async function main() {
const argv = await parser.argv;

// Setup anchor provider
const connection = new anchor.web3.Connection(argv.url);
const provider = new anchor.AnchorProvider(
connection,
new NodeWallet(anchor.web3.Keypair.generate()), // Dummy wallet since we're only reading
{ commitment: "confirmed" }
);
anchor.setProvider(provider);

const program: anchor.Program<PythLazerSolanaContract> = new anchor.Program(
pythLazerSolanaContractIdl as PythLazerSolanaContract,
provider
);

// Fetch and decode storage account
const storageId = new anchor.web3.PublicKey(argv["storage-id"]);
const storage = await program.account.storage.fetch(storageId);

// Print storage info
console.log("Storage Account Info:");
console.log("--------------------");
console.log("Top Authority:", storage.topAuthority.toBase58());
console.log("Treasury:", storage.treasury.toBase58());
console.log("\nTrusted Signers:");
console.log("----------------");

for (const signer of storage.trustedSigners) {
if (signer.pubkey.equals(anchor.web3.PublicKey.default)) continue;
console.log(`\nPublic Key: ${signer.pubkey.toBase58()}`);
console.log(
`Expires At: ${new Date(
signer.expiresAt.toNumber() * 1000
).toISOString()}`
);
console.log(
`Active: ${
signer.expiresAt.toNumber() > Date.now() / 1000 ? "Yes" : "No"
}`
);
}
}

main().catch((err) => {
console.error(err);
process.exit(1);
});
2 changes: 1 addition & 1 deletion lazer/sdk/js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pythnetwork/pyth-lazer-sdk",
"version": "0.2.0",
"version": "0.2.1",
"description": "Pyth Lazer SDK",
"publishConfig": {
"access": "public"
Expand Down
8 changes: 8 additions & 0 deletions lazer/sdk/js/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { PublicKey } from "@solana/web3.js";

export const LAZER_PROGRAM_ID = new PublicKey(
"pytd2yyk641x7ak7mkaasSJVXh6YYZnC7wTmtgAyxPt"
);
export const STORAGE_ID = new PublicKey(
"3rdJbqfnagQ4yx9HXJViD4zc4xpiSqmFsKpPuSCQVyQL"
);
1 change: 1 addition & 0 deletions lazer/sdk/js/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./client.js";
export * from "./protocol.js";
export * from "./ed25519.js";
export * from "./constants.js";
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

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

Loading