diff --git a/packages/data-flow/src/eventsFetcher.ts b/packages/data-flow/src/eventsFetcher.ts index b061c52..cf83383 100644 --- a/packages/data-flow/src/eventsFetcher.ts +++ b/packages/data-flow/src/eventsFetcher.ts @@ -7,8 +7,8 @@ export class EventsFetcher implements IEventsFetcher { constructor(private indexerClient: IIndexerClient) {} /* @inheritdoc */ async fetchEventsByBlockNumberAndLogIndex( - chainId: number, - blockNumber: number, + chainId: bigint, + blockNumber: bigint, logIndex: number, limit: number = 100, ): Promise { diff --git a/packages/data-flow/src/interfaces/index.ts b/packages/data-flow/src/interfaces/index.ts index d8366c6..a02c04e 100644 --- a/packages/data-flow/src/interfaces/index.ts +++ b/packages/data-flow/src/interfaces/index.ts @@ -12,8 +12,8 @@ export interface IEventsFetcher { * @param limit limit of events to fetch */ fetchEventsByBlockNumberAndLogIndex( - chainId: number, - blockNumber: number, + chainId: bigint, + blockNumber: bigint, logIndex: number, limit?: number, ): Promise; diff --git a/packages/data-flow/test/unit/eventsFetcher.spec.ts b/packages/data-flow/test/unit/eventsFetcher.spec.ts index df7620e..5a2de23 100644 --- a/packages/data-flow/test/unit/eventsFetcher.spec.ts +++ b/packages/data-flow/test/unit/eventsFetcher.spec.ts @@ -24,7 +24,6 @@ describe("EventsFetcher", () => { block_timestamp: 123123123, contract_name: "Allo", event_name: "PoolCreated", - event_id: "123", src_address: "0x1234567890123456789012345678901234567890", log_index: 0, params: { contractAddress: "0x1234" }, @@ -35,14 +34,13 @@ describe("EventsFetcher", () => { block_timestamp: 123123123, contract_name: "Allo", event_name: "PoolCreated", - event_id: "123", src_address: "0x1234567890123456789012345678901234567890", log_index: 0, params: { contractAddress: "0x1234" }, }, ]; - const chainId = 1; - const blockNumber = 1000; + const chainId = 1n; + const blockNumber = 1000n; const logIndex = 0; const limit = 100; @@ -64,8 +62,8 @@ describe("EventsFetcher", () => { }); it("should handle errors thrown by indexer client", async () => { - const chainId = 1; - const blockNumber = 1000; + const chainId = 1n; + const blockNumber = 1000n; const logIndex = 0; indexerClientMock.getEventsAfterBlockNumberAndLogIndex.mockRejectedValue( diff --git a/packages/indexer-client/src/interfaces/indexerClient.ts b/packages/indexer-client/src/interfaces/indexerClient.ts index e0b3a46..f1fca99 100644 --- a/packages/indexer-client/src/interfaces/indexerClient.ts +++ b/packages/indexer-client/src/interfaces/indexerClient.ts @@ -12,8 +12,8 @@ export interface IIndexerClient { * @param limit Limit of events to fetch */ getEventsAfterBlockNumberAndLogIndex( - chainId: number, - fromBlock: number, + chainId: bigint, + fromBlock: bigint, logIndex: number, limit?: number, ): Promise; diff --git a/packages/indexer-client/src/providers/envioIndexerClient.ts b/packages/indexer-client/src/providers/envioIndexerClient.ts index 8b38e41..1bfdd2f 100644 --- a/packages/indexer-client/src/providers/envioIndexerClient.ts +++ b/packages/indexer-client/src/providers/envioIndexerClient.ts @@ -16,33 +16,41 @@ export class EnvioIndexerClient implements IIndexerClient { } /* @inheritdoc */ public async getEventsAfterBlockNumberAndLogIndex( - chainId: number, - blockNumber: number, + chainId: bigint, + blockNumber: bigint, logIndex: number, limit: number = 100, ): Promise { try { - const response = (await this.client.rawRequest(gql` - query getEventsAfterBlockNumberAndLogIndex { - raw_events( - where: { - chain_id: { _eq: ${chainId} } - block_number: { _gte: ${blockNumber} } - log_index: { _gt: ${logIndex} } - } - limit: ${limit} + const response = (await this.client.request( + gql` + query getEventsAfterBlockNumberAndLogIndex( + $chainId: Int! + $blockNumber: Int! + $logIndex: Int! + $limit: Int! ) { - block_number - block_timestamp - chain_id - contract_name - event_name - log_index - params - src_address + raw_events( + where: { + chain_id: { _eq: $chainId } + block_number: { _gte: $blockNumber } + log_index: { _gt: $logIndex } + } + limit: $limit + ) { + block_number: blockNumber + block_timestamp: blockTimestamp + chain_id: chainId + contract_name: contractName + event_name: eventName + log_index: logIndex + params + src_address: srcAddress + } } - } - `)) as { data: { raw_events: AnyProtocolEvent[] } }; + `, + { chainId, blockNumber, logIndex, limit }, + )) as { data: { raw_events: AnyProtocolEvent[] } }; if (response?.data?.raw_events) { return response.data.raw_events; } else { diff --git a/packages/indexer-client/test/unit/envioIndexerClient.spec.ts b/packages/indexer-client/test/unit/envioIndexerClient.spec.ts index 97e28ce..2c46dee 100644 --- a/packages/indexer-client/test/unit/envioIndexerClient.spec.ts +++ b/packages/indexer-client/test/unit/envioIndexerClient.spec.ts @@ -12,7 +12,7 @@ vi.mock("graphql-request", async (importOriginal) => { ...mod, GraphQLClient: vi.fn().mockImplementation(() => ({ setHeader: vi.fn(), - rawRequest: vi.fn(), + request: vi.fn(), })), }; }); @@ -31,11 +31,11 @@ describe("EnvioIndexerClient", () => { }); describe("constructor", () => { - it("should create a GraphQLClient with the provided URL", () => { + it("creates a GraphQLClient with the provided URL", () => { expect(GraphQLClient).toHaveBeenCalledWith("http://example.com/graphql"); }); - it("should set the x-hasura-admin-secret header", () => { + it("sets the x-hasura-admin-secret header", () => { expect(graphqlClient.setHeader).toHaveBeenCalledWith("x-hasura-admin-secret", "secret"); }); }); @@ -48,14 +48,13 @@ describe("EnvioIndexerClient", () => { block_timestamp: 123123123, contract_name: "Allo", event_name: "PoolCreated", - event_id: "123", src_address: "0x1234567890123456789012345678901234567890", log_index: 0, params: { contractAddress: "0x1234" }, }, ]; - it("should return events when the query is successful", async () => { + it("returns events when the query is successful", async () => { const mockedResponse = { status: 200, headers: {}, @@ -63,50 +62,18 @@ describe("EnvioIndexerClient", () => { raw_events: mockEvents, }, }; - graphqlClient.rawRequest.mockResolvedValue(mockedResponse); + graphqlClient.request.mockResolvedValue(mockedResponse); const result = await envioIndexerClient.getEventsAfterBlockNumberAndLogIndex( - 1, - 12345, + 1n, + 12345n, 0, 100, ); expect(result).toEqual(mockEvents); }); - it("should use default limit when not provided", async () => { - const mockedResponse = { - status: 200, - headers: {}, - data: { - raw_events: mockEvents, - }, - }; - graphqlClient.rawRequest.mockResolvedValue(mockedResponse); - - await envioIndexerClient.getEventsAfterBlockNumberAndLogIndex(1, 12345, 0); - expect(graphqlClient.rawRequest).toHaveBeenCalledWith( - expect.stringContaining("limit: 100"), - ); - }); - - it("should use provided limit", async () => { - const mockedResponse = { - status: 200, - headers: {}, - data: { - raw_events: mockEvents, - }, - }; - graphqlClient.rawRequest.mockResolvedValue(mockedResponse); - - await envioIndexerClient.getEventsAfterBlockNumberAndLogIndex(1, 12345, 0, 50); - expect(graphqlClient.rawRequest).toHaveBeenCalledWith( - expect.stringContaining("limit: 50"), - ); - }); - - it("should throw InvalidIndexerResponse when response structure is incorrect", async () => { + it("throws InvalidIndexerResponse when response structure is incorrect", async () => { const mockedResponse = { status: 200, headers: {}, @@ -114,23 +81,23 @@ describe("EnvioIndexerClient", () => { raw_events: undefined, }, }; - graphqlClient.rawRequest.mockResolvedValue(mockedResponse); + graphqlClient.request.mockResolvedValue(mockedResponse); await expect( - envioIndexerClient.getEventsAfterBlockNumberAndLogIndex(1, 12345, 0), + envioIndexerClient.getEventsAfterBlockNumberAndLogIndex(1n, 12345n, 0), ).rejects.toThrow(InvalidIndexerResponse); }); - it("should throw IndexerClientError when GraphQL request fails", async () => { + it("throws IndexerClientError when GraphQL request fails", async () => { const error = new Error("GraphQL request failed"); - graphqlClient.rawRequest.mockRejectedValue(error); + graphqlClient.request.mockRejectedValue(error); await expect( - envioIndexerClient.getEventsAfterBlockNumberAndLogIndex(1, 12345, 0), + envioIndexerClient.getEventsAfterBlockNumberAndLogIndex(1n, 12345n, 0), ).rejects.toThrow(IndexerClientError); }); - it("should include chainId, blockNumber, and logIndex in the query", async () => { + it("uses the default limit value when limit is not provided", async () => { const mockedResponse = { status: 200, headers: {}, @@ -138,21 +105,28 @@ describe("EnvioIndexerClient", () => { raw_events: mockEvents, }, }; - graphqlClient.rawRequest.mockResolvedValue(mockedResponse); + graphqlClient.request.mockResolvedValue(mockedResponse); - await envioIndexerClient.getEventsAfterBlockNumberAndLogIndex(1, 12345, 0); - expect(graphqlClient.rawRequest).toHaveBeenCalledWith( - expect.stringContaining("chain_id: { _eq: 1 }"), - ); - expect(graphqlClient.rawRequest).toHaveBeenCalledWith( - expect.stringContaining("block_number: { _gte: 12345 }"), + // Call the method without the limit argument + const result = await envioIndexerClient.getEventsAfterBlockNumberAndLogIndex( + 1n, + 12345n, + 0, ); - expect(graphqlClient.rawRequest).toHaveBeenCalledWith( - expect.stringContaining("log_index: { _gt: 0 }"), + + expect(result).toEqual(mockEvents); + expect(graphqlClient.request).toHaveBeenCalledWith( + expect.any(String), // We can check the query string later if necessary + { + chainId: 1n, + blockNumber: 12345n, + logIndex: 0, + limit: 100, // Ensure the default limit is used + }, ); }); - it("should return an empty array when no events are found", async () => { + it("returns an empty array when no events are found", async () => { const mockedResponse = { status: 200, headers: {}, @@ -160,11 +134,11 @@ describe("EnvioIndexerClient", () => { raw_events: [], }, }; - graphqlClient.rawRequest.mockResolvedValue(mockedResponse); + graphqlClient.request.mockResolvedValue(mockedResponse); const result = await envioIndexerClient.getEventsAfterBlockNumberAndLogIndex( - 1, - 12345, + 1n, + 12345n, 0, ); expect(result).toEqual([]); diff --git a/packages/shared/src/types/events/common.ts b/packages/shared/src/types/events/common.ts index e64fb7e..3b4921b 100644 --- a/packages/shared/src/types/events/common.ts +++ b/packages/shared/src/types/events/common.ts @@ -30,15 +30,15 @@ export type EventParams * This type is used to represent a protocol event. */ export type ProtocolEvent> = { - block_number: number; - block_timestamp: number; - chain_id: number; - contract_name: T; - event_id: string; - event_name: E; - log_index: number; + //TODO: make blocknumber and chainId bigints, implies implementing adapter patterns in the EventsFetcher or IndexerClient + blockNumber: number; + blockTimestamp: number; + chainId: number; + contractName: T; + eventName: E; + logIndex: number; params: EventParams; - src_address: Address; + srcAddress: Address; }; export type AnyProtocolEvent = ProtocolEvent>;