From 2f67bb82b337055318e7588550eb578d93a69071 Mon Sep 17 00:00:00 2001 From: debuggingfuture Date: Sat, 17 Feb 2024 04:52:44 +0800 Subject: [PATCH] add: use single event listener per #91 --- packages/webapp/src/store/subscriptions.ts | 37 ++++++++++++++++------ 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/packages/webapp/src/store/subscriptions.ts b/packages/webapp/src/store/subscriptions.ts index 4abde7cc..1a7baaf8 100644 --- a/packages/webapp/src/store/subscriptions.ts +++ b/packages/webapp/src/store/subscriptions.ts @@ -11,6 +11,7 @@ // ================================================================================================= +import _ from "lodash" import { Log } from "viem" import { getPublicClient } from "wagmi/actions" @@ -75,15 +76,33 @@ export function subscribeToGame(ID: bigint|null) { } if (needsSub) { currentlySubscribedID = ID - eventNames.forEach(eventName => { - unsubFunctions.push(publicClient.watchContractEvent({ - address: deployment.Game, - abi: gameABI, - eventName: eventName as any, - args: { gameID: ID }, - onLogs: logs => gameEventListener(eventName, logs) - })) - }) + + const eventsABI = gameABI.filter((abi) => abi.type === "event" && eventNames.includes(abi.name)); + + /** + * + * Related to https://github.com/0xFableOrg/0xFable/issues/91 + * + * viem limitations: watchEvent scoped to multiple events supposedly not also scoped with indexed arguments (args). + * https://viem.sh/docs/actions/public/watchEvent.html#multiple-events + * + * use `watchEvent` (instead of watchContractEvent) which will create filter against gameID + * this is not expected usage of watchEvent and might break when upgrade + * also only works if the args (gameID) is expected across all event topics + */ + unsubFunctions.push(publicClient.watchEvent({ + address: deployment.Game, + events: eventsABI, + args: { gameID: ID }, + onLogs: logs => { + _.toPairs(_.groupBy(logs, (log:any)=>log.eventName)) + .forEach( + ([eventName, logs]:[string,any]) => { + gameEventListener(eventName, logs) + } + ) + } + })) } }