Skip to content

Commit 371286d

Browse files
authored
feat: support initializing stake accounts (#1819)
* feat: support initializing stake accounts * cleanup * fix * fix * remove console log * cleanup * fix * simplify * go * fix: add initialize instruction parser
1 parent a36f7ac commit 371286d

File tree

4 files changed

+99
-1
lines changed

4 files changed

+99
-1
lines changed

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

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import {
3535
PROGRAM_AUTHORITY_ESCROW,
3636
getMultisigCluster,
3737
getProposalInstructions,
38+
findDetermisticStakeAccountAddress,
3839
} from "@pythnetwork/xc-admin-common";
3940

4041
import {
@@ -408,6 +409,68 @@ multisigCommand(
408409
);
409410
});
410411

412+
multisigCommand(
413+
"initialize-stake-accounts",
414+
"Initialize stake accounts and assign them to the given vote accounts"
415+
)
416+
.requiredOption(
417+
"-d, --vote-pubkeys <comma_separated_voter_pubkeys>",
418+
"vote account to delegate to"
419+
)
420+
.action(async (options: any) => {
421+
const vault = await loadVaultFromOptions(options);
422+
const cluster: PythCluster = options.cluster;
423+
const authorizedPubkey: PublicKey = await vault.getVaultAuthorityPDA(
424+
cluster
425+
);
426+
427+
const votePubkeys: PublicKey[] = options.votePubkeys
428+
? options.votePubkeys.split(",").map((m: string) => new PublicKey(m))
429+
: [];
430+
431+
const instructions: TransactionInstruction[] = [];
432+
433+
for (const votePubkey of votePubkeys) {
434+
const [stakePubkey, seed] = await findDetermisticStakeAccountAddress(
435+
authorizedPubkey,
436+
votePubkey
437+
);
438+
instructions.push(
439+
SystemProgram.createAccountWithSeed({
440+
basePubkey: authorizedPubkey,
441+
seed: seed,
442+
fromPubkey: authorizedPubkey,
443+
newAccountPubkey: stakePubkey,
444+
lamports: 100000 * LAMPORTS_PER_SOL,
445+
space: StakeProgram.space,
446+
programId: StakeProgram.programId,
447+
})
448+
);
449+
instructions.push(
450+
StakeProgram.initialize({
451+
stakePubkey,
452+
authorized: {
453+
staker: authorizedPubkey,
454+
withdrawer: authorizedPubkey,
455+
},
456+
})
457+
);
458+
instructions.push(
459+
StakeProgram.delegate({
460+
stakePubkey,
461+
authorizedPubkey,
462+
votePubkey,
463+
}).instructions[0]
464+
);
465+
}
466+
467+
await vault.proposeInstructions(
468+
instructions,
469+
cluster,
470+
DEFAULT_PRIORITY_FEE_CONFIG
471+
);
472+
});
473+
411474
multisigCommand(
412475
"init-price",
413476
"Init price (useful for changing the exponent), only to be used on unused price feeds"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { PublicKey, StakeProgram } from "@solana/web3.js";
2+
3+
export async function findDetermisticStakeAccountAddress(
4+
basePubkey: PublicKey,
5+
votePubkey: PublicKey
6+
): Promise<[PublicKey, string]> {
7+
const seed: string = votePubkey.toBuffer().toString("hex").slice(0, 32);
8+
const address: PublicKey = await PublicKey.createWithSeed(
9+
basePubkey,
10+
seed,
11+
StakeProgram.programId
12+
);
13+
return [address, seed];
14+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ export * from "./cranks";
1111
export * from "./message_buffer";
1212
export * from "./executor";
1313
export * from "./chains";
14+
export * from "./deterministic_stake_accounts";

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,29 @@ export class SolanaStakingMultisigInstruction implements MultisigInstruction {
7777
remaining: [],
7878
}
7979
);
80+
case "Initialize":
81+
const decodedInitialize =
82+
StakeInstruction.decodeInitialize(instruction);
83+
return new SolanaStakingMultisigInstruction(
84+
"Initialize",
85+
{
86+
authorized: decodedInitialize.authorized,
87+
lockup: decodedInitialize.lockup,
88+
},
89+
{
90+
named: {
91+
stakePubkey: {
92+
pubkey: decodedInitialize.stakePubkey,
93+
isSigner: false,
94+
isWritable: true,
95+
},
96+
},
97+
remaining: [],
98+
}
99+
);
80100
case "Authorize":
81101
case "AuthorizeWithSeed":
82-
case "Initialize":
102+
83103
case "Merge":
84104
case "Split":
85105
case "Withdraw":

0 commit comments

Comments
 (0)