Skip to content

migrate to new indexer #40

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 32 additions & 15 deletions src/controllers/evaluationController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,27 @@ export const recreateEvaluationQuestions = async (
return;
}

await evaluationQuestionService.resetEvaluationQuestions(
chainId,
alloPoolId,
evaluationQuestions
const [errorReset] = await catchError(
evaluationQuestionService.resetEvaluationQuestions(
chainId,
alloPoolId,
evaluationQuestions
)
);

await evaluationService.cleanEvaluations();
if (errorReset !== undefined) {
logger.error('Failed to reset evaluation questions', { errorReset });
res.status(500).json({ message: 'Failed to reset evaluation questions' });
return;
}

const [errorClean] = await catchError(evaluationService.cleanEvaluations());

if (errorClean !== undefined) {
logger.error('Failed to clean evaluations', { errorClean });
res.status(500).json({ message: 'Failed to clean evaluations' });
return;
}

res.status(200).json(evaluationQuestions);
};
Expand Down Expand Up @@ -150,14 +164,16 @@ export const evaluateApplication = async (
summaryInput,
};

const isAllowed = await isPoolManager<CreateEvaluationParams>(
createEvaluationParams,
signature,
chainId,
alloPoolId
const [isAllowedError, isAllowed] = await catchError(
isPoolManager<CreateEvaluationParams>(
createEvaluationParams,
signature,
chainId,
alloPoolId
)
);

if (!isAllowed) {
if (isAllowedError !== undefined || isAllowed === undefined) {
logger.warn(
`User with address: ${evaluator} is not allowed to evaluate application`
);
Expand Down Expand Up @@ -301,16 +317,17 @@ export const triggerLLMEvaluation = async (
questions,
};

try {
await createLLMEvaluations([data]);
res.status(200).json({ message: 'LLM evaluation triggered successfully' });
} catch (error) {
const [error] = await catchError(createLLMEvaluations([data]));
if (error !== undefined) {
logger.error('Failed to create evaluations:', error);
res.status(500).json({
message: 'Failed to create evaluations',
error: error.message,
});
}

logger.info('LLM evaluation triggered successfully');
res.status(200).json({ message: 'LLM evaluation triggered successfully' });
};

const batchPromises = <T>(array: T[], batchSize: number): T[][] => {
Expand Down
22 changes: 14 additions & 8 deletions src/controllers/passportValidationController.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { Request, Response } from 'express';
import { validateRequest } from '@/utils';
import { catchError, validateRequest } from '@/utils';
import type { ProjectApplicationForManager } from '@/ext/passport/types';
import { isVerified } from '@/ext/passport/credentialverification';
import { createLogger } from '@/logger';

interface SocialCredentialBody {
application: Partial<ProjectApplicationForManager>;
}

const logger = createLogger();

export const validateSocialCredential = async (
req: Request,
res: Response
Expand All @@ -15,13 +18,16 @@ export const validateSocialCredential = async (

const { application } = req.body as SocialCredentialBody;

try {
const result = await isVerified(application);
res.json({
message: 'Social credential validated',
provider: result,
});
} catch (error) {
const [error, result] = await catchError(isVerified(application));
if (error !== undefined) {
logger.error('Failed to validate social credential:', error);
res.status(400).json({ message: 'Error validating social credential' });
return;
}

logger.info('Social credential validated', { result });
res.json({
message: 'Social credential validated',
provider: result,
});
};
12 changes: 9 additions & 3 deletions src/controllers/poolController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,17 @@ const handlePoolEvaluationQuestions = async (
pool: Pool,
poolMetadata: IndexerRoundMetadata
): Promise<PromptEvaluationQuestions> => {
const questions =
await evaluationQuestionService.getEvaluationQuestionsByAlloPoolId(
const [error, questions] = await catchError(
evaluationQuestionService.getEvaluationQuestionsByAlloPoolId(
pool.alloPoolId,
pool.chainId
);
)
);

if (error !== undefined || questions === undefined) {
logger.error('Failed to get evaluation questions:', error);
throw new Error('Failed to get evaluation questions');
}

if (questions.length > 0) {
return questions.map(question => question.question);
Expand Down
20 changes: 14 additions & 6 deletions src/ext/indexer/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ class IndexerClient {
getRoundManager,
requestVariables
);

if (response.rounds.length === 0) {
this.logger.warn(
`No round found for poolId: ${alloPoolId} on chainId: ${chainId}`
Expand All @@ -97,15 +96,15 @@ class IndexerClient {

const round = response.rounds[0];

if (round.roles.length === 0) {
if (round.roundRoles.length === 0) {
this.logger.warn(
`No manager found for poolId: ${alloPoolId} on chainId: ${chainId}`
);
return [];
}

this.logger.info(`Successfully fetched round manager`);
return round.roles.map(role => role.address);
return round.roundRoles.map(role => role.address);
} catch (error) {
this.logger.error(`Failed to fetch round manager: ${error.message}`, {
error,
Expand Down Expand Up @@ -157,7 +156,16 @@ class IndexerClient {
return null;
}

const round = response.rounds[0];
const round = {
chainId: response.rounds[0].chainId,
id: response.rounds[0].id,
roundMetadata: response.rounds[0].roundMetadata,
roundMetadataCid: response.rounds[0].roundMetadataCid,
applications: response.rounds[0].applications.map(application => ({
...application,
project: application.projects[0],
})),
};

// Cache the result
this.cache.set(cacheKey, round);
Expand Down Expand Up @@ -197,15 +205,15 @@ class IndexerClient {
requestVariables
);

const application = response.application;
const application = response.applications[0];

if (application == null) {
this.logger.warn(
`No application found for applicationId: ${applicationId} in roundId: ${roundId} on chainId: ${chainId}`
);
return null;
}
return response.application;
return application;
} catch (error) {
this.logger.error(
`Failed to fetch round with single application: ${error.message}`,
Expand Down
20 changes: 11 additions & 9 deletions src/ext/indexer/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ import { gql } from 'graphql-request';

export const getRoundManager = gql`
query RoundManager($chainId: Int!, $alloPoolId: String!) {
rounds(
filter: { chainId: { equalTo: $chainId }, id: { equalTo: $alloPoolId } }
) {
roles {
rounds(where: { chainId: { _eq: $chainId }, id: { _eq: $alloPoolId } }) {
roundRoles {
address
}
}
Expand All @@ -14,9 +12,7 @@ export const getRoundManager = gql`

export const getRoundWithApplications = gql`
query RoundApplications($chainId: Int!, $roundId: String!) {
rounds(
filter: { chainId: { equalTo: $chainId }, id: { equalTo: $roundId } }
) {
rounds(where: { chainId: { _eq: $chainId }, id: { _eq: $roundId } }) {
chainId
id
roundMetadata
Expand All @@ -27,7 +23,7 @@ export const getRoundWithApplications = gql`
metadataCid
status
projectId
project: canonicalProject {
projects(where: { projectType: { _eq: "canonical" } }) {
metadata
metadataCid
}
Expand All @@ -42,7 +38,13 @@ export const getApplicationWithRound = gql`
$roundId: String!
$applicationId: String!
) {
application(chainId: $chainId, roundId: $roundId, id: $applicationId) {
applications(
where: {
chainId: { _eq: $chainId }
roundId: { _eq: $roundId }
id: { _eq: $applicationId }
}
) {
metadata
metadataCid
round {
Expand Down
38 changes: 27 additions & 11 deletions src/ext/indexer/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// 1. Basic Types & Enums
export type Address = `0x${string}`;

export enum Status {
Expand All @@ -6,6 +7,7 @@ export enum Status {
REJECTED = 'REJECTED',
}

// 2. Metadata & Supporting Interfaces
export interface ApplicationMetadata {
signature: string;
application: {
Expand Down Expand Up @@ -52,34 +54,48 @@ export interface ProjectMetadata {
projectTwitter?: string;
userGithub?: string;
projectGithub?: string;
// credentials: ProjectCredentials;
owners: Array<{ address: string }>;
createdAt: number;
lastUpdated: number;
}

export interface Application {
// 3. Base Interfaces (Used in Multiple Places)
export interface BaseProject {
metadata: ProjectMetadata;
metadataCid: string;
}

export interface BaseApplication {
id: string;
metadata: ApplicationMetadata;
metadataCid: string;
status: Status;
projectId: string;
project: {
metadata: ProjectMetadata;
metadataCid: string;
};
}

export interface RoundWithApplications {
// 4. Extended Implementations
export interface Application extends BaseApplication {
project: BaseProject;
}

export interface ApplicationQuery extends BaseApplication {
projects: BaseProject[];
}

export interface BaseRound<T extends BaseApplication> {
chainId: number;
id: string;
roundMetadata: RoundMetadata;
roundMetadataCid: string;
applications: Application[];
applications: T[];
}

export type RoundWithApplications = BaseRound<Application>;
export type RoundWithApplicationsQuery = BaseRound<ApplicationQuery>;

// 5. API Response Structures
export interface RoundApplicationsQueryResponse {
rounds: RoundWithApplications[];
rounds: RoundWithApplicationsQuery[];
}

export interface ApplicationWithRound {
Expand All @@ -94,12 +110,12 @@ export interface ApplicationWithRound {
}

export interface ApplicationRoundQueryResponse {
application: ApplicationWithRound;
applications: ApplicationWithRound[];
}

export interface ManagerRolesResponse {
rounds: Array<{
roles: Array<{
roundRoles: Array<{
address: string;
}>;
}>;
Expand Down
17 changes: 13 additions & 4 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,23 @@ export async function isPoolManager<T>(
chainId: number,
alloPoolId: string
): Promise<boolean> {
const validAddresses = await indexerClient.getRoundManager({
chainId,
alloPoolId,
});
const [error, validAddresses] = await catchError(
indexerClient.getRoundManager({
chainId,
alloPoolId,
})
);

if (error !== undefined || validAddresses === undefined) {
logger.error('Failed to fetch pool manager', { error });
return false;
}

if (env.NODE_ENV === 'development' && signature === '0xdeadbeef') {
logger.info('Skipping signature check in development mode');
return true;
}

try {
const address = await recoverSignerAddress(obj, signature);
logger.info(`Recovered address: ${address}`);
Expand Down