Skip to content

Commit ab7560a

Browse files
authored
feat(governance/xc_admin): add initial support for solana receiver (#1365)
* feat(governance/xc_admin): add initial support for solana receiver This change adds Solana Receiver IDL to xc-admin to support parsing them in the xc-admin Frontend. Also adds two CLI commands to request and accept governance authority transfer. * chore: address comments * chore: bump version
1 parent a40de24 commit ab7560a

File tree

8 files changed

+108
-17
lines changed

8 files changed

+108
-17
lines changed

governance/xc_admin/packages/xc_admin_cli/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"@sqds/mesh": "^1.0.6",
2929
"commander": "^9.5.0",
3030
"typescript": "^4.9.4",
31-
"xc_admin_common": "*"
31+
"xc_admin_common": "*",
32+
"@pythnetwork/pyth-solana-receiver": "*"
3233
}
3334
}

governance/xc_admin/packages/xc_admin_cli/src/index.ts

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ import {
3636
getMultisigCluster,
3737
getProposalInstructions,
3838
} from "xc_admin_common";
39+
40+
import {
41+
pythSolanaReceiverIdl,
42+
getConfigPda,
43+
DEFAULT_RECEIVER_PROGRAM_ID,
44+
} from "@pythnetwork/pyth-solana-receiver";
45+
3946
import { LedgerNodeWallet } from "./ledger";
4047

4148
export async function loadHotWalletOrLedger(
@@ -102,7 +109,7 @@ program
102109
.version("0.1.0");
103110

104111
multisigCommand(
105-
"accept-authority",
112+
"escrow-program-accept-authority",
106113
"Accept authority from the program authority escrow"
107114
)
108115
.requiredOption(
@@ -150,6 +157,61 @@ multisigCommand(
150157
await vault.proposeInstructions([proposalInstruction], targetCluster);
151158
});
152159

160+
multisigCommand(
161+
"solana-receiver-program-accept-governance-authority-transfer",
162+
"Accept governance authority transfer for the solana receiver program"
163+
).action(async (options: any) => {
164+
const vault = await loadVaultFromOptions(options);
165+
const targetCluster: PythCluster = options.cluster;
166+
167+
const programSolanaReceiver = new Program(
168+
pythSolanaReceiverIdl,
169+
DEFAULT_RECEIVER_PROGRAM_ID,
170+
vault.getAnchorProvider()
171+
);
172+
173+
const proposalInstruction = await programSolanaReceiver.methods
174+
.acceptGovernanceAuthorityTransfer()
175+
.accounts({
176+
payer: await vault.getVaultAuthorityPDA(targetCluster),
177+
config: getConfigPda(DEFAULT_RECEIVER_PROGRAM_ID),
178+
})
179+
.instruction();
180+
181+
await vault.proposeInstructions([proposalInstruction], targetCluster);
182+
});
183+
184+
multisigCommand(
185+
"solana-receiver-program-request-governance-authority-transfer",
186+
"Request governance authority transfer for the solana receiver program"
187+
)
188+
.requiredOption(
189+
"-t, --target <pubkey>",
190+
"The new governance authority to take over. " +
191+
"If the target is another multisig, it will be the multisig's vault authority PDA."
192+
)
193+
.action(async (options: any) => {
194+
const vault = await loadVaultFromOptions(options);
195+
const targetCluster: PythCluster = options.cluster;
196+
const target: PublicKey = new PublicKey(options.target);
197+
198+
const programSolanaReceiver = new Program(
199+
pythSolanaReceiverIdl,
200+
DEFAULT_RECEIVER_PROGRAM_ID,
201+
vault.getAnchorProvider()
202+
);
203+
204+
const proposalInstruction = await programSolanaReceiver.methods
205+
.requestGovernanceAuthorityTransfer(target)
206+
.accounts({
207+
payer: await vault.getVaultAuthorityPDA(targetCluster),
208+
config: getConfigPda(DEFAULT_RECEIVER_PROGRAM_ID),
209+
})
210+
.instruction();
211+
212+
await vault.proposeInstructions([proposalInstruction], targetCluster);
213+
});
214+
153215
multisigCommand("upgrade-program", "Upgrade a program from a buffer")
154216
.requiredOption(
155217
"-p, --program-id <pubkey>",

governance/xc_admin/packages/xc_admin_common/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
"ethers": "^5.7.2",
3131
"lodash": "^4.17.21",
3232
"typescript": "^4.9.4",
33-
"@pythnetwork/solana-utils": "*"
33+
"@pythnetwork/solana-utils": "*",
34+
"@pythnetwork/pyth-solana-receiver": "*"
3435
},
3536
"devDependencies": {
3637
"@types/bn.js": "^5.1.1",

governance/xc_admin/packages/xc_admin_common/src/multisig_transaction/MessageBufferMultisigInstruction.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ import { Idl, BorshCoder } from "@coral-xyz/anchor";
1111
import { MESSAGE_BUFFER_PROGRAM_ID } from "../message_buffer";
1212
import meshIdl from "@sqds/mesh/lib/mesh-idl/mesh.json";
1313
import stakingIdl from "./idl/staking.json";
14+
import {
15+
DEFAULT_RECEIVER_PROGRAM_ID,
16+
pythSolanaReceiverIdl,
17+
} from "@pythnetwork/pyth-solana-receiver";
1418

1519
export const MESH_PROGRAM_ID = new PublicKey(
1620
"SMPLVC8MxZ5Bf5EfF7PaMiTCxoBAcmkbM2vkrvMK8ho"
@@ -55,6 +59,10 @@ export class AnchorMultisigInstruction implements MultisigInstruction {
5559
idl = stakingIdl as Idl;
5660
program = MultisigInstructionProgram.Staking;
5761
break;
62+
case DEFAULT_RECEIVER_PROGRAM_ID.toBase58():
63+
idl = pythSolanaReceiverIdl as Idl;
64+
program = MultisigInstructionProgram.SolanaReceiver;
65+
break;
5866
default:
5967
return UnrecognizedProgram.fromTransactionInstruction(instruction);
6068
}

governance/xc_admin/packages/xc_admin_common/src/multisig_transaction/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { BpfUpgradableLoaderInstruction } from "./BpfUpgradableLoaderMultisigIns
2222
import { BPF_UPGRADABLE_LOADER } from "../bpf_upgradable_loader";
2323
import { AnchorAccounts } from "./anchor";
2424
import { SolanaStakingMultisigInstruction } from "./SolanaStakingMultisigInstruction";
25+
import { DEFAULT_RECEIVER_PROGRAM_ID } from "@pythnetwork/pyth-solana-receiver";
2526

2627
export const UNRECOGNIZED_INSTRUCTION = "unrecognizedInstruction";
2728
export enum MultisigInstructionProgram {
@@ -33,6 +34,7 @@ export enum MultisigInstructionProgram {
3334
SystemProgram,
3435
BpfUpgradableLoader,
3536
SolanaStakingProgram,
37+
SolanaReceiver,
3638
UnrecognizedProgram,
3739
}
3840

@@ -54,6 +56,8 @@ export function getProgramName(program: MultisigInstructionProgram) {
5456
return "Mesh Multisig Program";
5557
case MultisigInstructionProgram.Staking:
5658
return "Pyth Staking Program";
59+
case MultisigInstructionProgram.SolanaReceiver:
60+
return "Pyth Solana Receiver";
5761
case MultisigInstructionProgram.UnrecognizedProgram:
5862
return "Unknown";
5963
}
@@ -123,7 +127,8 @@ export class MultisigParser {
123127
} else if (
124128
instruction.programId.equals(MESSAGE_BUFFER_PROGRAM_ID) ||
125129
instruction.programId.equals(MESH_PROGRAM_ID) ||
126-
instruction.programId.equals(STAKING_PROGRAM_ID)
130+
instruction.programId.equals(STAKING_PROGRAM_ID) ||
131+
instruction.programId.equals(DEFAULT_RECEIVER_PROGRAM_ID)
127132
) {
128133
return AnchorMultisigInstruction.fromTransactionInstruction(instruction);
129134
} else if (instruction.programId.equals(SystemProgram.programId)) {

package-lock.json

Lines changed: 10 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

target_chains/solana/sdk/js/pyth_solana_receiver/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pythnetwork/pyth-solana-receiver",
3-
"version": "0.2.2",
3+
"version": "0.2.3",
44
"description": "Pyth solana receiver SDK",
55
"homepage": "https://pyth.network",
66
"main": "lib/index.js",

target_chains/solana/sdk/js/pyth_solana_receiver/src/index.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,19 @@ export {
66
TransactionBuilder,
77
InstructionWithEphemeralSigners,
88
} from "@pythnetwork/solana-utils";
9+
10+
export {
11+
getConfigPda,
12+
DEFAULT_RECEIVER_PROGRAM_ID,
13+
DEFAULT_WORMHOLE_PROGRAM_ID,
14+
} from "./address";
15+
16+
export {
17+
IDL as pythSolanaReceiverIdl,
18+
PythSolanaReceiver as PythSolanaReceiverProgram,
19+
} from "./idl/pyth_solana_receiver";
20+
21+
export {
22+
IDL as wormholeCoreBridgeIdl,
23+
WormholeCoreBridgeSolana as WormholeCoreBridgeProgram,
24+
} from "./idl/wormhole_core_bridge_solana";

0 commit comments

Comments
 (0)