diff --git a/public/swagger.json b/public/swagger.json index 2e207d2..0fd05e5 100644 --- a/public/swagger.json +++ b/public/swagger.json @@ -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": [ diff --git a/src/controllers/DappsStakingV3Controller.ts b/src/controllers/DappsStakingV3Controller.ts index c20f4d3..6994d4a 100644 --- a/src/controllers/DappsStakingV3Controller.ts +++ b/src/controllers/DappsStakingV3Controller.ts @@ -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 { @@ -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, + ), + ); + }, + ); } } diff --git a/src/services/DappsStakingEvents.ts b/src/services/DappsStakingEvents.ts index ca7e91f..26074a3 100644 --- a/src/services/DappsStakingEvents.ts +++ b/src/services/DappsStakingEvents.ts @@ -23,9 +23,13 @@ export interface IDappsStakingEvents { getAggregatedData(network: NetworkType, period: PeriodType): Promise; getDappStakingTvl(network: NetworkType, period: PeriodType): Promise; getDappStakingStakersCount(network: NetworkType, contractAddress: string, period: PeriodType): Promise; + getDappStakingRewards(network: NetworkType, period: PeriodType, transaction: RewardEventType): Promise; + getDappStakingRewardsAggregated(network: NetworkType, address: string, period: PeriodType): Promise; getDappStakingStakersList(network: NetworkType, contractAddress: string): Promise; } +export type RewardEventType = 'Reward' | 'BonusReward' | 'DAppReward'; + declare global { interface BigInt { toJSON: () => string; @@ -144,6 +148,88 @@ export class DappsStakingEvents extends ServiceBase implements IDappsStakingEven } } + public async getDappStakingRewards( + network: NetworkType, + period: PeriodType, + transaction: RewardEventType, + ): Promise { + 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 { + 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,