Skip to content

Commit

Permalink
Add set reward authority cli commands (#502)
Browse files Browse the repository at this point in the history
* use promptText to input priority fee

I could not input 0.000001

* add setRewardEmissionsSuperAuthority

* add SetRewardAuthority

* update README

* fix lint error
  • Loading branch information
yugure-orca authored Nov 15, 2024
1 parent a55346a commit b157b1c
Show file tree
Hide file tree
Showing 4 changed files with 226 additions and 3 deletions.
3 changes: 2 additions & 1 deletion legacy-sdk/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Token-2022 tokens are acceptable 👍
- `yarn start setDefaultProtocolFeeRate`: set new default protocol fee rate on WhirlpoolsConfig
- `yarn start setFeeAuthority`: set new fee authority on WhirlpoolsConfig
- `yarn start setCollectProtocolFeesAuthority`: set new collect protocol fees authority on WhirlpoolsConfig
- TODO: set reward emissions super authority
- `yarn start setRewardEmissionsSuperAuthority`: set new reward emissions super authority on WhirlpoolsConfig
- TODO: set config extension authority

## Whirlpool & TickArray
Expand All @@ -41,6 +41,7 @@ Token-2022 tokens are acceptable 👍
- `yarn start deleteTokenBadge`: delete TokenBadge account

## Reward
- `yarn start setRewardAuthority`: set new reward authority of rewards on a whirlpool
- `yarn start initializeReward`: initialize new reward for a whirlpool
- TODO: set reward emission

Expand Down
116 changes: 116 additions & 0 deletions legacy-sdk/cli/src/commands/set_reward_authority.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { PublicKey } from "@solana/web3.js";
import {
WhirlpoolIx,
} from "@orca-so/whirlpools-sdk";
import { TransactionBuilder } from "@orca-so/common-sdk";
import { sendTransaction } from "../utils/transaction_sender";
import { ctx } from "../utils/provider";
import { promptConfirm, promptText } from "../utils/prompt";

console.info("set RewardAuthority...");

// prompt
const whirlpoolPubkeyStr = await promptText("whirlpoolPubkey");

const whirlpoolPubkey = new PublicKey(whirlpoolPubkeyStr);
const whirlpool = await ctx.fetcher.getPool(whirlpoolPubkey);
if (!whirlpool) {
throw new Error("whirlpool not found");
}

const updatableRewardIndexes: number[] = [];
whirlpool.rewardInfos.forEach((ri, i) => {
const updatable = ri.authority.equals(ctx.wallet.publicKey);
if (updatable) updatableRewardIndexes.push(i);
console.info(`reward[${i}] authority: ${ri.authority.toBase58()} ${updatable ? " (Updatable)" : " (wallet is not authority)"}`);
})

if (updatableRewardIndexes.length === 0) {
throw new Error("This wallet is NOT reward authority for all reward indexes");
}

console.info("\nEnter new reward authority\n* If you don't want to update it, just type SKIP\n");

const newRewardAuthorities: (PublicKey|undefined)[] = [];
for (let i=0; i<updatableRewardIndexes.length; i++) {
const newRewardAuthority = await promptText(`newRewardAuthority for reward[${updatableRewardIndexes[i]}]`);
try {
const newAuthority = new PublicKey(newRewardAuthority);
if (newAuthority.equals(ctx.wallet.publicKey)) {
throw new Error("newAuthority is same to the current authority");
}
newRewardAuthorities.push(newAuthority);
} catch(_e) {
newRewardAuthorities.push(undefined);
}
}

if (newRewardAuthorities.every((a) => a === undefined)) {
throw new Error("No new reward authority");
}

console.info("setting...");
for (let i=0; i<updatableRewardIndexes.length; i++) {
if (newRewardAuthorities[i]) {
console.info(`\treward[${updatableRewardIndexes[i]}] ${whirlpool.rewardInfos[updatableRewardIndexes[i]].authority.toBase58()} -> ${newRewardAuthorities[i]!.toBase58()}`);
} else {
console.info(`\treward[${updatableRewardIndexes[i]}] ${whirlpool.rewardInfos[updatableRewardIndexes[i]].authority.toBase58()} (unchanged)`);
}
}
console.info("\nif the above is OK, enter YES");
const yesno = await promptConfirm("yesno");
if (!yesno) {
throw new Error("stopped");
}

const builder = new TransactionBuilder(ctx.connection, ctx.wallet);
for (let i=0; i<updatableRewardIndexes.length; i++) {
const rewardIndex = updatableRewardIndexes[i];
const newRewardAuthority = newRewardAuthorities[i];
if (newRewardAuthority) {
builder.addInstruction(
WhirlpoolIx.setRewardAuthorityIx(ctx.program, {
whirlpool: whirlpoolPubkey,
rewardIndex,
rewardAuthority: ctx.wallet.publicKey,
newRewardAuthority,
}),
);
}
}

await sendTransaction(builder);

/*
SAMPLE EXECUTION LOG
wallet 3otH3AHWqkqgSVfKFkrxyDqd2vK6LcaqigHrFEmWcGuo
set RewardAuthority...
✔ whirlpoolPubkey … 3KBZiL2g8C7tiJ32hTv5v3KM7aK9htpqTw4cTXz1HvPt
reward[0] authority: 3otH3AHWqkqgSVfKFkrxyDqd2vK6LcaqigHrFEmWcGuo (Updatable)
reward[1] authority: 2v112XbwQXFrdqX438HUrfZF91qCZb7QRP4bwUiN7JF5 (wallet is not authority)
reward[2] authority: 3otH3AHWqkqgSVfKFkrxyDqd2vK6LcaqigHrFEmWcGuo (Updatable)
Enter new reward authority
* If you don't want to update it, just type SKIP
✔ newRewardAuthority for reward[0] … SKIP
✔ newRewardAuthority for reward[2] … 2v112XbwQXFrdqX438HUrfZF91qCZb7QRP4bwUiN7JF5
setting...
reward[0] 3otH3AHWqkqgSVfKFkrxyDqd2vK6LcaqigHrFEmWcGuo (unchanged)
reward[2] 3otH3AHWqkqgSVfKFkrxyDqd2vK6LcaqigHrFEmWcGuo -> 2v112XbwQXFrdqX438HUrfZF91qCZb7QRP4bwUiN7JF5
if the above is OK, enter YES
✔ yesno › Yes
estimatedComputeUnits: 103936
✔ priorityFeeInSOL … 0.000001
Priority fee: 0.000001 SOL
process transaction...
transaction is still valid, 150 blocks left (at most)
sending...
confirming...
✅successfully landed
signature 5iLophVC1xsk2MsCZQ5pW81Pa18ta7pe1FsNHQPUptdRh2kLDTHw54MQNwKd5HbVY9kzqNvEELrN4xB29gUhwAPx
*/
106 changes: 106 additions & 0 deletions legacy-sdk/cli/src/commands/set_reward_emissions_super_authority.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { PublicKey } from "@solana/web3.js";
import { WhirlpoolIx } from "@orca-so/whirlpools-sdk";
import { TransactionBuilder } from "@orca-so/common-sdk";
import { sendTransaction } from "../utils/transaction_sender";
import { ctx } from "../utils/provider";
import { promptConfirm, promptText } from "../utils/prompt";

console.info("set RewardEmissionsSuperAuthority...");

// prompt
const whirlpoolsConfigPubkeyStr = await promptText("whirlpoolsConfigPubkey");
const newRewardEmissionsSuperAuthorityPubkeyStr = await promptText(
"newRewardEmissionsSuperAuthorityPubkey",
);
const newRewardEmissionsSuperAuthorityPubkeyAgainStr = await promptText(
"newRewardEmissionsSuperAuthorityPubkeyAgain",
);

const whirlpoolsConfigPubkey = new PublicKey(whirlpoolsConfigPubkeyStr);
const newRewardEmissionsSuperAuthorityPubkey = new PublicKey(
newRewardEmissionsSuperAuthorityPubkeyStr,
);
const newRewardEmissionsSuperAuthorityPubkeyAgain = new PublicKey(
newRewardEmissionsSuperAuthorityPubkeyAgainStr,
);

if (
!newRewardEmissionsSuperAuthorityPubkey.equals(
newRewardEmissionsSuperAuthorityPubkeyAgain,
)
) {
throw new Error(
"newRewardEmissionsSuperAuthorityPubkey and newRewardEmissionsSuperAuthorityPubkeyAgain must be the same",
);
}

const whirlpoolsConfig = await ctx.fetcher.getConfig(whirlpoolsConfigPubkey);
if (!whirlpoolsConfig) {
throw new Error("whirlpoolsConfig not found");
}

if (
!whirlpoolsConfig.rewardEmissionsSuperAuthority.equals(ctx.wallet.publicKey)
) {
throw new Error(
`the current wallet must be the reward emissions super authority(${whirlpoolsConfig.rewardEmissionsSuperAuthority.toBase58()})`,
);
}

console.info(
"setting...",
"\n\trewardEmissionsSuperAuthority",
whirlpoolsConfig.rewardEmissionsSuperAuthority.toBase58(),
"\n\tnewRewardEmissionsSuperAuthority",
newRewardEmissionsSuperAuthorityPubkey.toBase58(),
);
console.info("\nif the above is OK, enter YES");
console.info(
"\n>>>>> WARNING: authority transfer is highly sensitive operation, please double check new authority address <<<<<\n",
);
const yesno = await promptConfirm("yesno");
if (!yesno) {
throw new Error("stopped");
}

const builder = new TransactionBuilder(ctx.connection, ctx.wallet);
builder.addInstruction(
WhirlpoolIx.setRewardEmissionsSuperAuthorityIx(ctx.program, {
whirlpoolsConfig: whirlpoolsConfigPubkey,
rewardEmissionsSuperAuthority: whirlpoolsConfig.rewardEmissionsSuperAuthority,
newRewardEmissionsSuperAuthority: newRewardEmissionsSuperAuthorityPubkey,
}),
);

await sendTransaction(builder);

/*
SAMPLE EXECUTION LOG
connection endpoint http://localhost:8899
wallet 2v112XbwQXFrdqX438HUrfZF91qCZb7QRP4bwUiN7JF5
set RewardEmissionsSuperAuthority...
✔ whirlpoolsConfigPubkey … FcrweFY1G9HJAHG5inkGB6pKg1HZ6x9UC2WioAfWrGkR
✔ newRewardEmissionsSuperAuthorityPubkey … 3otH3AHWqkqgSVfKFkrxyDqd2vK6LcaqigHrFEmWcGuo
✔ newRewardEmissionsSuperAuthorityPubkeyAgain … 3otH3AHWqkqgSVfKFkrxyDqd2vK6LcaqigHrFEmWcGuo
setting...
rewardEmissionsSuperAuthority 2v112XbwQXFrdqX438HUrfZF91qCZb7QRP4bwUiN7JF5
newRewardEmissionsSuperAuthority 3otH3AHWqkqgSVfKFkrxyDqd2vK6LcaqigHrFEmWcGuo
if the above is OK, enter YES
>>>>> WARNING: authority transfer is highly sensitive operation, please double check new authority address <<<<<
✔ yesno › Yes
estimatedComputeUnits: 102385
✔ priorityFeeInSOL … 0.000002
Priority fee: 0.000002 SOL
process transaction...
transaction is still valid, 150 blocks left (at most)
sending...
confirming...
✅successfully landed
signature 432eMv1tPRN6JU7b7ezFCSU1npEVudkmfXcVsUYEnyGep988oLraMP9cz7nMEcwzhh8xW3YfnHZa4eReHU5tfzfC
*/
4 changes: 2 additions & 2 deletions legacy-sdk/cli/src/utils/transaction_sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from "@orca-so/common-sdk";
import Decimal from "decimal.js";
import base58 from "bs58";
import { promptConfirm, promptNumber } from "./prompt";
import { promptConfirm, promptText } from "./prompt";

export async function sendTransaction(
builder: TransactionBuilder,
Expand All @@ -31,7 +31,7 @@ export async function sendTransaction(
let priorityFeeInLamports = 0;

while (true) {
const priorityFeeInSOL = await promptNumber("priorityFeeInSOL");
const priorityFeeInSOL = await promptText("priorityFeeInSOL");
priorityFeeInLamports = DecimalUtil.toBN(
new Decimal(priorityFeeInSOL),
9,
Expand Down

0 comments on commit b157b1c

Please sign in to comment.