Skip to content

Commit 47c07e2

Browse files
authored
Merge pull request #83 from windingtree/feat/subscribe-contracts
feat: 🎸 Added subscribeMarket method to ProtocolsContracts
2 parents 8b405a6 + 310f526 commit 47c07e2

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

packages/contracts-manger/src/index.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import {
1515
stringToHex,
1616
getAddress,
1717
zeroAddress,
18+
GetFilterLogsReturnType,
19+
InferEventName,
1820
} from 'viem';
1921
import { stringify } from 'superjson';
2022
import {
@@ -684,4 +686,71 @@ export class ProtocolContracts<
684686
args: [id],
685687
});
686688
}
689+
690+
/**
691+
* Subscribes to specific events emitted by the market smart contract.
692+
*
693+
* @param eventName - The name of the event to listen for.
694+
* @param onLogs - Callback function to handle the event logs.
695+
* @param fromBlock - (Optional) The starting block number for listening to events.
696+
* @param pollInterval - (Optional) Interval in milliseconds for polling new events.
697+
* @returns A function to unsubscribe from the event.
698+
* @template TEventName - Generic type parameter for event name.
699+
*/
700+
async subscribeMarket<TEventName extends string | undefined = undefined>(
701+
eventName: InferEventName<typeof marketABI, TEventName>,
702+
onLogs: (logs: GetFilterLogsReturnType<typeof marketABI>) => void,
703+
fromBlock?: bigint,
704+
pollInterval = 1000,
705+
): Promise<() => void> {
706+
let blockNumber = await this.publicClient.getBlockNumber();
707+
let isUnsubscribed = false;
708+
let timeoutId: NodeJS.Timeout;
709+
710+
// Use the specified fromBlock or the current block number
711+
if (fromBlock && fromBlock < blockNumber) {
712+
blockNumber = fromBlock;
713+
}
714+
715+
// Function to fetch and process logs
716+
const getLogs = async () => {
717+
if (isUnsubscribed) return; // Stop if unsubscribed
718+
719+
// Create an event filter
720+
const filter = await this.publicClient.createContractEventFilter({
721+
abi: marketABI,
722+
address: this.contracts['market'].address,
723+
eventName,
724+
fromBlock: blockNumber,
725+
strict: true,
726+
});
727+
728+
// Retrieve logs based on the filter
729+
const logs = await this.publicClient.getFilterLogs({ filter });
730+
731+
// Process logs and update the block number
732+
if (logs.length > 0) {
733+
const maxBlockNumber = logs.reduce(
734+
(max, log) => (log.blockNumber > max ? log.blockNumber : max),
735+
BigInt(0),
736+
);
737+
blockNumber = maxBlockNumber + BigInt(1);
738+
onLogs(logs);
739+
}
740+
741+
// Schedule the next call
742+
timeoutId = setTimeout(() => {
743+
getLogs().catch(logger.error);
744+
}, pollInterval);
745+
};
746+
747+
// Initial call to start the polling process
748+
getLogs().catch(logger.error);
749+
750+
// Return the unsubscribe function
751+
return () => {
752+
isUnsubscribed = true; // Set the flag to stop further polling
753+
clearTimeout(timeoutId); // Clear the timeout to stop scheduled calls
754+
};
755+
}
687756
}

0 commit comments

Comments
 (0)