Skip to content

Commit 20d99bc

Browse files
authored
feat: enable remote stake delegation (#1501)
* feat: enable remote stake delegation * Cleanup space * Go * feat: drive-by priority fees * fix: pr comments * fix: pr comments
1 parent d2ce2ec commit 20d99bc

File tree

2 files changed

+115
-16
lines changed

2 files changed

+115
-16
lines changed

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

Lines changed: 85 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
} from "@pythnetwork/pyth-solana-receiver";
4545

4646
import { LedgerNodeWallet } from "./ledger";
47+
import { DEFAULT_PRIORITY_FEE_CONFIG } from "@pythnetwork/solana-utils";
4748

4849
export async function loadHotWalletOrLedger(
4950
wallet: string,
@@ -74,7 +75,7 @@ async function loadVaultFromOptions(options: any): Promise<MultisigVault> {
7475
const vault: PublicKey = new PublicKey(options.vault);
7576

7677
const squad = SquadsMesh.endpoint(
77-
getPythClusterApiUrl(multisigCluster),
78+
options.rpcUrlOverride ?? getPythClusterApiUrl(multisigCluster),
7879
wallet
7980
);
8081

@@ -101,6 +102,10 @@ const multisigCommand = (name: string, description: string) =>
101102
.option(
102103
"-ldc, --ledger-derivation-change <number>",
103104
"ledger derivation change to use"
105+
)
106+
.option(
107+
"-u, --rpc-url-override <string>",
108+
"RPC URL to override the default for the cluster. Make sure this is an RPC URL of the cluster where the multisig lives. For Pythnet proposals it should be a Solana Mainnet RPC URL."
104109
);
105110

106111
program
@@ -154,7 +159,11 @@ multisigCommand(
154159
})
155160
.instruction();
156161

157-
await vault.proposeInstructions([proposalInstruction], targetCluster);
162+
await vault.proposeInstructions(
163+
[proposalInstruction],
164+
targetCluster,
165+
DEFAULT_PRIORITY_FEE_CONFIG
166+
);
158167
});
159168

160169
multisigCommand(
@@ -178,7 +187,11 @@ multisigCommand(
178187
})
179188
.instruction();
180189

181-
await vault.proposeInstructions([proposalInstruction], targetCluster);
190+
await vault.proposeInstructions(
191+
[proposalInstruction],
192+
targetCluster,
193+
DEFAULT_PRIORITY_FEE_CONFIG
194+
);
182195
});
183196

184197
multisigCommand(
@@ -209,7 +222,11 @@ multisigCommand(
209222
})
210223
.instruction();
211224

212-
await vault.proposeInstructions([proposalInstruction], targetCluster);
225+
await vault.proposeInstructions(
226+
[proposalInstruction],
227+
targetCluster,
228+
DEFAULT_PRIORITY_FEE_CONFIG
229+
);
213230
});
214231

215232
multisigCommand("upgrade-program", "Upgrade a program from a buffer")
@@ -250,7 +267,11 @@ multisigCommand("upgrade-program", "Upgrade a program from a buffer")
250267
],
251268
};
252269

253-
await vault.proposeInstructions([proposalInstruction], cluster);
270+
await vault.proposeInstructions(
271+
[proposalInstruction],
272+
cluster,
273+
DEFAULT_PRIORITY_FEE_CONFIG
274+
);
254275
});
255276

256277
multisigCommand(
@@ -286,7 +307,11 @@ multisigCommand(
286307
],
287308
};
288309

289-
await vault.proposeInstructions([proposalInstruction], cluster);
310+
await vault.proposeInstructions(
311+
[proposalInstruction],
312+
cluster,
313+
DEFAULT_PRIORITY_FEE_CONFIG
314+
);
290315
});
291316

292317
multisigCommand(
@@ -315,7 +340,40 @@ multisigCommand(
315340
[]
316341
);
317342

318-
await vault.proposeInstructions(instructions, cluster);
343+
await vault.proposeInstructions(
344+
instructions,
345+
cluster,
346+
DEFAULT_PRIORITY_FEE_CONFIG
347+
);
348+
});
349+
350+
multisigCommand(
351+
"delegate-stake",
352+
"Delegate a stake account to the given vote account"
353+
)
354+
.requiredOption("-s, --stake-account <pubkey>", "stake account to delegate")
355+
.requiredOption("-d, --vote-account <pubkey>", "vote account to delegate to")
356+
.action(async (options: any) => {
357+
const vault = await loadVaultFromOptions(options);
358+
const cluster: PythCluster = options.cluster;
359+
const authorizedPubkey: PublicKey = await vault.getVaultAuthorityPDA(
360+
cluster
361+
);
362+
363+
const stakeAccount: PublicKey = new PublicKey(options.stakeAccount);
364+
const voteAccount: PublicKey = new PublicKey(options.voteAccount);
365+
366+
const instructions = StakeProgram.delegate({
367+
stakePubkey: stakeAccount,
368+
authorizedPubkey,
369+
votePubkey: voteAccount,
370+
}).instructions;
371+
372+
await vault.proposeInstructions(
373+
instructions,
374+
cluster,
375+
DEFAULT_PRIORITY_FEE_CONFIG
376+
);
319377
});
320378

321379
multisigCommand(
@@ -340,7 +398,11 @@ multisigCommand(
340398
priceAccount,
341399
})
342400
.instruction();
343-
await vault.proposeInstructions([proposalInstruction], cluster);
401+
await vault.proposeInstructions(
402+
[proposalInstruction],
403+
cluster,
404+
DEFAULT_PRIORITY_FEE_CONFIG
405+
);
344406
});
345407

346408
program
@@ -431,7 +493,11 @@ multisigCommand("propose-token-transfer", "Propose token transfer")
431493
BigInt(amount) * BigInt(10) ** BigInt(mintAccount.decimals)
432494
);
433495

434-
await vault.proposeInstructions([proposalInstruction], cluster);
496+
await vault.proposeInstructions(
497+
[proposalInstruction],
498+
cluster,
499+
DEFAULT_PRIORITY_FEE_CONFIG
500+
);
435501
});
436502

437503
multisigCommand("propose-sol-transfer", "Propose sol transfer")
@@ -450,7 +516,11 @@ multisigCommand("propose-sol-transfer", "Propose sol transfer")
450516
lamports: amount * LAMPORTS_PER_SOL,
451517
});
452518

453-
await vault.proposeInstructions([proposalInstruction], cluster);
519+
await vault.proposeInstructions(
520+
[proposalInstruction],
521+
cluster,
522+
DEFAULT_PRIORITY_FEE_CONFIG
523+
);
454524
});
455525

456526
multisigCommand("propose-arbitrary-payload", "Propose arbitrary payload")
@@ -524,7 +594,11 @@ multisigCommand("add-and-delete", "Change the roster of the multisig")
524594
}
525595
}
526596

527-
vault.proposeInstructions(proposalInstructions, options.cluster);
597+
vault.proposeInstructions(
598+
proposalInstructions,
599+
options.cluster,
600+
DEFAULT_PRIORITY_FEE_CONFIG
601+
);
528602
});
529603

530604
/**

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

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,30 +30,55 @@ export class SolanaStakingMultisigInstruction implements MultisigInstruction {
3030
const type = StakeInstruction.decodeInstructionType(instruction);
3131
switch (type) {
3232
case "Deactivate":
33-
const decoded = StakeInstruction.decodeDeactivate(instruction);
33+
const decodedDeactivate =
34+
StakeInstruction.decodeDeactivate(instruction);
3435
return new SolanaStakingMultisigInstruction(
3536
"Deactivate",
3637
{},
3738
{
3839
named: {
3940
stakePubkey: {
40-
pubkey: decoded.stakePubkey,
41+
pubkey: decodedDeactivate.stakePubkey,
4142
isSigner: false,
4243
isWritable: true,
4344
},
4445
authorizedPubkey: {
45-
pubkey: decoded.authorizedPubkey,
46+
pubkey: decodedDeactivate.authorizedPubkey,
47+
isSigner: true,
48+
isWritable: false,
49+
},
50+
},
51+
remaining: [],
52+
}
53+
);
54+
case "Delegate":
55+
const decodedDelegate = StakeInstruction.decodeDelegate(instruction);
56+
return new SolanaStakingMultisigInstruction(
57+
"Delegate",
58+
{},
59+
{
60+
named: {
61+
stakePubkey: {
62+
pubkey: decodedDelegate.stakePubkey,
63+
isSigner: false,
64+
isWritable: true,
65+
},
66+
votePubkey: {
67+
pubkey: decodedDelegate.votePubkey,
68+
isSigner: false,
69+
isWritable: false,
70+
},
71+
authorizedPubkey: {
72+
pubkey: decodedDelegate.authorizedPubkey,
4673
isSigner: true,
4774
isWritable: false,
4875
},
4976
},
5077
remaining: [],
5178
}
5279
);
53-
5480
case "Authorize":
5581
case "AuthorizeWithSeed":
56-
case "Delegate":
5782
case "Initialize":
5883
case "Merge":
5984
case "Split":

0 commit comments

Comments
 (0)