fix: query pezRewards and stakingScore from People Chain

- pezRewards pallet is on People Chain, not Relay Chain
- stakingScore pallet is also on People Chain
- Update getStakingInfo to accept optional peopleApi parameter
- Update StakingDashboard to pass peopleApi
This commit is contained in:
2026-02-06 21:28:56 +03:00
parent 61eb5cff20
commit 6b26f434dd
2 changed files with 29 additions and 22 deletions
+21 -14
View File
@@ -189,20 +189,21 @@ export async function getBlocksUntilEra(
/**
* Get PEZ rewards information for an account
* Note: pezRewards pallet is on People Chain, not Relay Chain
*/
export async function getPezRewards(
api: ApiPromise,
peopleApi: ApiPromise,
address: string
): Promise<PezRewardInfo | null> {
try {
// Check if pezRewards pallet exists
if (!api.query.pezRewards || !api.query.pezRewards.epochInfo) {
console.warn('PezRewards pallet not available');
// Check if pezRewards pallet exists on People Chain
if (!peopleApi?.query?.pezRewards || !peopleApi.query.pezRewards.epochInfo) {
console.warn('PezRewards pallet not available on People Chain');
return null;
}
// Get current epoch info
const epochInfoResult = await api.query.pezRewards.epochInfo();
const epochInfoResult = await peopleApi.query.pezRewards.epochInfo();
if (!epochInfoResult) {
console.warn('No epoch info found');
@@ -221,15 +222,15 @@ export async function getPezRewards(
for (let i = Math.max(0, currentEpoch - 3); i < currentEpoch; i++) {
try {
// Check if user has claimed this epoch already
const claimedResult = await api.query.pezRewards.claimedRewards(i, address);
const claimedResult = await peopleApi.query.pezRewards.claimedRewards(i, address);
if (claimedResult.isNone) {
// User hasn't claimed - check if they have rewards
const userScoreResult = await api.query.pezRewards.userEpochScores(i, address);
const userScoreResult = await peopleApi.query.pezRewards.userEpochScores(i, address);
if (userScoreResult.isSome) {
// User has a score for this epoch - calculate their reward
const epochPoolResult = await api.query.pezRewards.epochRewardPools(i);
const epochPoolResult = await peopleApi.query.pezRewards.epochRewardPools(i);
if (epochPoolResult.isSome) {
const epochPoolCodec = epochPoolResult.unwrap() as { toJSON: () => unknown };
@@ -272,10 +273,14 @@ export async function getPezRewards(
/**
* Get comprehensive staking info for an account
* @param api - Relay Chain API (for staking pallet)
* @param address - User address
* @param peopleApi - Optional People Chain API (for pezRewards and stakingScore pallets)
*/
export async function getStakingInfo(
api: ApiPromise,
address: string
address: string,
peopleApi?: ApiPromise
): Promise<StakingInfo> {
const ledger = await getStakingLedger(api, address);
const nominations = await getNominations(api, address);
@@ -324,15 +329,17 @@ export async function getStakingInfo(
let hasStartedScoreTracking = false;
try {
if (api.query.stakingScore && api.query.stakingScore.stakingStartBlock) {
// stakingScore pallet is on People Chain
const scoreApi = peopleApi || api;
if (scoreApi.query.stakingScore && scoreApi.query.stakingScore.stakingStartBlock) {
// Check if user has started score tracking
const scoreResult = await api.query.stakingScore.stakingStartBlock(address);
const scoreResult = await scoreApi.query.stakingScore.stakingStartBlock(address);
if (scoreResult.isSome) {
hasStartedScoreTracking = true;
const startBlockCodec = scoreResult.unwrap() as { toString: () => string };
const startBlock = Number(startBlockCodec.toString());
const currentBlock = Number((await api.query.system.number()).toString());
const currentBlock = Number((await scoreApi.query.system.number()).toString());
const durationInBlocks = currentBlock - startBlock;
stakingDuration = durationInBlocks;
@@ -387,8 +394,8 @@ export async function getStakingInfo(
const validatorsOption = await api.query.staking.validators(address);
const isValidator = validatorsOption.isSome;
// Get PEZ rewards information
const pezRewards = await getPezRewards(api, address);
// Get PEZ rewards information (from People Chain)
const pezRewards = peopleApi ? await getPezRewards(peopleApi, address) : null;
return {
bonded: ledger ? formatBalance(ledger.total) : '0',
@@ -25,7 +25,7 @@ import { ValidatorPoolDashboard } from './ValidatorPoolDashboard';
import { handleBlockchainError, handleBlockchainSuccess } from '@pezkuwi/lib/error-handler';
export const StakingDashboard: React.FC = () => {
const { api, selectedAccount, isApiReady } = usePezkuwi();
const { api, peopleApi, selectedAccount, isApiReady, isPeopleReady } = usePezkuwi();
const { balances, refreshBalances } = useWallet();
const [stakingInfo, setStakingInfo] = useState<StakingInfo | null>(null);
@@ -50,7 +50,7 @@ export const StakingDashboard: React.FC = () => {
setIsLoadingData(true);
try {
const [info, activeVals, minBond, duration, era] = await Promise.all([
getStakingInfo(api, selectedAccount.address),
getStakingInfo(api, selectedAccount.address, peopleApi || undefined),
getActiveValidators(api),
getMinNominatorBond(api),
getBondingDuration(api),
@@ -79,7 +79,7 @@ export const StakingDashboard: React.FC = () => {
fetchStakingData();
const interval = setInterval(fetchStakingData, 30000); // Refresh every 30s
return () => clearInterval(interval);
}, [api, isApiReady, selectedAccount]);
}, [api, peopleApi, isApiReady, isPeopleReady, selectedAccount]);
const handleBond = async () => {
if (!api || !selectedAccount || !bondAmount) return;
@@ -125,7 +125,7 @@ export const StakingDashboard: React.FC = () => {
// Refresh staking data after a delay
setTimeout(() => {
if (api && selectedAccount) {
getStakingInfo(api, selectedAccount.address).then(setStakingInfo);
getStakingInfo(api, selectedAccount.address, peopleApi || undefined).then(setStakingInfo);
}
}, 3000);
setIsLoading(false);
@@ -167,7 +167,7 @@ export const StakingDashboard: React.FC = () => {
// Refresh staking data
setTimeout(() => {
if (api && selectedAccount) {
getStakingInfo(api, selectedAccount.address).then(setStakingInfo);
getStakingInfo(api, selectedAccount.address, peopleApi || undefined).then(setStakingInfo);
}
}, 3000);
setIsLoading(false);
@@ -212,7 +212,7 @@ export const StakingDashboard: React.FC = () => {
setUnbondAmount('');
setTimeout(() => {
if (api && selectedAccount) {
getStakingInfo(api, selectedAccount.address).then(setStakingInfo);
getStakingInfo(api, selectedAccount.address, peopleApi || undefined).then(setStakingInfo);
}
}, 3000);
setIsLoading(false);
@@ -260,7 +260,7 @@ export const StakingDashboard: React.FC = () => {
refreshBalances();
setTimeout(() => {
if (api && selectedAccount) {
getStakingInfo(api, selectedAccount.address).then(setStakingInfo);
getStakingInfo(api, selectedAccount.address, peopleApi || undefined).then(setStakingInfo);
}
}, 3000);
setIsLoading(false);
@@ -306,7 +306,7 @@ export const StakingDashboard: React.FC = () => {
// Refresh staking data after a delay
setTimeout(() => {
if (api && selectedAccount) {
getStakingInfo(api, selectedAccount.address).then(setStakingInfo);
getStakingInfo(api, selectedAccount.address, peopleApi || undefined).then(setStakingInfo);
}
}, 3000);
setIsLoading(false);