Skip to content

Commit

Permalink
feat: v3 staking rewards and aggregated (#129)
Browse files Browse the repository at this point in the history
* staking rewards and aggregated

* add transaction even type as a filter
  • Loading branch information
gluneau authored Jan 23, 2024
1 parent 43241e8 commit e10593b
Show file tree
Hide file tree
Showing 3 changed files with 247 additions and 1 deletion.
94 changes: 94 additions & 0 deletions public/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,100 @@
}
}
},
"/api/v3/{network}/dapps-staking/rewards/{period}": {
"get": {
"tags": [
"Dapps Staking"
],
"description": "Retrieves dapps staking rewards for a given network and period.",
"parameters": [
{
"name": "network",
"in": "path",
"required": true,
"type": "string",
"description": "The network name. Supported networks: astar",
"enum": [
"astar",
"shiden",
"shibuya"
]
},
{
"name": "period",
"in": "path",
"required": true,
"type": "string",
"description": "The period type. Supported values: 1 day, 7 days, 30 days, 90 days, 1 year",
"enum": [
"1 day",
"7 days",
"30 days",
"90 days",
"1 year"
]
},
{
"name": "transaction",
"in": "query",
"type": "string"
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/api/v3/{network}/dapps-staking/rewards-aggregated/{address}/{period}": {
"get": {
"tags": [
"Dapps Staking"
],
"description": "Retrieves dapps staking rewards for a given network and period.",
"parameters": [
{
"name": "network",
"in": "path",
"required": true,
"type": "string",
"description": "The network name. Supported networks: astar",
"enum": [
"astar",
"shiden",
"shibuya"
]
},
{
"name": "address",
"in": "path",
"required": true,
"type": "string",
"description": "User address or contract address who received rewards"
},
{
"name": "period",
"in": "path",
"required": true,
"type": "string",
"description": "The period type. Supported values: 1 day, 7 days, 30 days, 90 days, 1 year",
"enum": [
"1 day",
"7 days",
"30 days",
"90 days",
"1 year"
]
}
],
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/api/v1/{network}/node/tx-perblock/total": {
"get": {
"tags": [
Expand Down
68 changes: 67 additions & 1 deletion src/controllers/DappsStakingV3Controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { NetworkType } from '../networks';
import { PeriodType } from '../services/ServiceBase';
import { ControllerBase } from './ControllerBase';
import { IControllerBase } from './IControllerBase';
import { IDappsStakingEvents } from '../services/DappsStakingEvents';
import { IDappsStakingEvents, RewardEventType } from '../services/DappsStakingEvents';

@injectable()
export class DappsStakingV3Controller extends ControllerBase implements IControllerBase {
Expand Down Expand Up @@ -214,5 +214,71 @@ export class DappsStakingV3Controller extends ControllerBase implements IControl
}
},
);

app.route('/api/v3/:network/dapps-staking/rewards/:period').get(async (req: Request, res: Response) => {
/*
#swagger.description = 'Retrieves dapps staking rewards for a given network and period.'
#swagger.tags = ['Dapps Staking']
#swagger.parameters['network'] = {
in: 'path',
description: 'The network name. Supported networks: astar',
required: true,
enum: ['astar', 'shiden', 'shibuya']
}
#swagger.parameters['period'] = {
in: 'path',
description: 'The period type. Supported values: 1 day, 7 days, 30 days, 90 days, 1 year',
required: true,
enum: ['1 day', '7 days', '30 days', '90 days', '1 year']
}
#swagger.parameters['transaction'] = {
in: 'query',
description: 'The Reward Event transaction type. Supported values: Reward', 'BonusReward', 'DAppReward',
required: false,
type: 'string',
enum: ['Reward', 'BonusReward', 'DAppReward']
}
*/
res.json(
await this._dappsStakingEvents.getDappStakingRewards(
req.params.network as NetworkType,
req.params.period as PeriodType,
req.query.transaction as RewardEventType,
),
);
});

app.route('/api/v3/:network/dapps-staking/rewards-aggregated/:address/:period').get(
async (req: Request, res: Response) => {
/*
#swagger.description = 'Retrieves dapps staking rewards for a given network and period.'
#swagger.tags = ['Dapps Staking']
#swagger.parameters['network'] = {
in: 'path',
description: 'The network name. Supported networks: astar',
required: true,
enum: ['astar', 'shiden', 'shibuya']
}
#swagger.parameters['address'] = {
in: 'path',
description: 'User address or contract address who received rewards',
required: true
}
#swagger.parameters['period'] = {
in: 'path',
description: 'The period type. Supported values: 1 day, 7 days, 30 days, 90 days, 1 year',
required: true,
enum: ['1 day', '7 days', '30 days', '90 days', '1 year']
}
*/
res.json(
await this._dappsStakingEvents.getDappStakingRewardsAggregated(
req.params.network as NetworkType,
req.params.address as string,
req.params.period as PeriodType,
),
);
},
);
}
}
86 changes: 86 additions & 0 deletions src/services/DappsStakingEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@ export interface IDappsStakingEvents {
getAggregatedData(network: NetworkType, period: PeriodType): Promise<DappStakingAggregatedData[]>;
getDappStakingTvl(network: NetworkType, period: PeriodType): Promise<Pair[]>;
getDappStakingStakersCount(network: NetworkType, contractAddress: string, period: PeriodType): Promise<Pair[]>;
getDappStakingRewards(network: NetworkType, period: PeriodType, transaction: RewardEventType): Promise<Pair[]>;
getDappStakingRewardsAggregated(network: NetworkType, address: string, period: PeriodType): Promise<Pair[]>;
getDappStakingStakersList(network: NetworkType, contractAddress: string): Promise<List[]>;
}

export type RewardEventType = 'Reward' | 'BonusReward' | 'DAppReward';

declare global {
interface BigInt {
toJSON: () => string;
Expand Down Expand Up @@ -144,6 +148,88 @@ export class DappsStakingEvents extends ServiceBase implements IDappsStakingEven
}
}

public async getDappStakingRewards(
network: NetworkType,
period: PeriodType,
transaction: RewardEventType,
): Promise<Pair[]> {
if (network !== 'astar' && network !== 'shiden' && network !== 'shibuya') {
return [];
}

const range = this.getDateRange(period);

try {
const result = await axios.post(this.getApiUrl(network), {
query: `query MyQuery {
rewardEvents(
where: {
timestamp_gte: "${range.start.getTime()}",
timestamp_lte: "${range.end.getTime()}",
${transaction ? `transaction_in: [${transaction}]}` : '}'}
orderBy: id_ASC) {
amount
blockNumber
contractAddress
era
id
period
tierId
timestamp
transaction
userAddress
}
}`,
});

return result.data.data.rewardEvents;
} catch (e) {
console.error(e);
return [];
}
}

public async getDappStakingRewardsAggregated(
network: NetworkType,
address: string,
period: PeriodType,
): Promise<Pair[]> {
if (network !== 'astar' && network !== 'shiden' && network !== 'shibuya') {
return [];
}

const range = this.getDateRange(period);

try {
const result = await axios.post(this.getApiUrl(network), {
query: `query {
rewardAggregatedDailies(
orderBy: timestamp_DESC
where: {
beneficiary_eq: "${address}"
timestamp_gte: "${range.start.getTime()}"
timestamp_lte: "${range.end.getTime()}"
}
) {
amount
timestamp
}
}`,
});

const stakersCount = result.data.data.rewardAggregatedDailies.map(
(node: { timestamp: string; amount: number }) => {
return [node.timestamp, node.amount];
},
);

return stakersCount;
} catch (e) {
console.error(e);
return [];
}
}

public async getDappStakingStakersCount(
network: NetworkType,
contractAddress: string,
Expand Down

0 comments on commit e10593b

Please sign in to comment.