Skip to content

Commit 1153abe

Browse files
authored
[xc-admin] Start cli and add accept transfer for upgrade authorities (#467)
* Checkpoint * Add global options
1 parent 670fc23 commit 1153abe

File tree

4 files changed

+340
-0
lines changed

4 files changed

+340
-0
lines changed

xc-admin/package-lock.json

Lines changed: 197 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "xc-admin-cli",
3+
"version": "0.0.0",
4+
"description": "",
5+
"author": "",
6+
"homepage": "https://github.com/pyth-network/pyth-crosschain",
7+
"license": "ISC",
8+
"main": "src/index.ts",
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/pyth-network/pyth-crosschain.git"
12+
},
13+
"bugs": {
14+
"url": "https://github.com/pyth-network/pyth-crosschain/issues"
15+
},
16+
"scripts": {
17+
"build": "tsc",
18+
"format": "prettier --write \"src/**/*.ts\""
19+
},
20+
"dependencies": {
21+
"@coral-xyz/anchor": "^0.26.0",
22+
"@pythnetwork/client": "^2.9.0",
23+
"@solana/web3.js": "^1.73.0",
24+
"@sqds/mesh": "^1.0.6",
25+
"commander": "^9.5.0",
26+
"typescript": "^4.9.4",
27+
"xc-admin-common": "*"
28+
}
29+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { Keypair, PublicKey } from "@solana/web3.js";
2+
import { program } from "commander";
3+
import { PythCluster } from "@pythnetwork/client/lib/cluster";
4+
import { getPythClusterApiUrl } from "@pythnetwork/client/lib/cluster";
5+
import { AnchorError, AnchorProvider, Program } from "@coral-xyz/anchor";
6+
import fs from "fs";
7+
import SquadsMesh from "@sqds/mesh";
8+
import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
9+
import { proposeInstructions } from "xc-admin-common";
10+
11+
const PROGRAM_AUTHORITY_ESCROW = new PublicKey(
12+
"escMHe7kSqPcDHx4HU44rAHhgdTLBZkUrU39aN8kMcL"
13+
);
14+
const BPF_UPGRADABLE_LOADER = new PublicKey(
15+
"BPFLoaderUpgradeab1e11111111111111111111111"
16+
);
17+
18+
const mutlisigCommand = (name: string, description: string) =>
19+
program
20+
.command(name)
21+
.description(description)
22+
.requiredOption("-c, --cluster <network>", "solana cluster to use")
23+
.requiredOption("-w, --wallet <filepath>", "path to the operations key")
24+
.requiredOption("-v, --vault <pubkey>", "multisig address");
25+
26+
program
27+
.name("xc-admin-cli")
28+
.description("CLI for interacting with Pyth's xc-admin")
29+
.version("0.1.0");
30+
31+
mutlisigCommand(
32+
"accept-authority",
33+
"Accept authority from the program authority escrow"
34+
)
35+
.requiredOption(
36+
"-p, --program-id <pubkey>",
37+
"program whose authority we want to transfer"
38+
)
39+
.requiredOption(
40+
"-a, --current <pubkey>",
41+
"current authority (before the transfer)"
42+
)
43+
44+
.action(async (options: any) => {
45+
const wallet = new NodeWallet(
46+
Keypair.fromSecretKey(
47+
Uint8Array.from(JSON.parse(fs.readFileSync(options.wallet, "ascii")))
48+
)
49+
);
50+
const cluster: PythCluster = options.cluster;
51+
const programId: PublicKey = new PublicKey(options.programId);
52+
const current: PublicKey = new PublicKey(options.current);
53+
const vault: PublicKey = new PublicKey(options.vault);
54+
55+
const squad = SquadsMesh.endpoint(getPythClusterApiUrl(cluster), wallet);
56+
const msAccount = await squad.getMultisig(vault);
57+
const vaultAuthority = squad.getAuthorityPDA(
58+
msAccount.publicKey,
59+
msAccount.authorityIndex
60+
);
61+
62+
const programAuthorityEscrowIdl = await Program.fetchIdl(
63+
PROGRAM_AUTHORITY_ESCROW,
64+
new AnchorProvider(
65+
squad.connection,
66+
squad.wallet,
67+
AnchorProvider.defaultOptions()
68+
)
69+
);
70+
const programAuthorityEscrow = new Program(
71+
programAuthorityEscrowIdl!,
72+
PROGRAM_AUTHORITY_ESCROW,
73+
new AnchorProvider(
74+
squad.connection,
75+
squad.wallet,
76+
AnchorProvider.defaultOptions()
77+
)
78+
);
79+
const programDataAccount = PublicKey.findProgramAddressSync(
80+
[programId.toBuffer()],
81+
BPF_UPGRADABLE_LOADER
82+
)[0];
83+
84+
const proposalInstruction = await programAuthorityEscrow.methods
85+
.accept()
86+
.accounts({
87+
currentAuthority: current,
88+
newAuthority: vaultAuthority,
89+
programAccount: programId,
90+
programDataAccount,
91+
bpfUpgradableLoader: BPF_UPGRADABLE_LOADER,
92+
})
93+
.instruction();
94+
95+
await proposeInstructions(squad, vault, [proposalInstruction], false);
96+
});
97+
98+
program.parse();
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"compilerOptions": {
3+
"declaration": true,
4+
"target": "es2016",
5+
"module": "commonjs",
6+
"outDir": "lib",
7+
"esModuleInterop": true,
8+
"forceConsistentCasingInFileNames": true,
9+
"strict": true,
10+
"skipLibCheck": true,
11+
"resolveJsonModule": true,
12+
"noErrorTruncation": true
13+
},
14+
"include": ["src/**/*.ts"],
15+
"exclude": ["src/__tests__/"]
16+
}

0 commit comments

Comments
 (0)