-
Notifications
You must be signed in to change notification settings - Fork 302
feat(staking): add governance ui methods #1937
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
e54024f
a89a66c
52ebb6c
5e71829
a0e3849
fbf8a2d
f0f03d1
e1f6410
0c2c569
da1f031
a01e265
83a12fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,20 +21,27 @@ import { | |
| TransactionInstruction, | ||
| } from "@solana/web3.js"; | ||
|
|
||
| import { GOVERNANCE_ADDRESS, POSITIONS_ACCOUNT_SIZE } from "./constants"; | ||
| import { | ||
| GOVERNANCE_ADDRESS, | ||
| MAX_VOTER_WEIGHT, | ||
| POSITIONS_ACCOUNT_SIZE, | ||
| } from "./constants"; | ||
| import { | ||
| getConfigAddress, | ||
| getDelegationRecordAddress, | ||
| getPoolConfigAddress, | ||
| getStakeAccountCustodyAddress, | ||
| getStakeAccountMetadataAddress, | ||
| getTargetAccountAddress, | ||
| } from "./pdas"; | ||
| import { | ||
| PositionState, | ||
| type GlobalConfig, | ||
| type PoolConfig, | ||
| type PoolDataAccount, | ||
| type StakeAccountPositions, | ||
| type TargetAccount, | ||
| type VoterWeightAction, | ||
| } from "./types"; | ||
| import { convertBigIntToBN, convertBNToBigInt } from "./utils/bn"; | ||
| import { epochToDate, getCurrentEpoch } from "./utils/clock"; | ||
|
|
@@ -687,4 +694,112 @@ export class PythStakingClient { | |
| undefined, | ||
| ); | ||
| } | ||
|
|
||
| public async getTargetAccount(): Promise<TargetAccount> { | ||
| const targetAccount = | ||
| await this.stakingProgram.account.targetMetadata.fetch( | ||
| getTargetAccountAddress(), | ||
| ); | ||
| return convertBNToBigInt(targetAccount); | ||
| } | ||
|
|
||
| /** | ||
| * This returns the current scaling factor between staked tokens and realms voter weight. | ||
| * The formula is n_staked_tokens = scaling_factor * n_voter_weight | ||
| */ | ||
| public async getScalingFactor(): Promise<number> { | ||
| const targetAccount = await this.getTargetAccount(); | ||
| return Number(targetAccount.locked) / MAX_VOTER_WEIGHT; | ||
| } | ||
|
|
||
| public async getRecoverAccountInstruction( | ||
| stakeAccountPositions: PublicKey, | ||
| governanceAuthority: PublicKey, | ||
| ): Promise<TransactionInstruction> { | ||
| return this.stakingProgram.methods | ||
| .recoverAccount() | ||
| .accountsPartial({ | ||
| stakeAccountPositions, | ||
| governanceAuthority, | ||
| }) | ||
| .instruction(); | ||
| } | ||
|
|
||
| public async getUpdatePoolAuthorityInstruction( | ||
| governanceAuthority: PublicKey, | ||
| poolAuthority: PublicKey, | ||
| ): Promise<TransactionInstruction> { | ||
| return this.stakingProgram.methods | ||
| .updatePoolAuthority(poolAuthority) | ||
| .accounts({ | ||
| governanceAuthority, | ||
keyvankhademi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }) | ||
| .instruction(); | ||
| } | ||
|
|
||
| public async getUpdateVoterWeightInstruction( | ||
| stakeAccountPositions: PublicKey, | ||
| action: VoterWeightAction, | ||
| remainingAccount?: PublicKey, | ||
| ) { | ||
| return this.stakingProgram.methods | ||
| .updateVoterWeight(action) | ||
| .accounts({ | ||
| stakeAccountPositions, | ||
| }) | ||
| .remainingAccounts( | ||
| remainingAccount | ||
| ? [ | ||
| { | ||
| pubkey: remainingAccount, | ||
| isWritable: false, | ||
| isSigner: false, | ||
| }, | ||
| ] | ||
| : [], | ||
| ) | ||
| .instruction(); | ||
| } | ||
|
|
||
| public async getMainStakeAccount() { | ||
| const stakeAccountPositions = await this.getAllStakeAccountPositions(); | ||
| const stakeAccountBalances = await Promise.all( | ||
| stakeAccountPositions.map(async (position) => { | ||
| const stakeAccountCustody = await this.getStakeAccountCustody(position); | ||
| return { | ||
| stakeAccountPosition: position, | ||
| balance: stakeAccountCustody.amount, | ||
| }; | ||
| }), | ||
| ); | ||
|
|
||
| let mainAccount = stakeAccountBalances[0]; | ||
|
|
||
| if (mainAccount === undefined) { | ||
| return; | ||
| } | ||
|
|
||
| for (let i = 1; i < stakeAccountBalances.length; i++) { | ||
| const currentAccount = stakeAccountBalances[i]; | ||
| if ( | ||
| currentAccount !== undefined && | ||
| currentAccount.balance > mainAccount.balance | ||
|
||
| ) { | ||
| mainAccount = currentAccount; | ||
| } | ||
| } | ||
|
|
||
| return mainAccount; | ||
| } | ||
|
|
||
| public async getVoterWeight() { | ||
| const mainAccount = await this.getMainStakeAccount(); | ||
|
|
||
| if (mainAccount === undefined) { | ||
| return 0; | ||
| } | ||
|
|
||
| const scalingFactor = await this.getScalingFactor(); | ||
| return Number(mainAccount.balance) / scalingFactor; | ||
|
||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: this is only valid if someone has cranked the target account (happens whenever someone stakes to unstakes, or whenever someome slashes). I generally think this approach seems fine