Skip to content

Commit 3c68a31

Browse files
committed
fix: 🐛 Fixed contract events subscription fromBlock management
1 parent cff4095 commit 3c68a31

File tree

1 file changed

+35
-26
lines changed

1 file changed

+35
-26
lines changed

packages/contracts-manger/src/index.ts

+35-26
Original file line numberDiff line numberDiff line change
@@ -705,10 +705,10 @@ export class ProtocolContracts<
705705
* @param {(logs: GetFilterLogsReturnType<TAbi>) => void} onLogs Callback to execute when logs are received.
706706
* @param {bigint} [fromBlock] The block number from which to start listening for events.
707707
* @param {number} [pollInterval=1000] The interval in milliseconds at which to poll for new events.
708-
* @returns {Promise<() => void>} A promise that resolves to an unsubscribe function.
708+
* @returns {() => void} A promise that resolves to an unsubscribe function.
709709
* @private
710710
*/
711-
private async subscribeToEvents<
711+
private subscribeToEvents<
712712
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
713713
const TAbi extends Abi | readonly unknown[] = Abi,
714714
TEventName extends string | undefined = undefined,
@@ -717,38 +717,47 @@ export class ProtocolContracts<
717717
address: Address,
718718
eventName: InferEventName<TAbi, TEventName>,
719719
// eslint-disable-next-line @typescript-eslint/no-explicit-any
720-
onLogs: (logs: any) => void,
721-
fromBlock?: bigint,
720+
onLogs: (logs: any, maxBlockNumber: bigint) => void,
721+
fromBlock: bigint = 0n,
722722
pollInterval: number = 1000,
723-
): Promise<() => void> {
724-
let blockNumber = await this.publicClient.getBlockNumber();
725-
let isUnsubscribed = false;
723+
): () => void {
726724
let timeoutId: NodeJS.Timeout;
727-
728-
// Adjust starting block number if fromBlock is provided and valid
729-
if (fromBlock && fromBlock < blockNumber) {
730-
blockNumber = fromBlock;
731-
}
725+
let isUnsubscribed = false;
732726

733727
// Function to fetch and process logs
734728
const getLogs = async () => {
735729
if (isUnsubscribed) return;
736730

731+
const blockNumber = await this.publicClient.getBlockNumber();
732+
733+
// Adjust starting block number if fromBlock is provided
734+
if (fromBlock > blockNumber) {
735+
fromBlock = blockNumber;
736+
}
737+
737738
const filter = await this.publicClient.createContractEventFilter({
738739
abi,
739740
address,
740-
fromBlock: blockNumber,
741+
fromBlock,
741742
strict: true,
742743
eventName: eventName,
743744
} as unknown as FilterOptions);
744745

745746
const logs = await this.publicClient.getFilterLogs({ filter });
746747

747748
if (logs.length > 0) {
748-
onLogs(logs);
749-
// Update the block number to the next after the last log's block
750-
const bn = logs[logs.length - 1].blockNumber;
751-
blockNumber = (bn !== null ? bn : BigInt(0)) + BigInt(1);
749+
const maxBlockNumber = logs.reduce(
750+
(max, log) =>
751+
log.blockNumber !== null && log.blockNumber > max
752+
? log.blockNumber
753+
: max,
754+
0n,
755+
);
756+
757+
if (maxBlockNumber > fromBlock) {
758+
fromBlock = maxBlockNumber + 1n;
759+
onLogs(logs, maxBlockNumber);
760+
}
752761
}
753762

754763
if (!isUnsubscribed) {
@@ -776,14 +785,14 @@ export class ProtocolContracts<
776785
* @param {(logs: GetFilterLogsReturnType<typeof marketABI>) => void} onLogs Callback for when logs are received.
777786
* @param {bigint} [fromBlock] Starting block number for listening for events.
778787
* @param {number} [pollInterval=1000] Polling interval in milliseconds.
779-
* @returns {Promise<() => void>} Unsubscribe function.
788+
* @returns {() => void} Unsubscribe function.
780789
*/
781-
async subscribeMarket<TEventName extends string | undefined = undefined>(
790+
subscribeMarket<TEventName extends string | undefined = undefined>(
782791
eventName: InferEventName<typeof marketABI, TEventName>,
783792
onLogs: (logs: GetFilterLogsReturnType<typeof marketABI>) => void,
784793
fromBlock?: bigint,
785794
pollInterval: number = 1000,
786-
): Promise<() => void> {
795+
): () => void {
787796
return this.subscribeToEvents(
788797
marketABI,
789798
this.contracts['market'].address,
@@ -802,14 +811,14 @@ export class ProtocolContracts<
802811
* @param {(logs: GetFilterLogsReturnType<typeof entitiesRegistryABI>) => void} onLogs Callback for when logs are received.
803812
* @param {bigint} [fromBlock] Starting block number for listening for events.
804813
* @param {number} [pollInterval=1000] Polling interval in milliseconds.
805-
* @returns {Promise<() => void>} Unsubscribe function.
814+
* @returns {() => void} Unsubscribe function.
806815
*/
807-
async subscribeEntities<TEventName extends string | undefined = undefined>(
816+
subscribeEntities<TEventName extends string | undefined = undefined>(
808817
eventName: InferEventName<typeof entitiesRegistryABI, TEventName>,
809818
onLogs: (logs: GetFilterLogsReturnType<typeof entitiesRegistryABI>) => void,
810819
fromBlock?: bigint,
811820
pollInterval: number = 1000,
812-
): Promise<() => void> {
821+
): () => void {
813822
return this.subscribeToEvents(
814823
entitiesRegistryABI,
815824
this.contracts['entities'].address,
@@ -828,14 +837,14 @@ export class ProtocolContracts<
828837
* @param {(logs: GetFilterLogsReturnType<typeof configABI>) => void} onLogs Callback for when logs are received.
829838
* @param {bigint} [fromBlock] Starting block number for listening for events.
830839
* @param {number} [pollInterval=1000] Polling interval in milliseconds.
831-
* @returns {Promise<() => void>} Unsubscribe function.
840+
* @returns {() => void} Unsubscribe function.
832841
*/
833-
async subscribeConfig<TEventName extends string | undefined = undefined>(
842+
subscribeConfig<TEventName extends string | undefined = undefined>(
834843
eventName: InferEventName<typeof configABI, TEventName>,
835844
onLogs: (logs: GetFilterLogsReturnType<typeof configABI>) => void,
836845
fromBlock?: bigint,
837846
pollInterval: number = 1000,
838-
): Promise<() => void> {
847+
): () => void {
839848
return this.subscribeToEvents(
840849
configABI,
841850
this.contracts['config'].address,

0 commit comments

Comments
 (0)