Add multi-staking entities, APY calculation, Asset Hub indexer support

- Add StakingApy, ActiveStaker, Reward entities to schema.graphql
- Add APY calculation engine in NewEra.ts (inflation curve + validator commission)
- Add saveMultiStakingReward to Rewards.ts and PoolRewards.ts
- Add handleAssetTransfer for assets.Transferred events
- Add constants.ts with genesis hashes and inflation params
- Add docker-compose.prod.yml for production deployment (relay + assethub nodes)
- Add deploy-vps.yml GitHub Actions workflow for auto-deploy on push
This commit is contained in:
2026-02-14 02:38:22 +03:00
parent 9922e8ba89
commit 076b54bdc9
8 changed files with 496 additions and 15 deletions
+50
View File
@@ -3,10 +3,12 @@ import {
AccumulatedReward,
AccumulatedPoolReward,
HistoryElement,
Reward,
RewardType,
} from "../types";
import { SubstrateEvent } from "@subql/types";
import {
eventId,
eventIdFromBlockAndIdxAndAddress,
timestamp,
eventIdWithAddress,
@@ -18,6 +20,11 @@ import {
} from "./Rewards";
import { getPoolMembers } from "./Cache";
import { Option } from "@pezkuwi/types";
import {
PEZKUWI_RELAY_GENESIS,
PEZKUWI_ASSET_HUB_GENESIS,
STAKING_TYPE_NOMINATION_POOL,
} from "./constants";
export async function handlePoolReward(
rewardEvent: SubstrateEvent,
@@ -37,6 +44,13 @@ export async function handlePoolReward(
RewardType.reward,
accumulatedReward.amount,
);
// Save to multi-staking Reward entity for both relay and Asset Hub networkIds
await savePoolMultiStakingReward(
rewardEvent,
accountId.toString(),
(amount as any).toBigInt(),
RewardType.reward,
);
}
async function handlePoolRewardForTxHistory(
@@ -200,6 +214,13 @@ async function handleRelaychainPooledStakingSlash(
RewardType.slash,
accumulatedReward.amount,
);
// Save to multi-staking Reward entity
await savePoolMultiStakingReward(
event,
accountId,
personalSlash,
RewardType.slash,
);
}
}
}
@@ -239,3 +260,32 @@ async function handlePoolSlashForTxHistory(
await element.save();
}
/**
* Save pool reward/slash to the multi-staking Reward entity
* Saves for both relay chain and Asset Hub networkIds since nom pools
* are accessible from both contexts
*/
async function savePoolMultiStakingReward(
event: SubstrateEvent,
accountAddress: string,
amount: bigint,
rewardType: RewardType,
): Promise<void> {
const ts = timestamp(event.block);
const bn = blockNumber(event);
const baseId = `${eventId(event)}-${accountAddress}-pool`;
// Save for Asset Hub networkId (nomination pools are accessed via Asset Hub)
const ahReward = Reward.create({
id: `${baseId}-ah`,
networkId: PEZKUWI_ASSET_HUB_GENESIS,
stakingType: STAKING_TYPE_NOMINATION_POOL,
address: accountAddress,
type: rewardType,
amount,
timestamp: ts,
blockNumber: bn,
});
await ahReward.save();
}