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 * Get PEZ rewards information for an account
* Note: pezRewards pallet is on People Chain, not Relay Chain
*/ */
export async function getPezRewards( export async function getPezRewards(
api: ApiPromise, peopleApi: ApiPromise,
address: string address: string
): Promise<PezRewardInfo | null> { ): Promise<PezRewardInfo | null> {
try { try {
// Check if pezRewards pallet exists // Check if pezRewards pallet exists on People Chain
if (!api.query.pezRewards || !api.query.pezRewards.epochInfo) { if (!peopleApi?.query?.pezRewards || !peopleApi.query.pezRewards.epochInfo) {
console.warn('PezRewards pallet not available'); console.warn('PezRewards pallet not available on People Chain');
return null; return null;
} }
// Get current epoch info // Get current epoch info
const epochInfoResult = await api.query.pezRewards.epochInfo(); const epochInfoResult = await peopleApi.query.pezRewards.epochInfo();
if (!epochInfoResult) { if (!epochInfoResult) {
console.warn('No epoch info found'); 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++) { for (let i = Math.max(0, currentEpoch - 3); i < currentEpoch; i++) {
try { try {
// Check if user has claimed this epoch already // 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) { if (claimedResult.isNone) {
// User hasn't claimed - check if they have rewards // 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) { if (userScoreResult.isSome) {
// User has a score for this epoch - calculate their reward // 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) { if (epochPoolResult.isSome) {
const epochPoolCodec = epochPoolResult.unwrap() as { toJSON: () => unknown }; const epochPoolCodec = epochPoolResult.unwrap() as { toJSON: () => unknown };
@@ -272,10 +273,14 @@ export async function getPezRewards(
/** /**
* Get comprehensive staking info for an account * 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( export async function getStakingInfo(
api: ApiPromise, api: ApiPromise,
address: string address: string,
peopleApi?: ApiPromise
): Promise<StakingInfo> { ): Promise<StakingInfo> {
const ledger = await getStakingLedger(api, address); const ledger = await getStakingLedger(api, address);
const nominations = await getNominations(api, address); const nominations = await getNominations(api, address);
@@ -324,15 +329,17 @@ export async function getStakingInfo(
let hasStartedScoreTracking = false; let hasStartedScoreTracking = false;
try { 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 // 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) { if (scoreResult.isSome) {
hasStartedScoreTracking = true; hasStartedScoreTracking = true;
const startBlockCodec = scoreResult.unwrap() as { toString: () => string }; const startBlockCodec = scoreResult.unwrap() as { toString: () => string };
const startBlock = Number(startBlockCodec.toString()); 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; const durationInBlocks = currentBlock - startBlock;
stakingDuration = durationInBlocks; stakingDuration = durationInBlocks;
@@ -387,8 +394,8 @@ export async function getStakingInfo(
const validatorsOption = await api.query.staking.validators(address); const validatorsOption = await api.query.staking.validators(address);
const isValidator = validatorsOption.isSome; const isValidator = validatorsOption.isSome;
// Get PEZ rewards information // Get PEZ rewards information (from People Chain)
const pezRewards = await getPezRewards(api, address); const pezRewards = peopleApi ? await getPezRewards(peopleApi, address) : null;
return { return {
bonded: ledger ? formatBalance(ledger.total) : '0', bonded: ledger ? formatBalance(ledger.total) : '0',
@@ -25,7 +25,7 @@ import { ValidatorPoolDashboard } from './ValidatorPoolDashboard';
import { handleBlockchainError, handleBlockchainSuccess } from '@pezkuwi/lib/error-handler'; import { handleBlockchainError, handleBlockchainSuccess } from '@pezkuwi/lib/error-handler';
export const StakingDashboard: React.FC = () => { export const StakingDashboard: React.FC = () => {
const { api, selectedAccount, isApiReady } = usePezkuwi(); const { api, peopleApi, selectedAccount, isApiReady, isPeopleReady } = usePezkuwi();
const { balances, refreshBalances } = useWallet(); const { balances, refreshBalances } = useWallet();
const [stakingInfo, setStakingInfo] = useState<StakingInfo | null>(null); const [stakingInfo, setStakingInfo] = useState<StakingInfo | null>(null);
@@ -50,7 +50,7 @@ export const StakingDashboard: React.FC = () => {
setIsLoadingData(true); setIsLoadingData(true);
try { try {
const [info, activeVals, minBond, duration, era] = await Promise.all([ const [info, activeVals, minBond, duration, era] = await Promise.all([
getStakingInfo(api, selectedAccount.address), getStakingInfo(api, selectedAccount.address, peopleApi || undefined),
getActiveValidators(api), getActiveValidators(api),
getMinNominatorBond(api), getMinNominatorBond(api),
getBondingDuration(api), getBondingDuration(api),
@@ -79,7 +79,7 @@ export const StakingDashboard: React.FC = () => {
fetchStakingData(); fetchStakingData();
const interval = setInterval(fetchStakingData, 30000); // Refresh every 30s const interval = setInterval(fetchStakingData, 30000); // Refresh every 30s
return () => clearInterval(interval); return () => clearInterval(interval);
}, [api, isApiReady, selectedAccount]); }, [api, peopleApi, isApiReady, isPeopleReady, selectedAccount]);
const handleBond = async () => { const handleBond = async () => {
if (!api || !selectedAccount || !bondAmount) return; if (!api || !selectedAccount || !bondAmount) return;
@@ -125,7 +125,7 @@ export const StakingDashboard: React.FC = () => {
// Refresh staking data after a delay // Refresh staking data after a delay
setTimeout(() => { setTimeout(() => {
if (api && selectedAccount) { if (api && selectedAccount) {
getStakingInfo(api, selectedAccount.address).then(setStakingInfo); getStakingInfo(api, selectedAccount.address, peopleApi || undefined).then(setStakingInfo);
} }
}, 3000); }, 3000);
setIsLoading(false); setIsLoading(false);
@@ -167,7 +167,7 @@ export const StakingDashboard: React.FC = () => {
// Refresh staking data // Refresh staking data
setTimeout(() => { setTimeout(() => {
if (api && selectedAccount) { if (api && selectedAccount) {
getStakingInfo(api, selectedAccount.address).then(setStakingInfo); getStakingInfo(api, selectedAccount.address, peopleApi || undefined).then(setStakingInfo);
} }
}, 3000); }, 3000);
setIsLoading(false); setIsLoading(false);
@@ -212,7 +212,7 @@ export const StakingDashboard: React.FC = () => {
setUnbondAmount(''); setUnbondAmount('');
setTimeout(() => { setTimeout(() => {
if (api && selectedAccount) { if (api && selectedAccount) {
getStakingInfo(api, selectedAccount.address).then(setStakingInfo); getStakingInfo(api, selectedAccount.address, peopleApi || undefined).then(setStakingInfo);
} }
}, 3000); }, 3000);
setIsLoading(false); setIsLoading(false);
@@ -260,7 +260,7 @@ export const StakingDashboard: React.FC = () => {
refreshBalances(); refreshBalances();
setTimeout(() => { setTimeout(() => {
if (api && selectedAccount) { if (api && selectedAccount) {
getStakingInfo(api, selectedAccount.address).then(setStakingInfo); getStakingInfo(api, selectedAccount.address, peopleApi || undefined).then(setStakingInfo);
} }
}, 3000); }, 3000);
setIsLoading(false); setIsLoading(false);
@@ -306,7 +306,7 @@ export const StakingDashboard: React.FC = () => {
// Refresh staking data after a delay // Refresh staking data after a delay
setTimeout(() => { setTimeout(() => {
if (api && selectedAccount) { if (api && selectedAccount) {
getStakingInfo(api, selectedAccount.address).then(setStakingInfo); getStakingInfo(api, selectedAccount.address, peopleApi || undefined).then(setStakingInfo);
} }
}, 3000); }, 3000);
setIsLoading(false); setIsLoading(false);