generated from defi-wonderland/ts-turborepo-boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'dev' into feat/dummy-pricing-provider
- Loading branch information
Showing
61 changed files
with
2,553 additions
and
199 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export enum ApplicationStatus { | ||
NONE = 0, | ||
PENDING, | ||
APPROVED, | ||
REJECTED, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./enums.js"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
packages/processors/src/exceptions/metadataNotFound.exception.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export class MetadataNotFound extends Error { | ||
constructor(message: string) { | ||
super(message); | ||
this.name = "MetadataNotFoundError"; | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
packages/processors/src/processors/registry/handlers/roleRevoked.handler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
packages/processors/src/processors/strategy/common/baseDistributionUpdated.handler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { getAddress } from "viem"; | ||
|
||
import { Changeset } from "@grants-stack-indexer/repository"; | ||
import { ChainId, ProcessorEvent } from "@grants-stack-indexer/shared"; | ||
|
||
import { | ||
IEventHandler, | ||
MetadataNotFound, | ||
MetadataParsingFailed, | ||
ProcessorDependencies, | ||
} from "../../../internal.js"; | ||
import { MatchingDistribution, MatchingDistributionSchema } from "../../../schemas/index.js"; | ||
|
||
type Dependencies = Pick<ProcessorDependencies, "metadataProvider" | "logger">; | ||
|
||
/** | ||
* BaseDistributionUpdatedHandler: Processes 'DistributionUpdated' events | ||
* | ||
* - Decodes the updated distribution metadata | ||
* - Creates a changeset to update the round with the new distribution | ||
* - Serves as a base class as all strategies share the same logic for this event. | ||
* | ||
* @dev: | ||
* - Strategy handlers that want to handle the DistributionUpdated event should create an instance of this class corresponding to the event. | ||
* | ||
*/ | ||
|
||
export class BaseDistributionUpdatedHandler | ||
implements IEventHandler<"Strategy", "DistributionUpdated"> | ||
{ | ||
constructor( | ||
readonly event: ProcessorEvent<"Strategy", "DistributionUpdated">, | ||
private readonly chainId: ChainId, | ||
private readonly dependencies: Dependencies, | ||
) {} | ||
|
||
/* @inheritdoc */ | ||
async handle(): Promise<Changeset[]> { | ||
const { logger, metadataProvider } = this.dependencies; | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
const [_, pointer] = this.event.params.metadata; | ||
|
||
const strategyAddress = getAddress(this.event.srcAddress); | ||
const rawDistribution = await metadataProvider.getMetadata< | ||
MatchingDistribution | undefined | ||
>(pointer); | ||
|
||
if (!rawDistribution) { | ||
logger.warn(`No matching distribution found for pointer: ${pointer}`); | ||
|
||
throw new MetadataNotFound(`No matching distribution found for pointer: ${pointer}`); | ||
} | ||
|
||
const distribution = MatchingDistributionSchema.safeParse(rawDistribution); | ||
|
||
if (!distribution.success) { | ||
logger.warn(`Failed to parse matching distribution: ${distribution.error.message}`); | ||
|
||
throw new MetadataParsingFailed( | ||
`Failed to parse matching distribution: ${distribution.error.message}`, | ||
); | ||
} | ||
|
||
return [ | ||
{ | ||
type: "UpdateRoundByStrategyAddress", | ||
args: { | ||
chainId: this.chainId, | ||
strategyAddress, | ||
round: { | ||
readyForPayoutTransaction: this.event.transactionFields.hash, | ||
matchingDistribution: distribution.data.matchingDistribution, | ||
}, | ||
}, | ||
}, | ||
]; | ||
} | ||
} |
81 changes: 81 additions & 0 deletions
81
packages/processors/src/processors/strategy/common/baseFundsDistributed.handler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { getAddress } from "viem"; | ||
|
||
import { Changeset } from "@grants-stack-indexer/repository"; | ||
import { ChainId, ProcessorEvent } from "@grants-stack-indexer/shared"; | ||
|
||
import { IEventHandler, ProcessorDependencies } from "../../../internal.js"; | ||
|
||
type Dependencies = Pick< | ||
ProcessorDependencies, | ||
"roundRepository" | "applicationRepository" | "logger" | ||
>; | ||
|
||
/** | ||
* BaseFundsDistributedHandler: Processes 'FundsDistributed' events | ||
* | ||
* - Handles funds distributed events across all strategies. | ||
* - Creates two changesets: | ||
* 1. UpdateApplication: Updates the application with the transaction hash. | ||
* 2. IncrementRoundTotalDistributed: Increments the total distributed amount for a round. | ||
* - Serves as a base class as all strategies share the same logic for this event. | ||
* | ||
* @dev: | ||
* - Strategy handlers that want to handle the FundsDistributed event should create an instance of this class corresponding to the event. | ||
* | ||
*/ | ||
|
||
export class BaseFundsDistributedHandler implements IEventHandler<"Strategy", "FundsDistributed"> { | ||
constructor( | ||
readonly event: ProcessorEvent<"Strategy", "FundsDistributed">, | ||
private readonly chainId: ChainId, | ||
private readonly dependencies: Dependencies, | ||
) {} | ||
|
||
/** | ||
* Handles the FundsDistributed event. | ||
* @throws {RoundNotFound} if the round is not found. | ||
* @throws {ApplicationNotFound} if the application is not found. | ||
* @returns An array of changesets with the following: | ||
* 1. UpdateApplication: Updates the application with the transaction hash. | ||
* 2. IncrementRoundTotalDistributed: Increments the total distributed amount for a round. | ||
*/ | ||
async handle(): Promise<Changeset[]> { | ||
const { roundRepository, applicationRepository } = this.dependencies; | ||
|
||
const strategyAddress = getAddress(this.event.srcAddress); | ||
const round = await roundRepository.getRoundByStrategyAddressOrThrow( | ||
this.chainId, | ||
strategyAddress, | ||
); | ||
|
||
const roundId = round.id; | ||
const anchorAddress = getAddress(this.event.params.recipientId); | ||
const application = await applicationRepository.getApplicationByAnchorAddressOrThrow( | ||
this.chainId, | ||
roundId, | ||
anchorAddress, | ||
); | ||
|
||
return [ | ||
{ | ||
type: "UpdateApplication", | ||
args: { | ||
chainId: this.chainId, | ||
roundId, | ||
applicationId: application.id, | ||
application: { | ||
distributionTransaction: this.event.transactionFields.hash, | ||
}, | ||
}, | ||
}, | ||
{ | ||
type: "IncrementRoundTotalDistributed", | ||
args: { | ||
chainId: this.chainId, | ||
roundId: round.id, | ||
amount: BigInt(this.event.params.amount), | ||
}, | ||
}, | ||
]; | ||
} | ||
} |
112 changes: 112 additions & 0 deletions
112
packages/processors/src/processors/strategy/common/baseRecipientStatusUpdated.handler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import StatusesBitmap from "statuses-bitmap"; | ||
import { getAddress } from "viem"; | ||
|
||
import { Application, Changeset } from "@grants-stack-indexer/repository"; | ||
import { ChainId, ProcessorEvent } from "@grants-stack-indexer/shared"; | ||
|
||
import { ApplicationStatus, IEventHandler, ProcessorDependencies } from "../../../internal.js"; | ||
import { createStatusUpdate, isValidApplicationStatus } from "../helpers/index.js"; | ||
|
||
type Dependencies = Pick< | ||
ProcessorDependencies, | ||
"logger" | "roundRepository" | "applicationRepository" | ||
>; | ||
|
||
type ApplicationUpdate = { | ||
application: Application; | ||
status: number; | ||
}; | ||
|
||
/** | ||
* BaseRecipientStatusUpdatedHandler: Processes 'RecipientStatusUpdated' events | ||
* | ||
* - Decodes a bitmap containing status updates for multiple applications | ||
* - Validates each status is valid (between 1-3) | ||
* - Creates changesets to update application statuses in bulk | ||
* - Serves as a base class as all strategies share the same logic for this event | ||
* | ||
* @dev: | ||
* - Strategy handlers that want to handle the RecipientStatusUpdated event should create an instance of this class corresponding to the event. | ||
* | ||
*/ | ||
export class BaseRecipientStatusUpdatedHandler | ||
implements IEventHandler<"Strategy", "RecipientStatusUpdatedWithFullRow"> | ||
{ | ||
private readonly bitmap: StatusesBitmap; | ||
|
||
constructor( | ||
readonly event: ProcessorEvent<"Strategy", "RecipientStatusUpdatedWithFullRow">, | ||
private readonly chainId: ChainId, | ||
private readonly dependencies: Dependencies, | ||
) { | ||
this.bitmap = new StatusesBitmap(256n, 4n); | ||
} | ||
|
||
/** | ||
* Handles the RecipientStatusUpdated event by processing status updates for multiple applications. | ||
* @returns An array of changesets to update application statuses. | ||
*/ | ||
async handle(): Promise<Changeset[]> { | ||
const { roundRepository } = this.dependencies; | ||
|
||
const strategyAddress = getAddress(this.event.srcAddress); | ||
const round = await roundRepository.getRoundByStrategyAddressOrThrow( | ||
this.chainId, | ||
strategyAddress, | ||
); | ||
|
||
const applicationsToUpdate = await this.getApplicationsToUpdate(round.id); | ||
|
||
return applicationsToUpdate.map(({ application, status }) => { | ||
const statusString = ApplicationStatus[status] as Application["status"]; | ||
return { | ||
type: "UpdateApplication", | ||
args: { | ||
chainId: this.chainId, | ||
roundId: round.id, | ||
applicationId: application.id, | ||
application: createStatusUpdate({ | ||
application, | ||
newStatus: statusString, | ||
blockNumber: this.event.blockNumber, | ||
blockTimestamp: this.event.blockTimestamp, | ||
}), | ||
}, | ||
}; | ||
}); | ||
} | ||
|
||
/** | ||
* Gets the list of applications that need to be updated based on the bitmap row | ||
* @param roundId - The ID of the round. | ||
* @returns An array of application updates. | ||
*/ | ||
private async getApplicationsToUpdate(roundId: string): Promise<ApplicationUpdate[]> { | ||
const { rowIndex, fullRow } = this.event.params; | ||
this.bitmap.setRow(BigInt(rowIndex), BigInt(fullRow)); | ||
|
||
const startIndex = BigInt(rowIndex) * BigInt(this.bitmap.itemsPerRow); | ||
const applications: { application: Application; status: number }[] = []; | ||
|
||
for (let i = startIndex; i < startIndex + this.bitmap.itemsPerRow; i++) { | ||
const status = this.bitmap.getStatus(i); | ||
if (isValidApplicationStatus(status)) { | ||
const application = | ||
await this.dependencies.applicationRepository.getApplicationById( | ||
i.toString(), | ||
this.chainId, | ||
roundId, | ||
); | ||
|
||
if (application) { | ||
applications.push({ | ||
application, | ||
status, | ||
}); | ||
} | ||
} | ||
} | ||
|
||
return applications; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
export * from "./baseDistributed.handler.js"; | ||
export * from "./base.strategy.js"; | ||
export * from "./baseDistributionUpdated.handler.js"; | ||
export * from "./baseFundsDistributed.handler.js"; | ||
export * from "./baseRecipientStatusUpdated.handler.js"; |
Oops, something went wrong.