Skip to content

Commit

Permalink
fix POST/ route (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
thelostone-mc authored Jan 16, 2025
1 parent ec9b531 commit 708baba
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 79 deletions.
30 changes: 30 additions & 0 deletions src/ext/indexer/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import type {
ApplicationRoundQueryResponse,
ApplicationWithRound,
ManagerRolesResponse,
RoundDonationsQueryResponse,
} from './types';
import request from 'graphql-request';
import {
getRoundWithApplications,
getApplicationWithRound,
getRoundManager,
getRoundDonations,
} from './queries';
import type { Logger } from 'winston';
import { IsNullError } from '@/errors';
Expand Down Expand Up @@ -179,6 +181,34 @@ class IndexerClient {
throw error;
}
}

async getRoundDonations({
chainId,
roundId,
}: {
chainId: number;
roundId: string;
}): Promise<RoundDonationsQueryResponse> {
const requestVariables = {
chainId,
roundId,
};

try {
const response: RoundDonationsQueryResponse = await request(
this.indexerEndpoint,
getRoundDonations,
requestVariables
);

return response;
} catch (error) {
this.logger.error(`Failed to fetch round donations: ${error.message}`, {
error,
});
throw error;
}
}
}

export const indexerClient = IndexerClient.getInstance();
13 changes: 13 additions & 0 deletions src/ext/indexer/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,16 @@ export const getApplicationWithRound = gql`
}
}
`;

export const getRoundDonations = gql`
query RoundDonations($chainId: Int!, $roundId: String!) {
donations(
filter: { chainId: { equalTo: $chainId }, roundId: { equalTo: $roundId } }
) {
id
applicationId
amount
tokenAddress
}
}
`;
9 changes: 9 additions & 0 deletions src/ext/indexer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,12 @@ export interface ManagerRolesResponse {
}>;
}>;
}

export interface RoundDonationsQueryResponse {
donations: Array<{
id: string;
applicationId: string;
amount: string;
tokenAddress: string;
}>;
}
28 changes: 16 additions & 12 deletions src/routes/voteRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,19 @@ const router = Router();
* voter:
* type: string
* description: Address of the voter
* example: "0x1234567890abcdef1234567890abcdef12345678"
* example: "0xB8cEF765721A6da910f14Be93e7684e9a3714123"
* signature:
* type: string
* description: Signature of the voter
* example: "0xdeadbeef"
* alloPoolId:
* type: string
* description: The ID of the pool (from Allo) to which the vote is submitted
* example: "609"
* example: "615"
* chainId:
* type: number
* description: The chain ID associated with the pool
* example: 42161
* example: 11155111
* ballot:
* type: array
* description: Array of votes for metrics
Expand All @@ -46,10 +46,12 @@ const router = Router();
* type: number
* description: Vote share percentage allocated to the metric
* example:
* - metricId: "twitterAge"
* voteShare: 150
* - metricId: "githubFollowers"
* - metricId: "userEngagement"
* voteShare: 50
* - metricId: "twitterAccountAge"
* voteShare: 30
* - metricId: "gasFees"
* voteShare: 20
* required:
* - voter
* - signature
Expand Down Expand Up @@ -83,11 +85,11 @@ router.post('/', submitVote);
* alloPoolId:
* type: string
* description: The ID of the pool to predict
* example: "609"
* example: "615"
* chainId:
* type: number
* description: The chain ID associated with the pool
* example: 42161
* example: 11155111
* ballot:
* type: array
* description: Array of votes for metrics
Expand All @@ -101,10 +103,12 @@ router.post('/', submitVote);
* type: number
* description: Vote share percentage allocated to the metric
* example:
* - metricId: 1
* voteShare: 50
* - metricId: 2
* voteShare: 50
* - metricId: "userEngagement"
* voteShare: 20
* - metricId: "twitterAccountAge"
* voteShare: 60
* - metricId: "gasFees"
* voteShare: 20
* required:
* - alloPoolId
* - chainId
Expand Down
1 change: 1 addition & 0 deletions src/service/VoteService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class VoteService {
// Update existing vote
voteRepository.merge(existingVote, voteData);
await voteRepository.save(existingVote);
return;
}

// Create new vote
Expand Down
146 changes: 79 additions & 67 deletions src/utils/calculate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ActionNotAllowedError, NotFoundError } from '@/errors';
import { indexerClient, Status } from '@/ext/indexer';
import metricService from '@/service/MetricService';
import poolService from '@/service/PoolService';
import voteService from '@/service/VoteService';

interface MetricFetcherResponse {
alloApplicationId: string;
Expand All @@ -12,64 +13,71 @@ interface MetricFetcherResponse {
}

// Hardcoded votes for testing purposes
const getHardcodedVotes = (): Array<Partial<Vote>> => {
return [
{
ballot: [
{ metricIdentifier: 'twitterAccountAge', voteShare: 50 },
{ metricIdentifier: 'gasFees', voteShare: 30 },
{ metricIdentifier: 'userEngagement', voteShare: 20 },
],
},
{
ballot: [
{ metricIdentifier: 'twitterAccountAge', voteShare: 40 },
{ metricIdentifier: 'gasFees', voteShare: 50 },
{ metricIdentifier: 'userEngagement', voteShare: 10 },
],
},
{
ballot: [
{ metricIdentifier: 'twitterAccountAge', voteShare: 60 },
{ metricIdentifier: 'gasFees', voteShare: 20 },
{ metricIdentifier: 'userEngagement', voteShare: 20 },
],
},
{
ballot: [
{ metricIdentifier: 'twitterAccountAge', voteShare: 30 },
{ metricIdentifier: 'gasFees', voteShare: 60 },
{ metricIdentifier: 'userEngagement', voteShare: 10 },
],
},
{
ballot: [
{ metricIdentifier: 'twitterAccountAge', voteShare: 20 },
{ metricIdentifier: 'gasFees', voteShare: 30 },
{ metricIdentifier: 'userEngagement', voteShare: 50 },
],
},
];
};
// const getHardcodedVotes = (): Array<Partial<Vote>> => {
// return [
// {
// ballot: [
// { metricIdentifier: 'twitterAccountAge', voteShare: 50 },
// { metricIdentifier: 'gasFees', voteShare: 30 },
// { metricIdentifier: 'userEngagement', voteShare: 20 },
// ],
// },
// {
// ballot: [
// { metricIdentifier: 'twitterAccountAge', voteShare: 40 },
// { metricIdentifier: 'gasFees', voteShare: 50 },
// { metricIdentifier: 'userEngagement', voteShare: 10 },
// ],
// },
// {
// ballot: [
// { metricIdentifier: 'twitterAccountAge', voteShare: 60 },
// { metricIdentifier: 'gasFees', voteShare: 20 },
// { metricIdentifier: 'userEngagement', voteShare: 20 },
// ],
// },
// {
// ballot: [
// { metricIdentifier: 'twitterAccountAge', voteShare: 30 },
// { metricIdentifier: 'gasFees', voteShare: 60 },
// { metricIdentifier: 'userEngagement', voteShare: 10 },
// ],
// },
// {
// ballot: [
// { metricIdentifier: 'twitterAccountAge', voteShare: 20 },
// { metricIdentifier: 'gasFees', voteShare: 30 },
// { metricIdentifier: 'userEngagement', voteShare: 50 },
// ],
// },
// ];
// };

const getApprovedAlloApplicationIds = async (
alloPoolId: string,
chainId: number
): Promise<[boolean, string[]]> => {
): Promise<string[]> => {
const indexerPoolData = await indexerClient.getRoundWithApplications({
chainId,
roundId: alloPoolId,
});

// TODO: Implement this from indexer
const isFinalised = false;

return [
isFinalised,
return (
indexerPoolData?.applications
.filter(application => application.status === Status.APPROVED)
.map(application => application.id) ?? [],
];
.map(application => application.id) ?? []
);
};

const isPoolFinalised = async (
alloPoolId: string,
chainId: number
): Promise<boolean> => {
const roundDonations = await indexerClient.getRoundDonations({
chainId,
roundId: alloPoolId,
});
return roundDonations.donations.length > 0;
};

// TODO: Implement the gr8LucasMetricFetcher function to fetch metrics from the external endpoint
Expand All @@ -79,6 +87,17 @@ const gr8LucasMetricFetcher = async (
): Promise<MetricFetcherResponse[]> => {
// Hardcoded object for now
return [
{
alloApplicationId: '0',
metricIdentifier: 'twitterAccountAge',
metricScore: 0.5,
},
{ alloApplicationId: '0', metricIdentifier: 'gasFees', metricScore: 10 },
{
alloApplicationId: '0',
metricIdentifier: 'userEngagement',
metricScore: 0.6,
},
{
alloApplicationId: '1',
metricIdentifier: 'twitterAccountAge',
Expand Down Expand Up @@ -112,35 +131,26 @@ const gr8LucasMetricFetcher = async (
metricIdentifier: 'userEngagement',
metricScore: 0.4,
},
{
alloApplicationId: '4',
metricIdentifier: 'twitterAccountAge',
metricScore: 0.5,
},
{ alloApplicationId: '4', metricIdentifier: 'gasFees', metricScore: 10 },
{
alloApplicationId: '4',
metricIdentifier: 'userEngagement',
metricScore: 0.6,
},
];
};

const fetchVotes = async (
chainId: number,
alloPoolId: string
): Promise<Array<Partial<Vote>>> => {
// const votes = await voteService.getVotesByChainIdAndAlloPoolId(chainId, alloPoolId);
const votes = getHardcodedVotes();
return votes;
const votes = await voteService.getVotesByChainIdAndAlloPoolId(
chainId,
alloPoolId
);
return votes ?? [];
};

// Function to determine if a metric is increasing or decreasing
const isMetricIncreasing = (metricIdentifier: string): boolean => {
const metric = metricService.getEnabledMetricsByIdentifiers([
metricIdentifier,
]);
if (metric == null) {
if (metric === undefined) {
throw new NotFoundError(`Metric not found`);
}
return metric[0].orientation === 'increase';
Expand Down Expand Up @@ -179,14 +189,16 @@ export const calculate = async (
// Add unAccountedBallots to the votes
if (unAccountedBallots !== undefined) votes.push(unAccountedBallots);

// Fetch approved allo application ids
const [isFinalised, approvedAlloApplicationIds] =
await getApprovedAlloApplicationIds(alloPoolId, chainId);

if (isFinalised) {
if (await isPoolFinalised(alloPoolId, chainId)) {
throw new ActionNotAllowedError('Pool is finalised');
}

// Fetch approved allo application ids
const approvedAlloApplicationIds = await getApprovedAlloApplicationIds(
alloPoolId,
chainId
);

// Fetch metrics from the external endpoint
const fetchedApplicaionMetricScores = await gr8LucasMetricFetcher(
alloPoolId,
Expand Down

0 comments on commit 708baba

Please sign in to comment.