-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#### Problem The web3.js v1 package is inconsistent with the v2 package. #### Summary of changes A few things: * Rename web3js-1.0 -> js-v1 * Add testing to CI * Format the code * Use eslint correctly * Fix stake account discriminants
- Loading branch information
Showing
17 changed files
with
517 additions
and
157 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { Connection, PublicKey } from '@solana/web3.js'; | ||
import { getStakeAccount, getStakeHistory } from './stake'; | ||
import { getStakeActivatingAndDeactivating } from './delegation'; | ||
|
||
export interface StakeActivation { | ||
status: string; | ||
active: bigint; | ||
inactive: bigint; | ||
} | ||
|
||
export async function getStakeActivation( | ||
connection: Connection, | ||
stakeAddress: PublicKey | ||
): Promise<StakeActivation> { | ||
const SYSVAR_STAKE_HISTORY_ADDRESS = new PublicKey( | ||
'SysvarStakeHistory1111111111111111111111111' | ||
); | ||
const [epochInfo, { stakeAccount, stakeAccountLamports }, stakeHistory] = | ||
await Promise.all([ | ||
connection.getEpochInfo(), | ||
(async () => { | ||
const stakeAccountParsed = | ||
await connection.getParsedAccountInfo(stakeAddress); | ||
if (stakeAccountParsed === null || stakeAccountParsed.value === null) { | ||
throw new Error('Account not found'); | ||
} | ||
const stakeAccount = getStakeAccount(stakeAccountParsed); | ||
const stakeAccountLamports = stakeAccountParsed.value.lamports; | ||
return { stakeAccount, stakeAccountLamports }; | ||
})(), | ||
(async () => { | ||
const stakeHistoryParsed = await connection.getParsedAccountInfo( | ||
SYSVAR_STAKE_HISTORY_ADDRESS | ||
); | ||
if (stakeHistoryParsed === null) { | ||
throw new Error('StakeHistory not found'); | ||
} | ||
return getStakeHistory(stakeHistoryParsed); | ||
})(), | ||
]); | ||
|
||
const { effective, activating, deactivating } = stakeAccount.stake | ||
? getStakeActivatingAndDeactivating( | ||
stakeAccount.stake.delegation, | ||
BigInt(epochInfo.epoch), | ||
stakeHistory | ||
) | ||
: { | ||
effective: BigInt(0), | ||
activating: BigInt(0), | ||
deactivating: BigInt(0), | ||
}; | ||
|
||
let status; | ||
if (deactivating > 0) { | ||
status = 'deactivating'; | ||
} else if (activating > 0) { | ||
status = 'activating'; | ||
} else if (effective > 0) { | ||
status = 'active'; | ||
} else { | ||
status = 'inactive'; | ||
} | ||
const inactive = | ||
BigInt(stakeAccountLamports) - | ||
effective - | ||
stakeAccount.meta.rentExemptReserve; | ||
|
||
return { | ||
status, | ||
active: effective, | ||
inactive, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import { | ||
AccountInfo, | ||
ParsedAccountData, | ||
RpcResponseAndContext, | ||
} from '@solana/web3.js'; | ||
|
||
export type StakeHistoryEntry = { | ||
epoch: bigint; | ||
effective: bigint; | ||
activating: bigint; | ||
deactivating: bigint; | ||
}; | ||
|
||
export type Delegation = { | ||
voterPubkey: Uint8Array; | ||
stake: bigint; | ||
activationEpoch: bigint; | ||
deactivationEpoch: bigint; | ||
}; | ||
|
||
export type StakeAccount = { | ||
discriminant: bigint; | ||
meta: { | ||
rentExemptReserve: bigint; | ||
authorized: { | ||
staker: Uint8Array; | ||
withdrawer: Uint8Array; | ||
}; | ||
lockup: { | ||
unixTimestamp: bigint; | ||
epoch: bigint; | ||
custodian: Uint8Array; | ||
}; | ||
}; | ||
stake: { | ||
delegation: Delegation; | ||
creditsObserved: bigint; | ||
} | null; | ||
}; | ||
|
||
type StakeHistoryEntryRaw = { | ||
epoch: number; | ||
stakeHistory: { | ||
effective: number; | ||
activating: number; | ||
deactivating: number; | ||
}; | ||
}; | ||
|
||
export const getStakeHistory = function ( | ||
parsedData: RpcResponseAndContext<AccountInfo< | ||
ParsedAccountData | Buffer | ||
> | null> | ||
): StakeHistoryEntry[] { | ||
if (parsedData.value === null || parsedData.value.data instanceof Buffer) { | ||
throw new Error('Account not found'); | ||
} | ||
|
||
const stakeHistory: StakeHistoryEntry[] = []; | ||
|
||
parsedData.value.data.parsed.info.forEach((entry: StakeHistoryEntryRaw) => { | ||
stakeHistory.push({ | ||
epoch: BigInt(entry.epoch), | ||
effective: BigInt(entry.stakeHistory.effective), | ||
activating: BigInt(entry.stakeHistory.activating), | ||
deactivating: BigInt(entry.stakeHistory.deactivating), | ||
}); | ||
}); | ||
|
||
return stakeHistory; | ||
}; | ||
|
||
export const getStakeAccount = function ( | ||
parsedData: RpcResponseAndContext<AccountInfo< | ||
ParsedAccountData | Buffer | ||
> | null> | ||
): StakeAccount { | ||
if (parsedData.value === null || parsedData.value.data instanceof Buffer) { | ||
throw new Error('Account not found'); | ||
} | ||
|
||
let discriminant = BigInt(0); | ||
if (parsedData.value.data.parsed.type === 'initialized') { | ||
discriminant = BigInt(1); | ||
} else if (parsedData.value.data.parsed.type === 'delegated') { | ||
discriminant = BigInt(2); | ||
} | ||
|
||
return { | ||
discriminant: discriminant, | ||
meta: { | ||
rentExemptReserve: BigInt( | ||
parsedData.value.data.parsed.info.meta.rentExemptReserve | ||
), | ||
authorized: { | ||
staker: parsedData.value.data.parsed.info.meta.authorized.staker, | ||
withdrawer: | ||
parsedData.value.data.parsed.info.meta.authorized.withdrawer, | ||
}, | ||
lockup: { | ||
unixTimestamp: BigInt( | ||
parsedData.value.data.parsed.info.meta.lockup.unixTimestamp | ||
), | ||
epoch: BigInt(parsedData.value.data.parsed.info.meta.lockup.epoch), | ||
custodian: parsedData.value.data.parsed.info.meta.lockup.custodian, | ||
}, | ||
}, | ||
stake: parsedData.value.data.parsed.info.stake | ||
? { | ||
delegation: { | ||
voterPubkey: | ||
parsedData.value.data.parsed.info.stake.delegation.voterPubkey, | ||
stake: BigInt( | ||
parsedData.value.data.parsed.info.stake.delegation.stake | ||
), | ||
activationEpoch: BigInt( | ||
parsedData.value.data.parsed.info.stake.delegation.activationEpoch | ||
), | ||
deactivationEpoch: BigInt( | ||
parsedData.value.data.parsed.info.stake.delegation | ||
.deactivationEpoch | ||
), | ||
}, | ||
creditsObserved: BigInt( | ||
parsedData.value.data.parsed.info.stake.creditsObserved | ||
), | ||
} | ||
: null, | ||
}; | ||
}; |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.