From be7bbf1b0b7c01a49ede6d3b77520cc214f3b3ee Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Sat, 28 Mar 2026 12:30:44 +0100 Subject: [PATCH 01/11] Create `addOnchainEventListener` function Works as a thin wrapper over `ponder.on` function. This enabled adding some control logic while indexing onchain events. --- .../add-onchain-event-listener.test.ts | 25 +++++++++++++++++++ .../add-onchain-event-listener.ts | 17 +++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 apps/ensindexer/src/lib/onchain-events/add-onchain-event-listener.test.ts create mode 100644 apps/ensindexer/src/lib/onchain-events/add-onchain-event-listener.ts diff --git a/apps/ensindexer/src/lib/onchain-events/add-onchain-event-listener.test.ts b/apps/ensindexer/src/lib/onchain-events/add-onchain-event-listener.test.ts new file mode 100644 index 000000000..91f7974ab --- /dev/null +++ b/apps/ensindexer/src/lib/onchain-events/add-onchain-event-listener.test.ts @@ -0,0 +1,25 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +const mockPonderOn = vi.fn(); + +vi.mock("ponder:registry", () => ({ + ponder: { + on: mockPonderOn, + }, +})); + +describe("addOnchainEventListener", () => { + beforeEach(() => { + vi.resetModules(); + vi.clearAllMocks(); + }); + + it("should call ponder.on with the correct event name and handler", async () => { + const { addOnchainEventListener } = await import("./add-onchain-event-listener"); + const testHandler = vi.fn(); + + addOnchainEventListener("Resolver:AddrChanged", testHandler); + + expect(mockPonderOn).toHaveBeenCalledWith("Resolver:AddrChanged", testHandler); + }); +}); diff --git a/apps/ensindexer/src/lib/onchain-events/add-onchain-event-listener.ts b/apps/ensindexer/src/lib/onchain-events/add-onchain-event-listener.ts new file mode 100644 index 000000000..95700160a --- /dev/null +++ b/apps/ensindexer/src/lib/onchain-events/add-onchain-event-listener.ts @@ -0,0 +1,17 @@ +import { type EventNames, type IndexingFunctionArgs, ponder } from "ponder:registry"; + +/** + * Adds an event listener for a specific event. + * + * This is a thin wrapper around `ponder.on` that allows executing additional logic + * before or after the event handler if needed. + * + * For more details on `ponder.on`, see the Ponder indexing guide. + * @see https://ponder.sh/docs/indexing/overview#register-an-indexing-function + */ +export function addOnchainEventListener( + eventName: EventName, + eventHandler: (args: IndexingFunctionArgs) => Promise | void, +) { + return ponder.on(eventName, eventHandler); +} From 516741efbbc0d9a437c5a0be80b81f758d65827b Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Sat, 28 Mar 2026 12:31:14 +0100 Subject: [PATCH 02/11] Replace `ponder.on` with `addOnchainEventListener` Mechanical updates only. --- .../ensv2/handlers/ensv1/BaseRegistrar.ts | 14 ++- .../ensv2/handlers/ensv1/ENSv1Registry.ts | 22 +++-- .../ensv2/handlers/ensv1/NameWrapper.ts | 18 ++-- .../handlers/ensv1/RegistrarController.ts | 17 ++-- .../ensv2/handlers/ensv2/ENSv2Registry.ts | 18 ++-- .../ensv2/handlers/ensv2/ETHRegistrar.ts | 7 +- .../handlers/ensv2/EnhancedAccessControl.ts | 5 +- .../plugins/ensv2/handlers/shared/Resolver.ts | 61 ++++++++++--- .../handlers/ENSv1Registry.ts | 9 +- .../handlers/ENSv2Registry.ts | 5 +- .../handlers/Resolver.ts | 55 ++++++----- .../handlers/StandaloneReverseRegistrar.ts | 4 +- .../handlers/ThreeDNSToken.ts | 5 +- .../basenames/handlers/Basenames_Registrar.ts | 9 +- .../handlers/Basenames_RegistrarController.ts | 13 ++- .../ethnames/handlers/Ethnames_Registrar.ts | 7 +- .../handlers/Ethnames_RegistrarController.ts | 15 ++- ...s_UniversalRegistrarRenewalWithReferrer.ts | 5 +- .../handlers/Lineanames_Registrar.ts | 7 +- .../Lineanames_RegistrarController.ts | 11 +-- .../plugins/basenames/handlers/Registrar.ts | 40 ++++---- .../plugins/basenames/handlers/Registry.ts | 13 ++- .../lineanames/handlers/NameWrapper.ts | 30 ++++-- .../plugins/lineanames/handlers/Registrar.ts | 36 ++++---- .../plugins/lineanames/handlers/Registry.ts | 13 ++- .../plugins/subgraph/handlers/NameWrapper.ts | 30 ++++-- .../plugins/subgraph/handlers/Registrar.ts | 48 +++++----- .../plugins/subgraph/handlers/Registry.ts | 27 ++++-- .../threedns/handlers/ThreeDNSResolver.ts | 54 +++++++---- .../threedns/handlers/ThreeDNSToken.ts | 13 ++- .../shared-handlers/multi-chain/Resolver.ts | 34 +++---- .../tokenscope/handlers/BaseRegistrars.ts | 9 +- .../tokenscope/handlers/NameWrapper.ts | 7 +- .../plugins/tokenscope/handlers/Seaport.ts | 91 ++++++++++--------- .../tokenscope/handlers/ThreeDNSToken.ts | 12 +-- 35 files changed, 439 insertions(+), 325 deletions(-) diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts index acd6296a1..e822e82ba 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts @@ -1,4 +1,4 @@ -import { type Context, ponder } from "ponder:registry"; +import type { Context } from "ponder:registry"; import schema from "ponder:schema"; import { GRACE_PERIOD_SECONDS } from "@ensdomains/ensjs/utils"; import { type Address, isAddressEqual, zeroAddress } from "viem"; @@ -23,6 +23,7 @@ import { import { getThisAccountId } from "@/lib/get-this-account-id"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { getManagedName } from "@/lib/managed-names"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; @@ -42,7 +43,7 @@ const pluginName = PluginName.ENSv2; * exists and materialize its effective owner correctly. */ export default function () { - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "BaseRegistrar:Transfer"), async ({ context, @@ -143,13 +144,16 @@ export default function () { await ensureDomainEvent(context, event, domainId); } - ponder.on(namespaceContract(pluginName, "BaseRegistrar:NameRegistered"), handleNameRegistered); - ponder.on( + addOnchainEventListener( + namespaceContract(pluginName, "BaseRegistrar:NameRegistered"), + handleNameRegistered, + ); + addOnchainEventListener( namespaceContract(pluginName, "BaseRegistrar:NameRegisteredWithRecord"), handleNameRegistered, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "BaseRegistrar:NameRenewed"), async ({ context, diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts index 5b228c1fb..e78ce885e 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts @@ -1,6 +1,6 @@ import config from "@/config"; -import { type Context, ponder } from "ponder:registry"; +import type { Context } from "ponder:registry"; import schema from "ponder:schema"; import { type Address, isAddressEqual, zeroAddress } from "viem"; @@ -20,6 +20,7 @@ import { materializeENSv1DomainEffectiveOwner } from "@/lib/ensv2/domain-db-help import { ensureDomainEvent } from "@/lib/ensv2/event-db-helpers"; import { ensureLabel, ensureUnknownLabel } from "@/lib/ensv2/label-db-helpers"; import { healAddrReverseSubnameLabel } from "@/lib/heal-addr-reverse-subname-label"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { nodeIsMigrated } from "@/lib/protocol-acceleration/registry-migration-status"; @@ -169,7 +170,7 @@ export default function () { * Handles Registry#NewOwner for: * - ENS Root Chain's ENSv1RegistryOld */ - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ENSv1RegistryOld:NewOwner"), async ({ context, event }) => { const { label: labelHash, node: parentNode } = event.args; @@ -187,7 +188,7 @@ export default function () { * Handles Registry#Transfer for: * - ENS Root Chain's ENSv1RegistryOld */ - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ENSv1RegistryOld:Transfer"), async ({ context, event }) => { const shouldIgnoreEvent = await nodeIsMigrated(context, event.args.node); @@ -201,7 +202,7 @@ export default function () { * Handles Registry#NewTTL for: * - ENS Root Chain's ENSv1RegistryOld */ - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ENSv1RegistryOld:NewTTL"), async ({ context, event }) => { const shouldIgnoreEvent = await nodeIsMigrated(context, event.args.node); @@ -215,7 +216,7 @@ export default function () { * Handles Registry#NewResolver for: * - ENS Root Chain's ENSv1RegistryOld */ - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ENSv1RegistryOld:NewResolver"), async ({ context, event }) => { const shouldIgnoreEvent = await nodeIsMigrated(context, event.args.node); @@ -231,8 +232,11 @@ export default function () { * - Basenames Registry * - Lineanames Registry */ - ponder.on(namespaceContract(pluginName, "ENSv1Registry:NewOwner"), handleNewOwner); - ponder.on(namespaceContract(pluginName, "ENSv1Registry:Transfer"), handleTransfer); - ponder.on(namespaceContract(pluginName, "ENSv1Registry:NewTTL"), handleNewTTL); - ponder.on(namespaceContract(pluginName, "ENSv1Registry:NewResolver"), handleNewResolver); + addOnchainEventListener(namespaceContract(pluginName, "ENSv1Registry:NewOwner"), handleNewOwner); + addOnchainEventListener(namespaceContract(pluginName, "ENSv1Registry:Transfer"), handleTransfer); + addOnchainEventListener(namespaceContract(pluginName, "ENSv1Registry:NewTTL"), handleNewTTL); + addOnchainEventListener( + namespaceContract(pluginName, "ENSv1Registry:NewResolver"), + handleNewResolver, + ); } diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts index 50fb804e0..e6de75069 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts @@ -1,4 +1,4 @@ -import { type Context, ponder } from "ponder:registry"; +import type { Context } from "ponder:registry"; import schema from "ponder:schema"; import { type Address, isAddressEqual, zeroAddress } from "viem"; @@ -32,6 +32,7 @@ import { import { getThisAccountId } from "@/lib/get-this-account-id"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { getManagedName } from "@/lib/managed-names"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; @@ -138,7 +139,7 @@ export default function () { await ensureDomainEvent(context, event, domainId); } - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "NameWrapper:NameWrapped"), async ({ context, @@ -258,7 +259,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "NameWrapper:NameUnwrapped"), async ({ context, @@ -300,7 +301,7 @@ export default function () { /** * FusesSet can occur for expired or unexpired Registrations. */ - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "NameWrapper:FusesSet"), async ({ context, @@ -335,7 +336,7 @@ export default function () { /** * ExpiryExtended can occur for expired or unexpired Registrations. */ - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "NameWrapper:ExpiryExtended"), async ({ context, @@ -392,8 +393,11 @@ export default function () { }, ); - ponder.on(namespaceContract(pluginName, "NameWrapper:TransferSingle"), handleTransfer); - ponder.on( + addOnchainEventListener( + namespaceContract(pluginName, "NameWrapper:TransferSingle"), + handleTransfer, + ); + addOnchainEventListener( namespaceContract(pluginName, "NameWrapper:TransferBatch"), async ({ context, event }) => { for (const id of event.args.ids) { diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts index cfce030a5..813c722a1 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts @@ -1,5 +1,5 @@ /** biome-ignore-all lint/correctness/noUnusedVariables: ignore for now */ -import { type Context, ponder } from "ponder:registry"; +import type { Context } from "ponder:registry"; import schema from "ponder:schema"; import { @@ -19,6 +19,7 @@ import { getLatestRegistration, getLatestRenewal } from "@/lib/ensv2/registratio import { getThisAccountId } from "@/lib/get-this-account-id"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { getManagedName } from "@/lib/managed-names"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; @@ -154,7 +155,7 @@ export default function () { ////////////////////////////////////// // RegistrarController:NameRegistered ////////////////////////////////////// - ponder.on( + addOnchainEventListener( namespaceContract( pluginName, "RegistrarController:NameRegistered(string label, bytes32 indexed labelhash, address indexed owner, uint256 baseCost, uint256 premium, uint256 expires, bytes32 referrer)", @@ -168,7 +169,7 @@ export default function () { }, }), ); - ponder.on( + addOnchainEventListener( namespaceContract( pluginName, "RegistrarController:NameRegistered(string name, bytes32 indexed label, address indexed owner, uint256 baseCost, uint256 premium, uint256 expires)", @@ -182,7 +183,7 @@ export default function () { }, }), ); - ponder.on( + addOnchainEventListener( namespaceContract( pluginName, "RegistrarController:NameRegistered(string name, bytes32 indexed label, address indexed owner, uint256 cost, uint256 expires)", @@ -196,7 +197,7 @@ export default function () { }, }), ); - ponder.on( + addOnchainEventListener( namespaceContract( pluginName, "RegistrarController:NameRegistered(string name, bytes32 indexed label, address indexed owner, uint256 expires)", @@ -214,7 +215,7 @@ export default function () { /////////////////////////////////// // RegistrarController:NameRenewed /////////////////////////////////// - ponder.on( + addOnchainEventListener( namespaceContract( pluginName, "RegistrarController:NameRenewed(string label, bytes32 indexed labelhash, uint256 cost, uint256 expires, bytes32 referrer)", @@ -228,7 +229,7 @@ export default function () { }, }), ); - ponder.on( + addOnchainEventListener( namespaceContract( pluginName, "RegistrarController:NameRenewed(string name, bytes32 indexed label, uint256 cost, uint256 expires)", @@ -248,7 +249,7 @@ export default function () { }, }), ); - ponder.on( + addOnchainEventListener( namespaceContract( pluginName, "RegistrarController:NameRenewed(string name, bytes32 indexed label, uint256 expires)", diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts index b2a513e91..d387dab69 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts @@ -1,4 +1,4 @@ -import { type Context, ponder } from "ponder:registry"; +import type { Context } from "ponder:registry"; import schema from "ponder:schema"; import { type Address, hexToBigInt, labelhash } from "viem"; @@ -23,13 +23,14 @@ import { } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; import { toJson } from "@/lib/json-stringify-with-bigints"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; const pluginName = PluginName.ENSv2; export default function () { - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ENSv2Registry:NameRegistered"), async ({ context, @@ -128,7 +129,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ENSv2Registry:ExpiryUpdated"), async ({ context, @@ -170,7 +171,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ENSv2Registry:SubregistryUpdated"), async ({ context, @@ -222,7 +223,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ENSv2Registry:TokenRegenerated"), async ({ context, @@ -280,8 +281,11 @@ export default function () { await ensureDomainEvent(context, event, domainId); } - ponder.on(namespaceContract(pluginName, "ENSv2Registry:TransferSingle"), handleTransferSingle); - ponder.on( + addOnchainEventListener( + namespaceContract(pluginName, "ENSv2Registry:TransferSingle"), + handleTransferSingle, + ); + addOnchainEventListener( namespaceContract(pluginName, "ENSv2Registry:TransferBatch"), async ({ context, event }) => { for (const id of event.args.ids) { diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts index b2ea3cdaf..4bd08b956 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts @@ -1,4 +1,4 @@ -import { type Context, ponder } from "ponder:registry"; +import type { Context } from "ponder:registry"; import schema from "ponder:schema"; import type { Address } from "viem"; @@ -18,6 +18,7 @@ import { ensureDomainEvent, ensureEvent } from "@/lib/ensv2/event-db-helpers"; import { getLatestRegistration, insertLatestRenewal } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; import { toJson } from "@/lib/json-stringify-with-bigints"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs, LogEventBase } from "@/lib/ponder-helpers"; @@ -39,7 +40,7 @@ async function getRegistrarAndRegistry(context: Context, event: LogEventBase) { } export default function () { - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ETHRegistrar:NameRegistered"), async ({ context, @@ -118,7 +119,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ETHRegistrar:NameRenewed"), async ({ context, diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts index 589adeae8..d66ebb1ab 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts @@ -1,4 +1,4 @@ -import { type Context, ponder } from "ponder:registry"; +import type { Context } from "ponder:registry"; import schema from "ponder:schema"; import { type Address, isAddressEqual, zeroAddress } from "viem"; @@ -12,6 +12,7 @@ import { import { ensureAccount } from "@/lib/ensv2/account-db-helpers"; import { ensurePermissionsEvent } from "@/lib/ensv2/event-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; @@ -44,7 +45,7 @@ const ensurePermissionsResource = async ( const isZeroRoles = (roles: bigint) => roles === 0n; export default function () { - ponder.on( + addOnchainEventListener( namespaceContract(PluginName.ENSv2, "EnhancedAccessControl:EACRolesChanged"), async ({ context, diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts b/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts index 8f344afcc..1fa7aa3f4 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts @@ -1,9 +1,10 @@ -import { type Context, ponder } from "ponder:registry"; +import type { Context } from "ponder:registry"; import { PluginName } from "@ensnode/ensnode-sdk"; import { ensureResolverEvent } from "@/lib/ensv2/event-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { LogEventBase } from "@/lib/ponder-helpers"; @@ -27,18 +28,48 @@ export default function () { await ensureResolverEvent(context, event, resolver); } - ponder.on(namespaceContract(pluginName, "Resolver:AddrChanged"), handleResolverEvent); - ponder.on(namespaceContract(pluginName, "Resolver:AddressChanged"), handleResolverEvent); - ponder.on(namespaceContract(pluginName, "Resolver:NameChanged"), handleResolverEvent); - ponder.on(namespaceContract(pluginName, "Resolver:ContenthashChanged"), handleResolverEvent); - ponder.on(namespaceContract(pluginName, "Resolver:ABIChanged"), handleResolverEvent); - ponder.on(namespaceContract(pluginName, "Resolver:PubkeyChanged"), handleResolverEvent); - ponder.on(namespaceContract(pluginName, "Resolver:InterfaceChanged"), handleResolverEvent); - ponder.on(namespaceContract(pluginName, "Resolver:AuthorisationChanged"), handleResolverEvent); - ponder.on(namespaceContract(pluginName, "Resolver:VersionChanged"), handleResolverEvent); - ponder.on(namespaceContract(pluginName, "Resolver:DNSRecordDeleted"), handleResolverEvent); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:AddrChanged"), + handleResolverEvent, + ); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:AddressChanged"), + handleResolverEvent, + ); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:NameChanged"), + handleResolverEvent, + ); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:ContenthashChanged"), + handleResolverEvent, + ); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:ABIChanged"), + handleResolverEvent, + ); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:PubkeyChanged"), + handleResolverEvent, + ); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:InterfaceChanged"), + handleResolverEvent, + ); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:AuthorisationChanged"), + handleResolverEvent, + ); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:VersionChanged"), + handleResolverEvent, + ); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:DNSRecordDeleted"), + handleResolverEvent, + ); - ponder.on( + addOnchainEventListener( namespaceContract( pluginName, "Resolver:TextChanged(bytes32 indexed node, string indexed indexedKey, string key)", @@ -46,7 +77,7 @@ export default function () { handleResolverEvent, ); - ponder.on( + addOnchainEventListener( namespaceContract( pluginName, "Resolver:TextChanged(bytes32 indexed node, string indexed indexedKey, string key, string value)", @@ -54,7 +85,7 @@ export default function () { handleResolverEvent, ); - ponder.on( + addOnchainEventListener( namespaceContract( pluginName, "Resolver:DNSRecordChanged(bytes32 indexed node, bytes name, uint16 resource, bytes record)", @@ -62,7 +93,7 @@ export default function () { handleResolverEvent, ); - ponder.on( + addOnchainEventListener( namespaceContract( pluginName, "Resolver:DNSRecordChanged(bytes32 indexed node, bytes name, uint16 resource, uint32 ttl, bytes record)", diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts index 91b2dd996..f32115401 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts @@ -1,6 +1,6 @@ import config from "@/config"; -import { type Context, ponder } from "ponder:registry"; +import type { Context } from "ponder:registry"; import type { Address } from "viem"; import { getENSRootChainId } from "@ensnode/datasources"; @@ -13,6 +13,7 @@ import { } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { ensureDomainResolverRelation } from "@/lib/protocol-acceleration/domain-resolver-relationship-db-helpers"; @@ -47,7 +48,7 @@ export default function () { * Handles Registry#NewOwner for: * - ENS Root Chain's (new) Registry */ - ponder.on( + addOnchainEventListener( namespaceContract(PluginName.ProtocolAcceleration, "ENSv1Registry:NewOwner"), async ({ context, @@ -75,7 +76,7 @@ export default function () { * Handles Registry#NewResolver for: * - ENS Root Chain's ENSv1RegistryOld */ - ponder.on( + addOnchainEventListener( namespaceContract(PluginName.ProtocolAcceleration, "ENSv1RegistryOld:NewResolver"), async ({ context, @@ -98,7 +99,7 @@ export default function () { * - Basename's (shadow) Registry * - Lineanames's (shadow) Registry */ - ponder.on( + addOnchainEventListener( namespaceContract(PluginName.ProtocolAcceleration, "ENSv1Registry:NewResolver"), handleNewResolver, ); diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts index e918bc447..51d89db5c 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts @@ -1,9 +1,10 @@ -import { type Context, ponder } from "ponder:registry"; +import type { Context } from "ponder:registry"; import type { Address } from "viem"; import { getCanonicalId, makeENSv2DomainId, PluginName } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { ensureDomainResolverRelation } from "@/lib/protocol-acceleration/domain-resolver-relationship-db-helpers"; @@ -11,7 +12,7 @@ import { ensureDomainResolverRelation } from "@/lib/protocol-acceleration/domain const pluginName = PluginName.ProtocolAcceleration; export default function () { - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ENSv2Registry:ResolverUpdated"), async ({ context, diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/Resolver.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/Resolver.ts index ac5a97d83..2b6e02685 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/Resolver.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/Resolver.ts @@ -1,10 +1,9 @@ -import { ponder } from "ponder:registry"; - import { ResolverABI } from "@ensnode/datasources"; import { bigintToCoinType, type CoinType, ETH_COIN_TYPE, PluginName } from "@ensnode/ensnode-sdk"; import { parseDnsTxtRecordArgs } from "@/lib/dns-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { ensureResolver, @@ -22,19 +21,22 @@ const pluginName = PluginName.ProtocolAcceleration; * - indexes all Resolver Records described by protocol-acceleration.schema.ts */ export default function () { - ponder.on(namespaceContract(pluginName, "Resolver:AddrChanged"), async ({ context, event }) => { - const { a: address } = event.args; - const resolver = getThisAccountId(context, event); - await ensureResolver(context, resolver); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:AddrChanged"), + async ({ context, event }) => { + const { a: address } = event.args; + const resolver = getThisAccountId(context, event); + await ensureResolver(context, resolver); - const resolverRecordsKey = makeResolverRecordsCompositeKey(resolver, event); - await ensureResolverRecords(context, resolverRecordsKey); + const resolverRecordsKey = makeResolverRecordsCompositeKey(resolver, event); + await ensureResolverRecords(context, resolverRecordsKey); - // the Resolver#AddrChanged event is just Resolver#AddressChanged with implicit coinType of ETH - await handleResolverAddressRecordUpdate(context, resolverRecordsKey, ETH_COIN_TYPE, address); - }); + // the Resolver#AddrChanged event is just Resolver#AddressChanged with implicit coinType of ETH + await handleResolverAddressRecordUpdate(context, resolverRecordsKey, ETH_COIN_TYPE, address); + }, + ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Resolver:AddressChanged"), async ({ context, event }) => { const { coinType: _coinType, newAddress } = event.args; @@ -57,19 +59,22 @@ export default function () { }, ); - ponder.on(namespaceContract(pluginName, "Resolver:NameChanged"), async ({ context, event }) => { - const { name } = event.args; + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:NameChanged"), + async ({ context, event }) => { + const { name } = event.args; - const resolver = getThisAccountId(context, event); - await ensureResolver(context, resolver); + const resolver = getThisAccountId(context, event); + await ensureResolver(context, resolver); - const resolverRecordsKey = makeResolverRecordsCompositeKey(resolver, event); - await ensureResolverRecords(context, resolverRecordsKey); + const resolverRecordsKey = makeResolverRecordsCompositeKey(resolver, event); + await ensureResolverRecords(context, resolverRecordsKey); - await handleResolverNameUpdate(context, resolverRecordsKey, name); - }); + await handleResolverNameUpdate(context, resolverRecordsKey, name); + }, + ); - ponder.on( + addOnchainEventListener( namespaceContract( PluginName.ProtocolAcceleration, "Resolver:TextChanged(bytes32 indexed node, string indexed indexedKey, string key)", @@ -101,7 +106,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract( PluginName.ProtocolAcceleration, "Resolver:TextChanged(bytes32 indexed node, string indexed indexedKey, string key, string value)", @@ -121,7 +126,7 @@ export default function () { // ens-contracts' IDNSRecordResolver#DNSRecordChanged // https://github.com/ensdomains/ens-contracts/blob/85ddeb9f/contracts/resolvers/profiles/IDNSRecordResolver.sol#L6 - ponder.on( + addOnchainEventListener( namespaceContract( PluginName.ProtocolAcceleration, "Resolver:DNSRecordChanged(bytes32 indexed node, bytes name, uint16 resource, bytes record)", @@ -141,7 +146,7 @@ export default function () { ); // 3DNS' IDNSRecordResolver#DNSRecordChanged (includes `ttl` parameter) - ponder.on( + addOnchainEventListener( namespaceContract( PluginName.ProtocolAcceleration, "Resolver:DNSRecordChanged(bytes32 indexed node, bytes name, uint16 resource, uint32 ttl, bytes record)", @@ -160,7 +165,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Resolver:DNSRecordDeleted"), async ({ context, event }) => { const { key } = parseDnsTxtRecordArgs(event.args); diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts index 19ad6b5d6..fddc8c31a 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts @@ -1,12 +1,12 @@ import config from "@/config"; -import { ponder } from "ponder:registry"; import schema from "ponder:schema"; import { getENSRootChainId } from "@ensnode/datasources"; import { DEFAULT_EVM_COIN_TYPE, evmChainIdToCoinType, PluginName } from "@ensnode/ensnode-sdk"; import { interpretNameRecordValue } from "@ensnode/ensnode-sdk/internal"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; /** @@ -15,7 +15,7 @@ import { namespaceContract } from "@/lib/plugin-helpers"; * - indexes ENSIP-19 Reverse Name Records for an address, per-coinType (derived from context.chain.id) */ export default function () { - ponder.on( + addOnchainEventListener( namespaceContract( PluginName.ProtocolAcceleration, "StandaloneReverseRegistrar:NameForAddrChanged", diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts index 66236871e..05c20c006 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts @@ -1,6 +1,6 @@ import config from "@/config"; -import { type Context, ponder } from "ponder:registry"; +import type { Context } from "ponder:registry"; import type { Address } from "viem"; import { DatasourceNames, maybeGetDatasource } from "@ensnode/datasources"; @@ -14,6 +14,7 @@ import { } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { ensureDomainResolverRelation } from "@/lib/protocol-acceleration/domain-resolver-relationship-db-helpers"; @@ -38,7 +39,7 @@ const ThreeDNSResolverByChainId: Record = [ * - indexes Node-Resolver Relationships for all nodes registred in ThreeDNSToken */ export default function () { - ponder.on( + addOnchainEventListener( namespaceContract(PluginName.ProtocolAcceleration, "ThreeDNSToken:NewOwner"), async ({ context, diff --git a/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_Registrar.ts b/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_Registrar.ts index 9009c646e..56d75aa19 100644 --- a/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_Registrar.ts +++ b/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_Registrar.ts @@ -1,5 +1,3 @@ -import { ponder } from "ponder:registry"; - import { type BlockRef, bigIntToNumber, @@ -11,6 +9,7 @@ import { import { getThisAccountId } from "@/lib/get-this-account-id"; import { getManagedName } from "@/lib/managed-names"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { @@ -26,7 +25,7 @@ export default function () { const pluginName = PluginName.Registrars; // support NameRegisteredWithRecord for BaseRegistrar as it used by Base's RegistrarControllers - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Basenames_BaseRegistrar:NameRegisteredWithRecord"), async ({ context, event }) => { const id = event.id; @@ -59,7 +58,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Basenames_BaseRegistrar:NameRegistered"), async ({ context, event }) => { const id = event.id; @@ -92,7 +91,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Basenames_BaseRegistrar:NameRenewed"), async ({ context, event }) => { const id = event.id; diff --git a/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_RegistrarController.ts b/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_RegistrarController.ts index 70141f260..fefcd7f3a 100644 --- a/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_RegistrarController.ts +++ b/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_RegistrarController.ts @@ -1,5 +1,3 @@ -import { ponder } from "ponder:registry"; - import { makeSubdomainNode, PluginName, @@ -9,6 +7,7 @@ import { import { getThisAccountId } from "@/lib/get-this-account-id"; import { getManagedName } from "@/lib/managed-names"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { handleRegistrarControllerEvent } from "../../shared/lib/registrar-controller-events"; @@ -45,7 +44,7 @@ export default function () { * Basenames_EARegistrarController Event Handlers */ - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Basenames_EARegistrarController:NameRegistered"), async ({ context, event }) => { const { @@ -75,7 +74,7 @@ export default function () { * Basenames_RegistrarController Event Handlers */ - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Basenames_RegistrarController:NameRegistered"), async ({ context, event }) => { const { @@ -101,7 +100,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Basenames_RegistrarController:NameRenewed"), async ({ context, event }) => { const { @@ -131,7 +130,7 @@ export default function () { * Basenames_UpgradeableRegistrarController Event Handlers */ - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Basenames_UpgradeableRegistrarController:NameRegistered"), async ({ context, event }) => { const { @@ -157,7 +156,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Basenames_UpgradeableRegistrarController:NameRenewed"), async ({ context, event }) => { const { diff --git a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_Registrar.ts b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_Registrar.ts index ee93838d6..22417ab45 100644 --- a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_Registrar.ts +++ b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_Registrar.ts @@ -1,5 +1,3 @@ -import { ponder } from "ponder:registry"; - import { type BlockRef, bigIntToNumber, @@ -11,6 +9,7 @@ import { import { getThisAccountId } from "@/lib/get-this-account-id"; import { getManagedName } from "@/lib/managed-names"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { @@ -25,7 +24,7 @@ import { upsertSubregistry } from "../../shared/lib/subregistry"; export default function () { const pluginName = PluginName.Registrars; - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Ethnames_BaseRegistrar:NameRegistered"), async ({ context, event }) => { const id = event.id; @@ -58,7 +57,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Ethnames_BaseRegistrar:NameRenewed"), async ({ context, event }) => { const id = event.id; diff --git a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts index 4d1fbfdd1..e01fe4cea 100644 --- a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts +++ b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts @@ -1,5 +1,3 @@ -import { ponder } from "ponder:registry"; - import { addPrices, decodeEncodedReferrer, @@ -13,6 +11,7 @@ import { import { getThisAccountId } from "@/lib/get-this-account-id"; import { getManagedName } from "@/lib/managed-names"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { handleRegistrarControllerEvent } from "../../shared/lib/registrar-controller-events"; @@ -27,7 +26,7 @@ export default function () { * Ethnames_LegacyEthRegistrarController Event Handlers */ - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Ethnames_LegacyEthRegistrarController:NameRegistered"), async ({ context, event }) => { const { @@ -75,7 +74,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Ethnames_LegacyEthRegistrarController:NameRenewed"), async ({ context, event }) => { const { @@ -129,7 +128,7 @@ export default function () { * Ethnames_WrappedEthRegistrarController Event Handlers */ - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Ethnames_WrappedEthRegistrarController:NameRegistered"), async ({ context, event }) => { const { @@ -176,7 +175,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Ethnames_WrappedEthRegistrarController:NameRenewed"), async ({ context, event }) => { const { @@ -229,7 +228,7 @@ export default function () { * Ethnames_UnwrappedEthRegistrarController Event Handlers */ - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Ethnames_UnwrappedEthRegistrarController:NameRegistered"), async ({ context, event }) => { const { @@ -279,7 +278,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Ethnames_UnwrappedEthRegistrarController:NameRenewed"), async ({ context, event }) => { const { diff --git a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts index 5b6273515..6713299ff 100644 --- a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts +++ b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts @@ -1,5 +1,3 @@ -import { ponder } from "ponder:registry"; - import { decodeEncodedReferrer, makeSubdomainNode, @@ -9,6 +7,7 @@ import { import { getThisAccountId } from "@/lib/get-this-account-id"; import { getManagedName } from "@/lib/managed-names"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { handleUniversalRegistrarRenewalEvent } from "@/plugins/registrars/shared/lib/universal-registrar-renewal-with-referrer-events"; @@ -18,7 +17,7 @@ import { handleUniversalRegistrarRenewalEvent } from "@/plugins/registrars/share export default function () { const pluginName = PluginName.Registrars; - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Ethnames_UniversalRegistrarRenewalWithReferrer:RenewalReferred"), async ({ context, event }) => { const { diff --git a/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_Registrar.ts b/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_Registrar.ts index 723456344..ca5735fae 100644 --- a/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_Registrar.ts +++ b/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_Registrar.ts @@ -1,5 +1,3 @@ -import { ponder } from "ponder:registry"; - import { type BlockRef, bigIntToNumber, @@ -11,6 +9,7 @@ import { import { getThisAccountId } from "@/lib/get-this-account-id"; import { getManagedName } from "@/lib/managed-names"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { @@ -25,7 +24,7 @@ import { upsertSubregistry } from "../../shared/lib/subregistry"; export default function () { const pluginName = PluginName.Registrars; - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Lineanames_BaseRegistrar:NameRegistered"), async ({ context, event }) => { const id = event.id; @@ -58,7 +57,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Lineanames_BaseRegistrar:NameRenewed"), async ({ context, event }) => { const id = event.id; diff --git a/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_RegistrarController.ts b/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_RegistrarController.ts index 16b8c36c2..baf2990f9 100644 --- a/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_RegistrarController.ts +++ b/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_RegistrarController.ts @@ -1,5 +1,3 @@ -import { ponder } from "ponder:registry"; - import { addPrices, makeSubdomainNode, @@ -11,6 +9,7 @@ import { import { getThisAccountId } from "@/lib/get-this-account-id"; import { getManagedName } from "@/lib/managed-names"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { handleRegistrarControllerEvent } from "../../shared/lib/registrar-controller-events"; @@ -34,7 +33,7 @@ export default function () { * Lineanames_EthRegistrarController Event Handlers */ - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Lineanames_EthRegistrarController:OwnerNameRegistered"), async ({ context, event }) => { const { @@ -71,7 +70,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Lineanames_EthRegistrarController:PohNameRegistered"), async ({ context, event }) => { const { @@ -108,7 +107,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Lineanames_EthRegistrarController:NameRegistered"), async ({ context, event }) => { const { @@ -143,7 +142,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "Lineanames_EthRegistrarController:NameRenewed"), async ({ context, event }) => { const { diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registrar.ts b/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registrar.ts index c36b8958a..86286171f 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registrar.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registrar.ts @@ -1,7 +1,6 @@ -import { ponder } from "ponder:registry"; - import { interpretTokenIdAsLabelHash, PluginName } from "@ensnode/ensnode-sdk"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { makeRegistrarHandlers } from "@/plugins/subgraph/shared-handlers/Registrar"; @@ -20,7 +19,7 @@ export default function () { } = makeRegistrarHandlers({ pluginName }); // support NameRegisteredWithRecord for BaseRegistrar as it used by Base's RegistrarControllers - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "BaseRegistrar:NameRegisteredWithRecord"), async ({ context, event }) => { await handleNameRegistered({ @@ -33,7 +32,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "BaseRegistrar:NameRegistered"), async ({ context, event }) => { await handleNameRegistered({ @@ -46,7 +45,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "BaseRegistrar:NameRenewed"), async ({ context, event }) => { await handleNameRenewed({ @@ -59,17 +58,20 @@ export default function () { }, ); - ponder.on(namespaceContract(pluginName, "BaseRegistrar:Transfer"), async ({ context, event }) => { - await handleNameTransferred({ - context, - event: { - ...event, - args: { ...event.args, labelHash: interpretTokenIdAsLabelHash(event.args.tokenId) }, - }, - }); - }); + addOnchainEventListener( + namespaceContract(pluginName, "BaseRegistrar:Transfer"), + async ({ context, event }) => { + await handleNameTransferred({ + context, + event: { + ...event, + args: { ...event.args, labelHash: interpretTokenIdAsLabelHash(event.args.tokenId) }, + }, + }); + }, + ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "EARegistrarController:NameRegistered"), async ({ context, event }) => { await handleNameRegisteredByController({ @@ -87,7 +89,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "RegistrarController:NameRegistered"), async ({ context, event }) => { await handleNameRegisteredByController({ @@ -105,7 +107,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "RegistrarController:NameRenewed"), async ({ context, event }) => { await handleNameRenewedByController({ @@ -123,7 +125,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "UpgradeableRegistrarController:NameRegistered"), async ({ context, event }) => { await handleNameRegisteredByController({ @@ -141,7 +143,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "UpgradeableRegistrarController:NameRenewed"), async ({ context, event }) => { await handleNameRenewedByController({ diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registry.ts b/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registry.ts index 9ab1af7e6..2af355611 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registry.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registry.ts @@ -1,7 +1,6 @@ -import { ponder } from "ponder:registry"; - import { PluginName } from "@ensnode/ensnode-sdk"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { setupRootNode } from "@/lib/subgraph/subgraph-helpers"; import { @@ -17,9 +16,9 @@ import { export default function () { const pluginName = PluginName.Basenames; - ponder.on(namespaceContract(pluginName, "Registry:setup"), setupRootNode); - ponder.on(namespaceContract(pluginName, "Registry:NewOwner"), handleNewOwner(true)); - ponder.on(namespaceContract(pluginName, "Registry:NewResolver"), handleNewResolver); - ponder.on(namespaceContract(pluginName, "Registry:NewTTL"), handleNewTTL); - ponder.on(namespaceContract(pluginName, "Registry:Transfer"), handleTransfer); + addOnchainEventListener(namespaceContract(pluginName, "Registry:setup"), setupRootNode); + addOnchainEventListener(namespaceContract(pluginName, "Registry:NewOwner"), handleNewOwner(true)); + addOnchainEventListener(namespaceContract(pluginName, "Registry:NewResolver"), handleNewResolver); + addOnchainEventListener(namespaceContract(pluginName, "Registry:NewTTL"), handleNewTTL); + addOnchainEventListener(namespaceContract(pluginName, "Registry:Transfer"), handleTransfer); } diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/NameWrapper.ts b/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/NameWrapper.ts index ac1ec5f38..0436ce962 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/NameWrapper.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/NameWrapper.ts @@ -1,7 +1,6 @@ -import { ponder } from "ponder:registry"; - import { PluginName } from "@ensnode/ensnode-sdk"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { makeNameWrapperHandlers } from "@/plugins/subgraph/shared-handlers/NameWrapper"; @@ -20,10 +19,25 @@ export default function () { handleTransferBatch, } = makeNameWrapperHandlers(); - ponder.on(namespaceContract(pluginName, "NameWrapper:NameWrapped"), handleNameWrapped); - ponder.on(namespaceContract(pluginName, "NameWrapper:NameUnwrapped"), handleNameUnwrapped); - ponder.on(namespaceContract(pluginName, "NameWrapper:FusesSet"), handleFusesSet); - ponder.on(namespaceContract(pluginName, "NameWrapper:ExpiryExtended"), handleExpiryExtended); - ponder.on(namespaceContract(pluginName, "NameWrapper:TransferSingle"), handleTransferSingle); - ponder.on(namespaceContract(pluginName, "NameWrapper:TransferBatch"), handleTransferBatch); + addOnchainEventListener( + namespaceContract(pluginName, "NameWrapper:NameWrapped"), + handleNameWrapped, + ); + addOnchainEventListener( + namespaceContract(pluginName, "NameWrapper:NameUnwrapped"), + handleNameUnwrapped, + ); + addOnchainEventListener(namespaceContract(pluginName, "NameWrapper:FusesSet"), handleFusesSet); + addOnchainEventListener( + namespaceContract(pluginName, "NameWrapper:ExpiryExtended"), + handleExpiryExtended, + ); + addOnchainEventListener( + namespaceContract(pluginName, "NameWrapper:TransferSingle"), + handleTransferSingle, + ); + addOnchainEventListener( + namespaceContract(pluginName, "NameWrapper:TransferBatch"), + handleTransferBatch, + ); } diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registrar.ts b/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registrar.ts index d37c68b03..52c26920f 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registrar.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registrar.ts @@ -1,7 +1,6 @@ -import { ponder } from "ponder:registry"; - import { interpretTokenIdAsLabelHash, PluginName } from "@ensnode/ensnode-sdk"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { makeRegistrarHandlers } from "@/plugins/subgraph/shared-handlers/Registrar"; @@ -19,7 +18,7 @@ export default function () { handleNameTransferred, } = makeRegistrarHandlers({ pluginName }); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "BaseRegistrar:NameRegistered"), async ({ context, event }) => { await handleNameRegistered({ @@ -32,7 +31,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "BaseRegistrar:NameRenewed"), async ({ context, event }) => { await handleNameRenewed({ @@ -45,17 +44,20 @@ export default function () { }, ); - ponder.on(namespaceContract(pluginName, "BaseRegistrar:Transfer"), async ({ context, event }) => { - await handleNameTransferred({ - context, - event: { - ...event, - args: { ...event.args, labelHash: interpretTokenIdAsLabelHash(event.args.tokenId) }, - }, - }); - }); + addOnchainEventListener( + namespaceContract(pluginName, "BaseRegistrar:Transfer"), + async ({ context, event }) => { + await handleNameTransferred({ + context, + event: { + ...event, + args: { ...event.args, labelHash: interpretTokenIdAsLabelHash(event.args.tokenId) }, + }, + }); + }, + ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "EthRegistrarController:OwnerNameRegistered"), async ({ context, event }) => { await handleNameRegisteredByController({ @@ -74,7 +76,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "EthRegistrarController:PohNameRegistered"), async ({ context, event }) => { await handleNameRegisteredByController({ @@ -93,7 +95,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "EthRegistrarController:NameRegistered"), async ({ context, event }) => { await handleNameRegisteredByController({ @@ -112,7 +114,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "EthRegistrarController:NameRenewed"), async ({ context, event }) => { await handleNameRenewedByController({ diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registry.ts b/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registry.ts index 9b354f439..10bf36575 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registry.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registry.ts @@ -1,7 +1,6 @@ -import { ponder } from "ponder:registry"; - import { PluginName } from "@ensnode/ensnode-sdk"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { setupRootNode } from "@/lib/subgraph/subgraph-helpers"; import { @@ -17,9 +16,9 @@ import { export default function () { const pluginName = PluginName.Lineanames; - ponder.on(namespaceContract(pluginName, "Registry:setup"), setupRootNode); - ponder.on(namespaceContract(pluginName, "Registry:NewOwner"), handleNewOwner(true)); - ponder.on(namespaceContract(pluginName, "Registry:NewResolver"), handleNewResolver); - ponder.on(namespaceContract(pluginName, "Registry:NewTTL"), handleNewTTL); - ponder.on(namespaceContract(pluginName, "Registry:Transfer"), handleTransfer); + addOnchainEventListener(namespaceContract(pluginName, "Registry:setup"), setupRootNode); + addOnchainEventListener(namespaceContract(pluginName, "Registry:NewOwner"), handleNewOwner(true)); + addOnchainEventListener(namespaceContract(pluginName, "Registry:NewResolver"), handleNewResolver); + addOnchainEventListener(namespaceContract(pluginName, "Registry:NewTTL"), handleNewTTL); + addOnchainEventListener(namespaceContract(pluginName, "Registry:Transfer"), handleTransfer); } diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/NameWrapper.ts b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/NameWrapper.ts index 8b667cf7e..c53ae28b2 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/NameWrapper.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/NameWrapper.ts @@ -1,7 +1,6 @@ -import { ponder } from "ponder:registry"; - import { PluginName } from "@ensnode/ensnode-sdk"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { makeNameWrapperHandlers } from "@/plugins/subgraph/shared-handlers/NameWrapper"; @@ -20,10 +19,25 @@ export default function () { handleTransferSingle, } = makeNameWrapperHandlers(); - ponder.on(namespaceContract(pluginName, "NameWrapper:NameWrapped"), handleNameWrapped); - ponder.on(namespaceContract(pluginName, "NameWrapper:NameUnwrapped"), handleNameUnwrapped); - ponder.on(namespaceContract(pluginName, "NameWrapper:FusesSet"), handleFusesSet); - ponder.on(namespaceContract(pluginName, "NameWrapper:ExpiryExtended"), handleExpiryExtended); - ponder.on(namespaceContract(pluginName, "NameWrapper:TransferSingle"), handleTransferSingle); - ponder.on(namespaceContract(pluginName, "NameWrapper:TransferBatch"), handleTransferBatch); + addOnchainEventListener( + namespaceContract(pluginName, "NameWrapper:NameWrapped"), + handleNameWrapped, + ); + addOnchainEventListener( + namespaceContract(pluginName, "NameWrapper:NameUnwrapped"), + handleNameUnwrapped, + ); + addOnchainEventListener(namespaceContract(pluginName, "NameWrapper:FusesSet"), handleFusesSet); + addOnchainEventListener( + namespaceContract(pluginName, "NameWrapper:ExpiryExtended"), + handleExpiryExtended, + ); + addOnchainEventListener( + namespaceContract(pluginName, "NameWrapper:TransferSingle"), + handleTransferSingle, + ); + addOnchainEventListener( + namespaceContract(pluginName, "NameWrapper:TransferBatch"), + handleTransferBatch, + ); } diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registrar.ts b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registrar.ts index 293b0ad6b..221793a77 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registrar.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registrar.ts @@ -1,7 +1,6 @@ -import { ponder } from "ponder:registry"; - import { interpretTokenIdAsLabelHash, PluginName } from "@ensnode/ensnode-sdk"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { makeRegistrarHandlers } from "@/plugins/subgraph/shared-handlers/Registrar"; @@ -24,7 +23,7 @@ export default function () { // https://docs.ens.domains/registry/eth/#baseregistrar-vs-controller /////////////////////////////// - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "BaseRegistrar:NameRegistered"), async ({ context, event }) => { await handleNameRegistered({ @@ -40,7 +39,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "BaseRegistrar:NameRenewed"), async ({ context, event }) => { await handleNameRenewed({ @@ -56,26 +55,29 @@ export default function () { }, ); - ponder.on(namespaceContract(pluginName, "BaseRegistrar:Transfer"), async ({ context, event }) => { - const { tokenId, from, to } = event.args; - await handleNameTransferred({ - context, - event: { - ...event, - args: { - from, - to, - labelHash: interpretTokenIdAsLabelHash(tokenId), + addOnchainEventListener( + namespaceContract(pluginName, "BaseRegistrar:Transfer"), + async ({ context, event }) => { + const { tokenId, from, to } = event.args; + await handleNameTransferred({ + context, + event: { + ...event, + args: { + from, + to, + labelHash: interpretTokenIdAsLabelHash(tokenId), + }, }, - }, - }); - }); + }); + }, + ); /////////////////////////////// // LegacyEthRegistrarController /////////////////////////////// - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "LegacyEthRegistrarController:NameRegistered"), async ({ context, event }) => { await handleNameRegisteredByController({ @@ -93,7 +95,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "LegacyEthRegistrarController:NameRenewed"), async ({ context, event }) => { await handleNameRenewedByController({ @@ -115,7 +117,7 @@ export default function () { // WrappedEthRegistrarController //////////////////////////////// - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "WrappedEthRegistrarController:NameRegistered"), async ({ context, event }) => { await handleNameRegisteredByController({ @@ -134,7 +136,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "WrappedEthRegistrarController:NameRenewed"), async ({ context, event }) => { await handleNameRenewedByController({ @@ -156,7 +158,7 @@ export default function () { // UnwrappedEthRegistrarController ////////////////////////////////// - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "UnwrappedEthRegistrarController:NameRegistered"), async ({ context, event }) => { await handleNameRegisteredByController({ @@ -175,7 +177,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "UnwrappedEthRegistrarController:NameRenewed"), async ({ context, event }) => { await handleNameRenewedByController({ diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts index a3efc376d..1d417ce15 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts @@ -1,8 +1,9 @@ -import { type Context, ponder } from "ponder:registry"; +import type { Context } from "ponder:registry"; import schema from "ponder:schema"; import { makeSubdomainNode, type Node, PluginName, ROOT_NODE } from "@ensnode/ensnode-sdk"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { setupRootNode } from "@/lib/subgraph/subgraph-helpers"; import { @@ -31,11 +32,11 @@ async function shouldIgnoreRegistryOldEvents(context: Context, node: Node) { export default function () { const pluginName = PluginName.Subgraph; - ponder.on(namespaceContract(pluginName, "ENSv1RegistryOld:setup"), setupRootNode); + addOnchainEventListener(namespaceContract(pluginName, "ENSv1RegistryOld:setup"), setupRootNode); // old registry functions are proxied to the current handlers // iff the domain has not yet been migrated - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ENSv1RegistryOld:NewOwner"), async ({ context, event }) => { const { label: labelHash, node: parentNode } = event.args; @@ -48,7 +49,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ENSv1RegistryOld:NewResolver"), async ({ context, event }) => { const shouldIgnoreEvent = await shouldIgnoreRegistryOldEvents(context, event.args.node); @@ -63,7 +64,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ENSv1RegistryOld:NewTTL"), async ({ context, event }) => { const shouldIgnoreEvent = await shouldIgnoreRegistryOldEvents(context, event.args.node); @@ -73,7 +74,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ENSv1RegistryOld:Transfer"), async ({ context, event }) => { // NOTE: this logic derived from the subgraph introduces a bug for queries with a blockheight @@ -89,8 +90,14 @@ export default function () { }, ); - ponder.on(namespaceContract(pluginName, "ENSv1Registry:NewOwner"), handleNewOwner(true)); - ponder.on(namespaceContract(pluginName, "ENSv1Registry:NewResolver"), handleNewResolver); - ponder.on(namespaceContract(pluginName, "ENSv1Registry:NewTTL"), handleNewTTL); - ponder.on(namespaceContract(pluginName, "ENSv1Registry:Transfer"), handleTransfer); + addOnchainEventListener( + namespaceContract(pluginName, "ENSv1Registry:NewOwner"), + handleNewOwner(true), + ); + addOnchainEventListener( + namespaceContract(pluginName, "ENSv1Registry:NewResolver"), + handleNewResolver, + ); + addOnchainEventListener(namespaceContract(pluginName, "ENSv1Registry:NewTTL"), handleNewTTL); + addOnchainEventListener(namespaceContract(pluginName, "ENSv1Registry:Transfer"), handleTransfer); } diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSResolver.ts b/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSResolver.ts index eb5bad41b..4e1d680ea 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSResolver.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSResolver.ts @@ -1,7 +1,6 @@ -import { ponder } from "ponder:registry"; - import { PluginName } from "@ensnode/ensnode-sdk"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { handleABIChanged, @@ -26,43 +25,64 @@ import { export default function () { const pluginName = PluginName.ThreeDNS; - ponder.on(namespaceContract(pluginName, "Resolver:AddrChanged"), handleAddrChanged); - ponder.on(namespaceContract(pluginName, "Resolver:AddressChanged"), handleAddressChanged); - ponder.on(namespaceContract(pluginName, "Resolver:NameChanged"), handleNameChanged); - ponder.on(namespaceContract(pluginName, "Resolver:ABIChanged"), handleABIChanged); - ponder.on(namespaceContract(pluginName, "Resolver:PubkeyChanged"), handlePubkeyChanged); - ponder.on( + addOnchainEventListener(namespaceContract(pluginName, "Resolver:AddrChanged"), handleAddrChanged); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:AddressChanged"), + handleAddressChanged, + ); + addOnchainEventListener(namespaceContract(pluginName, "Resolver:NameChanged"), handleNameChanged); + addOnchainEventListener(namespaceContract(pluginName, "Resolver:ABIChanged"), handleABIChanged); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:PubkeyChanged"), + handlePubkeyChanged, + ); + addOnchainEventListener( namespaceContract( pluginName, "Resolver:TextChanged(bytes32 indexed node, string indexed indexedKey, string key)", ), handleTextChanged, ); - ponder.on( + addOnchainEventListener( namespaceContract( pluginName, "Resolver:TextChanged(bytes32 indexed node, string indexed indexedKey, string key, string value)", ), handleTextChanged, ); - ponder.on(namespaceContract(pluginName, "Resolver:ContenthashChanged"), handleContenthashChanged); - ponder.on(namespaceContract(pluginName, "Resolver:InterfaceChanged"), handleInterfaceChanged); - ponder.on( + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:ContenthashChanged"), + handleContenthashChanged, + ); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:InterfaceChanged"), + handleInterfaceChanged, + ); + addOnchainEventListener( namespaceContract(pluginName, "Resolver:AuthorisationChanged"), handleAuthorisationChanged, ); - ponder.on(namespaceContract(pluginName, "Resolver:VersionChanged"), handleVersionChanged); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:VersionChanged"), + handleVersionChanged, + ); // NOTE: 3DNS' Resolver contract only emits DNSRecordChanged with the included `ttl` argument // and we explicitly do not index ens-contracts' IDNSRecordResolver#DNSRecordChanged (without the `ttl`) // in this file, as these handlers are 3DNS-specific - ponder.on( + addOnchainEventListener( namespaceContract( pluginName, "Resolver:DNSRecordChanged(bytes32 indexed node, bytes name, uint16 resource, uint32 ttl, bytes record)", ), handleDNSRecordChanged, ); - ponder.on(namespaceContract(pluginName, "Resolver:DNSRecordDeleted"), handleDNSRecordDeleted); - ponder.on(namespaceContract(pluginName, "Resolver:DNSZonehashChanged"), handleDNSZonehashChanged); - ponder.on(namespaceContract(pluginName, "Resolver:ZoneCreated"), handleZoneCreated); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:DNSRecordDeleted"), + handleDNSRecordDeleted, + ); + addOnchainEventListener( + namespaceContract(pluginName, "Resolver:DNSZonehashChanged"), + handleDNSZonehashChanged, + ); + addOnchainEventListener(namespaceContract(pluginName, "Resolver:ZoneCreated"), handleZoneCreated); } diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSToken.ts b/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSToken.ts index 1bcb03c9e..bfee5e584 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSToken.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSToken.ts @@ -1,7 +1,6 @@ -import { ponder } from "ponder:registry"; - import { PluginName } from "@ensnode/ensnode-sdk"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { setupRootNode } from "@/lib/subgraph/subgraph-helpers"; import { @@ -17,14 +16,14 @@ import { export default function () { const pluginName = PluginName.ThreeDNS; - ponder.on(namespaceContract(pluginName, "ThreeDNSToken:setup"), setupRootNode); - ponder.on(namespaceContract(pluginName, "ThreeDNSToken:NewOwner"), handleNewOwner); - ponder.on(namespaceContract(pluginName, "ThreeDNSToken:Transfer"), handleTransfer); - ponder.on( + addOnchainEventListener(namespaceContract(pluginName, "ThreeDNSToken:setup"), setupRootNode); + addOnchainEventListener(namespaceContract(pluginName, "ThreeDNSToken:NewOwner"), handleNewOwner); + addOnchainEventListener(namespaceContract(pluginName, "ThreeDNSToken:Transfer"), handleTransfer); + addOnchainEventListener( namespaceContract(pluginName, "ThreeDNSToken:RegistrationCreated"), handleRegistrationCreated, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ThreeDNSToken:RegistrationExtended"), handleRegistrationExtended, ); diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/multi-chain/Resolver.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/multi-chain/Resolver.ts index 0b5e22006..5cf49489e 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/multi-chain/Resolver.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/multi-chain/Resolver.ts @@ -1,4 +1,4 @@ -import { ponder } from "ponder:registry"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { handleABIChanged, @@ -31,37 +31,37 @@ export default function attach_SharedMultichainResolverHandlers() { if (hasBeenRegistered) return; hasBeenRegistered = true; - ponder.on("Resolver:AddrChanged", handleAddrChanged); - ponder.on("Resolver:AddressChanged", handleAddressChanged); - ponder.on("Resolver:NameChanged", handleNameChanged); - ponder.on("Resolver:ABIChanged", handleABIChanged); - ponder.on("Resolver:PubkeyChanged", handlePubkeyChanged); - ponder.on( + addOnchainEventListener("Resolver:AddrChanged", handleAddrChanged); + addOnchainEventListener("Resolver:AddressChanged", handleAddressChanged); + addOnchainEventListener("Resolver:NameChanged", handleNameChanged); + addOnchainEventListener("Resolver:ABIChanged", handleABIChanged); + addOnchainEventListener("Resolver:PubkeyChanged", handlePubkeyChanged); + addOnchainEventListener( "Resolver:TextChanged(bytes32 indexed node, string indexed indexedKey, string key)", handleTextChanged, ); - ponder.on( + addOnchainEventListener( "Resolver:TextChanged(bytes32 indexed node, string indexed indexedKey, string key, string value)", handleTextChanged, ); - ponder.on("Resolver:ContenthashChanged", handleContenthashChanged); - ponder.on("Resolver:InterfaceChanged", handleInterfaceChanged); - ponder.on("Resolver:AuthorisationChanged", handleAuthorisationChanged); - ponder.on("Resolver:VersionChanged", handleVersionChanged); + addOnchainEventListener("Resolver:ContenthashChanged", handleContenthashChanged); + addOnchainEventListener("Resolver:InterfaceChanged", handleInterfaceChanged); + addOnchainEventListener("Resolver:AuthorisationChanged", handleAuthorisationChanged); + addOnchainEventListener("Resolver:VersionChanged", handleVersionChanged); // ens-contracts' IDNSRecordResolver#DNSRecordChanged // https://github.com/ensdomains/ens-contracts/blob/b6bc1eac9d241b7334ce78a51bacdf272f37fdf5/contracts/resolvers/profiles/IDNSRecordResolver.sol#L6 - ponder.on( + addOnchainEventListener( "Resolver:DNSRecordChanged(bytes32 indexed node, bytes name, uint16 resource, bytes record)", handleDNSRecordChanged, ); // NOTE: this DNSRecordChanged ABI spec with the included `ttl` parameter is specific to // 3DNS' Resolver implementation, but we include it here for theoretical completeness, were a // Resolver indexed by these shared handlers to emit this event. - ponder.on( + addOnchainEventListener( "Resolver:DNSRecordChanged(bytes32 indexed node, bytes name, uint16 resource, uint32 ttl, bytes record)", handleDNSRecordChanged, ); - ponder.on("Resolver:DNSRecordDeleted", handleDNSRecordDeleted); - ponder.on("Resolver:DNSZonehashChanged", handleDNSZonehashChanged); - ponder.on("Resolver:ZoneCreated", handleZoneCreated); + addOnchainEventListener("Resolver:DNSRecordDeleted", handleDNSRecordDeleted); + addOnchainEventListener("Resolver:DNSZonehashChanged", handleDNSZonehashChanged); + addOnchainEventListener("Resolver:ZoneCreated", handleZoneCreated); } diff --git a/apps/ensindexer/src/plugins/tokenscope/handlers/BaseRegistrars.ts b/apps/ensindexer/src/plugins/tokenscope/handlers/BaseRegistrars.ts index f7455539f..8ca6ec1ed 100644 --- a/apps/ensindexer/src/plugins/tokenscope/handlers/BaseRegistrars.ts +++ b/apps/ensindexer/src/plugins/tokenscope/handlers/BaseRegistrars.ts @@ -1,10 +1,9 @@ import config from "@/config"; -import { ponder } from "ponder:registry"; - import { DatasourceNames } from "@ensnode/datasources"; import { type NFTTransferEventMetadata, PluginName } from "@ensnode/ensnode-sdk"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { buildSupportedNFT } from "@/lib/tokenscope/nft-issuers"; @@ -16,7 +15,7 @@ import { handleNFTTransfer } from "../lib/handle-nft-transfer"; export default function () { const pluginName = PluginName.TokenScope; - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "EthBaseRegistrar:Transfer"), async ({ context, event }) => { const nft = buildSupportedNFT( @@ -38,7 +37,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "BaseBaseRegistrar:Transfer"), async ({ context, event }) => { const nft = buildSupportedNFT( @@ -60,7 +59,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "LineaBaseRegistrar:Transfer"), async ({ context, event }) => { const nft = buildSupportedNFT( diff --git a/apps/ensindexer/src/plugins/tokenscope/handlers/NameWrapper.ts b/apps/ensindexer/src/plugins/tokenscope/handlers/NameWrapper.ts index c76419124..355986403 100644 --- a/apps/ensindexer/src/plugins/tokenscope/handlers/NameWrapper.ts +++ b/apps/ensindexer/src/plugins/tokenscope/handlers/NameWrapper.ts @@ -1,10 +1,9 @@ import config from "@/config"; -import { ponder } from "ponder:registry"; - import { DatasourceNames } from "@ensnode/datasources"; import { type NFTTransferEventMetadata, PluginName } from "@ensnode/ensnode-sdk"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { buildSupportedNFT } from "@/lib/tokenscope/nft-issuers"; @@ -16,7 +15,7 @@ import { handleERC1155Transfer } from "../lib/handle-nft-transfer"; export default function () { const pluginName = PluginName.TokenScope; - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "NameWrapper:TransferSingle"), async ({ context, event }) => { const nft = buildSupportedNFT( @@ -47,7 +46,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "NameWrapper:TransferBatch"), async ({ context, event }) => { if (event.args.ids.length !== event.args.values.length) { diff --git a/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts b/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts index 104c2e7f7..da3ec2ea9 100644 --- a/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts +++ b/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts @@ -1,10 +1,10 @@ import config from "@/config"; -import { ponder } from "ponder:registry"; import schema from "ponder:schema"; import { formatAssetId, PluginName } from "@ensnode/ensnode-sdk"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { upsertAccount } from "@/lib/subgraph/db-helpers"; import { makeEventId } from "@/lib/subgraph/ids"; @@ -16,45 +16,52 @@ import { getSupportedSaleFromOrderFulfilledEvent } from "@/lib/tokenscope/seapor export default function () { const pluginName = PluginName.TokenScope; - ponder.on(namespaceContract(pluginName, "Seaport:OrderFulfilled"), async ({ context, event }) => { - const sale = getSupportedSaleFromOrderFulfilledEvent(config.namespace, context.chain.id, event); - - // the Seaport sale in the event is not supported by TokenScope, no-op - // this can happen for a number of reasons, including: - // - the sale was for a NFT that is not recognized as being associated with an ENS name - // (note how this event is triggered for any sale made through Seaport, not just ENS names) - // - the sale was not paid for with a supported currency (e.g. ETH, USDC, etc) - // - the sale received payments in multiple currencies - // - the sale was for multiple NFTs (not just one) - // TokenScope purposefully does not support these cases as we believe they overall add - // more complexity than benefit. We believe it's better to prioritize better simplicity of - // building apps on TokenScope than supporting these more complex and uncommon cases. - if (!sale) return; - - // upsert buyer and seller accounts - await upsertAccount(context, sale.seller); - await upsertAccount(context, sale.buyer); - - const assetIdString = formatAssetId(sale.nft); - - // insert NameSale entity - await context.db.insert(schema.nameSales).values({ - id: makeEventId(context.chain.id, event.block.number, event.log.logIndex), - chainId: sale.nft.contract.chainId, - blockNumber: event.block.number, - logIndex: event.log.logIndex, - transactionHash: event.transaction.hash, - orderHash: sale.orderHash, - contractAddress: sale.nft.contract.address, - tokenId: sale.nft.tokenId, - assetNamespace: sale.nft.assetNamespace, - assetId: assetIdString, - domainId: sale.nft.domainId, - buyer: sale.buyer, - seller: sale.seller, - currency: sale.payment.price.currency, - amount: sale.payment.price.amount, - timestamp: event.block.timestamp, - }); - }); + addOnchainEventListener( + namespaceContract(pluginName, "Seaport:OrderFulfilled"), + async ({ context, event }) => { + const sale = getSupportedSaleFromOrderFulfilledEvent( + config.namespace, + context.chain.id, + event, + ); + + // the Seaport sale in the event is not supported by TokenScope, no-op + // this can happen for a number of reasons, including: + // - the sale was for a NFT that is not recognized as being associated with an ENS name + // (note how this event is triggered for any sale made through Seaport, not just ENS names) + // - the sale was not paid for with a supported currency (e.g. ETH, USDC, etc) + // - the sale received payments in multiple currencies + // - the sale was for multiple NFTs (not just one) + // TokenScope purposefully does not support these cases as we believe they overall add + // more complexity than benefit. We believe it's better to prioritize better simplicity of + // building apps on TokenScope than supporting these more complex and uncommon cases. + if (!sale) return; + + // upsert buyer and seller accounts + await upsertAccount(context, sale.seller); + await upsertAccount(context, sale.buyer); + + const assetIdString = formatAssetId(sale.nft); + + // insert NameSale entity + await context.db.insert(schema.nameSales).values({ + id: makeEventId(context.chain.id, event.block.number, event.log.logIndex), + chainId: sale.nft.contract.chainId, + blockNumber: event.block.number, + logIndex: event.log.logIndex, + transactionHash: event.transaction.hash, + orderHash: sale.orderHash, + contractAddress: sale.nft.contract.address, + tokenId: sale.nft.tokenId, + assetNamespace: sale.nft.assetNamespace, + assetId: assetIdString, + domainId: sale.nft.domainId, + buyer: sale.buyer, + seller: sale.seller, + currency: sale.payment.price.currency, + amount: sale.payment.price.amount, + timestamp: event.block.timestamp, + }); + }, + ); } diff --git a/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts b/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts index 86cdf4c29..52c1336ce 100644 --- a/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts +++ b/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts @@ -1,11 +1,11 @@ import config from "@/config"; -import { ponder } from "ponder:registry"; import { base, optimism } from "viem/chains"; import { type DatasourceName, DatasourceNames } from "@ensnode/datasources"; import { type ChainId, type NFTTransferEventMetadata, PluginName } from "@ensnode/ensnode-sdk"; +import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { buildSupportedNFT } from "@/lib/tokenscope/nft-issuers"; @@ -28,7 +28,7 @@ const getThreeDNSDatasourceName = (chainId: ChainId): DatasourceName => { export default function () { const pluginName = PluginName.TokenScope; - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ThreeDNSToken:TransferSingle"), async ({ context, event }) => { const nft = buildSupportedNFT( @@ -64,7 +64,7 @@ export default function () { }, ); - ponder.on( + addOnchainEventListener( namespaceContract(pluginName, "ThreeDNSToken:TransferBatch"), async ({ context, event }) => { if (event.args.ids.length !== event.args.values.length) { @@ -112,7 +112,7 @@ export default function () { } }, ); - // ponder.on( + // addOnchainEventListener( // namespaceContract(pluginName, "ThreeDNSToken:RegistrationCreated"), // async ({ context, event }) => { // // currently no use for tld, fqdn, controlBitmap, or expiry fields in event.args @@ -135,7 +135,7 @@ export default function () { // }, // ); - // ponder.on( + // addOnchainEventListener( // namespaceContract(pluginName, "ThreeDNSToken:RegistrationTransferred"), // async ({ context, event }) => { // // currently no use for operator field in event.args @@ -170,7 +170,7 @@ export default function () { // }, // ); - // ponder.on( + // addOnchainEventListener( // namespaceContract(pluginName, "ThreeDNSToken:RegistrationBurned"), // async ({ context, event }) => { // // currently no use for burner field in event.args From 272f464857b68e6b6b1240298a75262f2c6579ef Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Sat, 28 Mar 2026 12:39:36 +0100 Subject: [PATCH 03/11] docs(changeset): Replaced `ponder.on` with `addOnchainEventListener`. This change will enable managing indexing process more granularly. --- .changeset/bold-bananas-jump.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/bold-bananas-jump.md diff --git a/.changeset/bold-bananas-jump.md b/.changeset/bold-bananas-jump.md new file mode 100644 index 000000000..fff10f330 --- /dev/null +++ b/.changeset/bold-bananas-jump.md @@ -0,0 +1,5 @@ +--- +"ensindexer": minor +--- + +Replaced `ponder.on` with `addOnchainEventListener`. This change enables more granular management of the indexing process. From f27483d28e54f8f80a53149271bda83320e56159 Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Sat, 28 Mar 2026 15:02:02 +0100 Subject: [PATCH 04/11] Create `indexing-engines/ponder.ts` file --- .../ponder.test.ts} | 2 +- .../ponder.ts} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename apps/ensindexer/src/lib/{onchain-events/add-onchain-event-listener.test.ts => indexing-engines/ponder.test.ts} (86%) rename apps/ensindexer/src/lib/{onchain-events/add-onchain-event-listener.ts => indexing-engines/ponder.ts} (100%) diff --git a/apps/ensindexer/src/lib/onchain-events/add-onchain-event-listener.test.ts b/apps/ensindexer/src/lib/indexing-engines/ponder.test.ts similarity index 86% rename from apps/ensindexer/src/lib/onchain-events/add-onchain-event-listener.test.ts rename to apps/ensindexer/src/lib/indexing-engines/ponder.test.ts index 91f7974ab..f7c629e47 100644 --- a/apps/ensindexer/src/lib/onchain-events/add-onchain-event-listener.test.ts +++ b/apps/ensindexer/src/lib/indexing-engines/ponder.test.ts @@ -15,7 +15,7 @@ describe("addOnchainEventListener", () => { }); it("should call ponder.on with the correct event name and handler", async () => { - const { addOnchainEventListener } = await import("./add-onchain-event-listener"); + const { addOnchainEventListener } = await import("./ponder"); const testHandler = vi.fn(); addOnchainEventListener("Resolver:AddrChanged", testHandler); diff --git a/apps/ensindexer/src/lib/onchain-events/add-onchain-event-listener.ts b/apps/ensindexer/src/lib/indexing-engines/ponder.ts similarity index 100% rename from apps/ensindexer/src/lib/onchain-events/add-onchain-event-listener.ts rename to apps/ensindexer/src/lib/indexing-engines/ponder.ts From 5ed57deb2a21705be38e37c092fcaaf4f80f2779 Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Sat, 28 Mar 2026 15:03:16 +0100 Subject: [PATCH 05/11] Update `context` param data model Allow using `context.ensDb` alias for accessing the cached Drizzle client for ENSDb. --- .../src/lib/indexing-engines/ponder.test.ts | 192 +++++++++++++++++- .../src/lib/indexing-engines/ponder.ts | 71 ++++++- 2 files changed, 247 insertions(+), 16 deletions(-) diff --git a/apps/ensindexer/src/lib/indexing-engines/ponder.test.ts b/apps/ensindexer/src/lib/indexing-engines/ponder.test.ts index f7c629e47..0e85fb28d 100644 --- a/apps/ensindexer/src/lib/indexing-engines/ponder.test.ts +++ b/apps/ensindexer/src/lib/indexing-engines/ponder.test.ts @@ -1,25 +1,203 @@ +import type { Context, EventNames } from "ponder:registry"; import { beforeEach, describe, expect, it, vi } from "vitest"; +import { + addOnchainEventListener, + type IndexingEngineContext, + type IndexingEngineEvent, +} from "./ponder"; + const mockPonderOn = vi.fn(); vi.mock("ponder:registry", () => ({ ponder: { - on: mockPonderOn, + on: (...args: unknown[]) => mockPonderOn(...args), }, })); describe("addOnchainEventListener", () => { beforeEach(() => { - vi.resetModules(); vi.clearAllMocks(); }); - it("should call ponder.on with the correct event name and handler", async () => { - const { addOnchainEventListener } = await import("./ponder"); - const testHandler = vi.fn(); + describe("registration", () => { + it("registers the handler with the correct event name", () => { + const testHandler = vi.fn(); + + addOnchainEventListener("Resolver:AddrChanged" as EventNames, testHandler); + + expect(mockPonderOn).toHaveBeenCalledWith("Resolver:AddrChanged", expect.any(Function)); + }); + + it("returns the result from ponder.on", () => { + const mockReturnValue = { unsubscribe: vi.fn() }; + mockPonderOn.mockReturnValue(mockReturnValue); + const testHandler = vi.fn(); + + const result = addOnchainEventListener("Resolver:AddrChanged" as EventNames, testHandler); + + expect(result).toBe(mockReturnValue); + }); + }); + + describe("context transformation", () => { + it("adds ensDb property referencing the same object as db", () => { + const testHandler = vi.fn(); + const mockDb = vi.fn(); + const mockContext = { db: mockDb } as unknown as Context; + const mockEvent = {} as IndexingEngineEvent; + + addOnchainEventListener("Resolver:AddrChanged" as EventNames, testHandler); + + const [, callback] = mockPonderOn.mock.calls[0]!; + callback({ context: mockContext, event: mockEvent }); + + const callArg = testHandler.mock.calls[0]?.[0]; + expect(callArg?.context.ensDb).toBe(callArg?.context.db); + }); + + it("preserves all other context properties", () => { + const testHandler = vi.fn(); + const mockDb = vi.fn(); + const mockContext = { + db: mockDb, + chain: { id: 1 }, + block: { number: 100n }, + } as unknown as Context; + const mockEvent = { args: { a: "0x123" } } as unknown as IndexingEngineEvent; + + addOnchainEventListener("Resolver:AddrChanged" as EventNames, testHandler); + + const [, callback] = mockPonderOn.mock.calls[0]!; + callback({ context: mockContext, event: mockEvent }); + + expect(testHandler).toHaveBeenCalledWith({ + context: expect.objectContaining({ + db: mockDb, + ensDb: mockDb, + chain: { id: 1 }, + block: { number: 100n }, + }), + event: mockEvent, + }); + }); + }); + + describe("event handling", () => { + it("supports multiple event names independently", () => { + const handler1 = vi.fn(); + const handler2 = vi.fn(); + + addOnchainEventListener("Resolver:AddrChanged" as EventNames, handler1); + addOnchainEventListener("Resolver:NameChanged" as EventNames, handler2); + + expect(mockPonderOn).toHaveBeenCalledTimes(2); + + const [, callback1] = mockPonderOn.mock.calls[0]!; + const mockDb1 = vi.fn(); + const event1 = {} as IndexingEngineEvent; + callback1({ context: { db: mockDb1 } as unknown as Context, event: event1 }); + + expect(handler1).toHaveBeenCalledTimes(1); + expect(handler2).toHaveBeenCalledTimes(0); + + const [, callback2] = mockPonderOn.mock.calls[1]!; + const mockDb2 = vi.fn(); + const event2 = {} as IndexingEngineEvent; + callback2({ context: { db: mockDb2 } as unknown as Context, event: event2 }); + + expect(handler2).toHaveBeenCalledTimes(1); + }); + + it("passes the event argument through to the handler", () => { + const testHandler = vi.fn(); + const mockDb = vi.fn(); + const mockEvent = { + args: { node: "0x123", label: "0x456" }, + } as unknown as IndexingEngineEvent; + + addOnchainEventListener("Resolver:AddrChanged" as EventNames, testHandler); + + const [, callback] = mockPonderOn.mock.calls[0]!; + callback({ context: { db: mockDb } as unknown as Context, event: mockEvent }); + + expect(testHandler).toHaveBeenCalledWith(expect.objectContaining({ event: mockEvent })); + }); + }); + + describe("handler types", () => { + it("handles async handlers", async () => { + const asyncHandler = vi.fn().mockResolvedValue(undefined); + const mockDb = vi.fn(); + const mockContext = { db: mockDb } as unknown as Context; + const mockEvent = {} as IndexingEngineEvent; + + addOnchainEventListener("Resolver:AddrChanged" as EventNames, asyncHandler); + + const [, callback] = mockPonderOn.mock.calls[0]!; + await callback({ context: mockContext, event: mockEvent }); + + expect(asyncHandler).toHaveBeenCalled(); + }); + + it("handles sync handlers", () => { + const syncHandler = vi.fn(); + const mockDb = vi.fn(); + const mockContext = { db: mockDb } as unknown as Context; + const mockEvent = {} as IndexingEngineEvent; + + addOnchainEventListener("Resolver:AddrChanged" as EventNames, syncHandler); + + const [, callback] = mockPonderOn.mock.calls[0]!; + callback({ context: mockContext, event: mockEvent }); + + expect(syncHandler).toHaveBeenCalled(); + }); + }); + + describe("error handling", () => { + it("propagates errors from sync handlers", () => { + const error = new Error("Handler failed"); + const failingHandler = vi.fn(() => { + throw error; + }); + const mockDb = vi.fn(); + const mockContext = { db: mockDb } as unknown as Context; + const mockEvent = {} as IndexingEngineEvent; + + addOnchainEventListener("Resolver:AddrChanged" as EventNames, failingHandler); + + const [, callback] = mockPonderOn.mock.calls[0]!; + expect(() => callback({ context: mockContext, event: mockEvent })).toThrow("Handler failed"); + }); + + it("propagates errors from async handlers", async () => { + const error = new Error("Async handler failed"); + const failingHandler = vi.fn().mockRejectedValue(error); + const mockDb = vi.fn(); + const mockContext = { db: mockDb } as unknown as Context; + const mockEvent = {} as IndexingEngineEvent; + + addOnchainEventListener("Resolver:AddrChanged" as EventNames, failingHandler); + + const [, callback] = mockPonderOn.mock.calls[0]!; + await expect(callback({ context: mockContext, event: mockEvent })).rejects.toThrow( + "Async handler failed", + ); + }); + }); +}); - addOnchainEventListener("Resolver:AddrChanged", testHandler); +describe("IndexingEngineContext type", () => { + it("should have ensDb property extending from Ponder context", () => { + const mockContext: IndexingEngineContext = { + db: vi.fn(), + ensDb: vi.fn(), + chain: { id: 1 }, + block: { number: 100n }, + client: vi.fn(), + } as unknown as IndexingEngineContext; - expect(mockPonderOn).toHaveBeenCalledWith("Resolver:AddrChanged", testHandler); + expect(mockContext.ensDb).toBeDefined(); }); }); diff --git a/apps/ensindexer/src/lib/indexing-engines/ponder.ts b/apps/ensindexer/src/lib/indexing-engines/ponder.ts index 95700160a..c7fe2f2d7 100644 --- a/apps/ensindexer/src/lib/indexing-engines/ponder.ts +++ b/apps/ensindexer/src/lib/indexing-engines/ponder.ts @@ -1,17 +1,70 @@ -import { type EventNames, type IndexingFunctionArgs, ponder } from "ponder:registry"; +import { + type EventNames, + type Context as PonderIndexingContext, + type Event as PonderIndexingEvent, + ponder, +} from "ponder:registry"; /** - * Adds an event listener for a specific event. - * - * This is a thin wrapper around `ponder.on` that allows executing additional logic - * before or after the event handler if needed. - * + * Context passed to event handlers registered with + * {@link addOnchainEventListener}. + */ +export interface IndexingEngineContext extends PonderIndexingContext { + ensDb: PonderIndexingContext["db"]; +} + +/** + * Event passed to event handlers registered with + * {@link addOnchainEventListener}. + */ +export type IndexingEngineEvent = + PonderIndexingEvent; + +/** + * Args passed to event handlers registered with + * {@link addOnchainEventListener}. + */ +export interface IndexingEngineEventHandlerArgs { + context: IndexingEngineContext; + event: IndexingEngineEvent; +} + +/** + * Build the context passed to event handlers registered + * with {@link addOnchainEventListener} from the context provided by + * Ponder. This is where we can add any additional properties, + * or helper functions to the context that we want to be available in + * all of our event handlers. + */ +function buildIndexingEngineContext( + ponderContext: PonderIndexingContext, +): IndexingEngineContext { + return { + ...ponderContext, + ensDb: ponderContext.db, + }; +} + +/** + * A thin wrapper around `ponder.on` that allows us to: + * - Provide custom context to event handlers. + * - Execute additional logic before or after the event handler, if needed. + * + * Note that this function is called on every event, so it should be + * efficient and avoid doing any heavy computations or database queries. + * * For more details on `ponder.on`, see the Ponder indexing guide. * @see https://ponder.sh/docs/indexing/overview#register-an-indexing-function + */ -export function addOnchainEventListener( +export function addOnchainEventListener( eventName: EventName, - eventHandler: (args: IndexingFunctionArgs) => Promise | void, + eventHandler: (args: IndexingEngineEventHandlerArgs) => Promise | void, ) { - return ponder.on(eventName, eventHandler); + return ponder.on(eventName, ({ context, event }) => + eventHandler({ + context: buildIndexingEngineContext(context), + event, + }), + ); } From 54314e9b6a831bd74721f6784805f69670a3a928 Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Sat, 28 Mar 2026 15:03:47 +0100 Subject: [PATCH 06/11] Update import paths Mechanical updates only --- .../src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts | 2 +- .../src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts | 2 +- apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts | 2 +- .../src/plugins/ensv2/handlers/ensv1/RegistrarController.ts | 2 +- .../src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts | 2 +- .../ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts | 2 +- .../src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts | 2 +- apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts | 2 +- .../src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts | 2 +- .../src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts | 2 +- .../src/plugins/protocol-acceleration/handlers/Resolver.ts | 2 +- .../handlers/StandaloneReverseRegistrar.ts | 2 +- .../src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts | 2 +- .../registrars/basenames/handlers/Basenames_Registrar.ts | 2 +- .../basenames/handlers/Basenames_RegistrarController.ts | 2 +- .../plugins/registrars/ethnames/handlers/Ethnames_Registrar.ts | 2 +- .../ethnames/handlers/Ethnames_RegistrarController.ts | 2 +- .../handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts | 2 +- .../registrars/lineanames/handlers/Lineanames_Registrar.ts | 2 +- .../lineanames/handlers/Lineanames_RegistrarController.ts | 2 +- .../plugins/subgraph/plugins/basenames/handlers/Registrar.ts | 2 +- .../src/plugins/subgraph/plugins/basenames/handlers/Registry.ts | 2 +- .../plugins/subgraph/plugins/lineanames/handlers/NameWrapper.ts | 2 +- .../plugins/subgraph/plugins/lineanames/handlers/Registrar.ts | 2 +- .../plugins/subgraph/plugins/lineanames/handlers/Registry.ts | 2 +- .../plugins/subgraph/plugins/subgraph/handlers/NameWrapper.ts | 2 +- .../src/plugins/subgraph/plugins/subgraph/handlers/Registrar.ts | 2 +- .../src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts | 2 +- .../subgraph/plugins/threedns/handlers/ThreeDNSResolver.ts | 2 +- .../plugins/subgraph/plugins/threedns/handlers/ThreeDNSToken.ts | 2 +- .../plugins/subgraph/shared-handlers/multi-chain/Resolver.ts | 2 +- .../src/plugins/tokenscope/handlers/BaseRegistrars.ts | 2 +- apps/ensindexer/src/plugins/tokenscope/handlers/NameWrapper.ts | 2 +- apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts | 2 +- .../ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts | 2 +- 35 files changed, 35 insertions(+), 35 deletions(-) diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts index e822e82ba..c2363afc8 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts @@ -21,9 +21,9 @@ import { insertLatestRenewal, } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { getManagedName } from "@/lib/managed-names"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts index e78ce885e..e8d2d080d 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts @@ -20,7 +20,7 @@ import { materializeENSv1DomainEffectiveOwner } from "@/lib/ensv2/domain-db-help import { ensureDomainEvent } from "@/lib/ensv2/event-db-helpers"; import { ensureLabel, ensureUnknownLabel } from "@/lib/ensv2/label-db-helpers"; import { healAddrReverseSubnameLabel } from "@/lib/heal-addr-reverse-subname-label"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { nodeIsMigrated } from "@/lib/protocol-acceleration/registry-migration-status"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts index e6de75069..b6c28079d 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts @@ -30,9 +30,9 @@ import { insertLatestRenewal, } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { getManagedName } from "@/lib/managed-names"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts index 813c722a1..796b1f936 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts @@ -17,9 +17,9 @@ import { ensureDomainEvent } from "@/lib/ensv2/event-db-helpers"; import { ensureLabel, ensureUnknownLabel } from "@/lib/ensv2/label-db-helpers"; import { getLatestRegistration, getLatestRenewal } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { getManagedName } from "@/lib/managed-names"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts index d387dab69..8746df5e1 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts @@ -22,8 +22,8 @@ import { insertLatestRegistration, } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts index 4bd08b956..745714932 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts @@ -17,8 +17,8 @@ import { ensureAccount } from "@/lib/ensv2/account-db-helpers"; import { ensureDomainEvent, ensureEvent } from "@/lib/ensv2/event-db-helpers"; import { getLatestRegistration, insertLatestRenewal } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs, LogEventBase } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts index d66ebb1ab..45de2155b 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts @@ -12,7 +12,7 @@ import { import { ensureAccount } from "@/lib/ensv2/account-db-helpers"; import { ensurePermissionsEvent } from "@/lib/ensv2/event-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts b/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts index 1fa7aa3f4..4f08972a1 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts @@ -4,7 +4,7 @@ import { PluginName } from "@ensnode/ensnode-sdk"; import { ensureResolverEvent } from "@/lib/ensv2/event-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { LogEventBase } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts index f32115401..5352af56f 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts @@ -13,7 +13,7 @@ import { } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { ensureDomainResolverRelation } from "@/lib/protocol-acceleration/domain-resolver-relationship-db-helpers"; diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts index 51d89db5c..d111a0cd7 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts @@ -4,7 +4,7 @@ import type { Address } from "viem"; import { getCanonicalId, makeENSv2DomainId, PluginName } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { ensureDomainResolverRelation } from "@/lib/protocol-acceleration/domain-resolver-relationship-db-helpers"; diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/Resolver.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/Resolver.ts index 2b6e02685..cbcc73df8 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/Resolver.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/Resolver.ts @@ -3,7 +3,7 @@ import { bigintToCoinType, type CoinType, ETH_COIN_TYPE, PluginName } from "@ens import { parseDnsTxtRecordArgs } from "@/lib/dns-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { ensureResolver, diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts index fddc8c31a..e4b24efc9 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts @@ -6,7 +6,7 @@ import { getENSRootChainId } from "@ensnode/datasources"; import { DEFAULT_EVM_COIN_TYPE, evmChainIdToCoinType, PluginName } from "@ensnode/ensnode-sdk"; import { interpretNameRecordValue } from "@ensnode/ensnode-sdk/internal"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; /** diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts index 05c20c006..b0bd09b71 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts @@ -14,7 +14,7 @@ import { } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { ensureDomainResolverRelation } from "@/lib/protocol-acceleration/domain-resolver-relationship-db-helpers"; diff --git a/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_Registrar.ts b/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_Registrar.ts index 56d75aa19..59dc62120 100644 --- a/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_Registrar.ts +++ b/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_Registrar.ts @@ -8,8 +8,8 @@ import { } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { getManagedName } from "@/lib/managed-names"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { diff --git a/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_RegistrarController.ts b/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_RegistrarController.ts index fefcd7f3a..e269de1d0 100644 --- a/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_RegistrarController.ts +++ b/apps/ensindexer/src/plugins/registrars/basenames/handlers/Basenames_RegistrarController.ts @@ -6,8 +6,8 @@ import { } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { getManagedName } from "@/lib/managed-names"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { handleRegistrarControllerEvent } from "../../shared/lib/registrar-controller-events"; diff --git a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_Registrar.ts b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_Registrar.ts index 22417ab45..d98dfd6b8 100644 --- a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_Registrar.ts +++ b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_Registrar.ts @@ -8,8 +8,8 @@ import { } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { getManagedName } from "@/lib/managed-names"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { diff --git a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts index e01fe4cea..fdadaa6cd 100644 --- a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts +++ b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_RegistrarController.ts @@ -10,8 +10,8 @@ import { } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { getManagedName } from "@/lib/managed-names"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { handleRegistrarControllerEvent } from "../../shared/lib/registrar-controller-events"; diff --git a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts index 6713299ff..d443cef7f 100644 --- a/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts +++ b/apps/ensindexer/src/plugins/registrars/ethnames/handlers/Ethnames_UniversalRegistrarRenewalWithReferrer.ts @@ -6,8 +6,8 @@ import { } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { getManagedName } from "@/lib/managed-names"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { handleUniversalRegistrarRenewalEvent } from "@/plugins/registrars/shared/lib/universal-registrar-renewal-with-referrer-events"; diff --git a/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_Registrar.ts b/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_Registrar.ts index ca5735fae..dcedc64b1 100644 --- a/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_Registrar.ts +++ b/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_Registrar.ts @@ -8,8 +8,8 @@ import { } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { getManagedName } from "@/lib/managed-names"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { diff --git a/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_RegistrarController.ts b/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_RegistrarController.ts index baf2990f9..3397c24f2 100644 --- a/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_RegistrarController.ts +++ b/apps/ensindexer/src/plugins/registrars/lineanames/handlers/Lineanames_RegistrarController.ts @@ -8,8 +8,8 @@ import { } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { getManagedName } from "@/lib/managed-names"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; import { namespaceContract } from "@/lib/plugin-helpers"; import { handleRegistrarControllerEvent } from "../../shared/lib/registrar-controller-events"; diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registrar.ts b/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registrar.ts index 86286171f..340dfd5b5 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registrar.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registrar.ts @@ -1,6 +1,6 @@ import { interpretTokenIdAsLabelHash, PluginName } from "@ensnode/ensnode-sdk"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { makeRegistrarHandlers } from "@/plugins/subgraph/shared-handlers/Registrar"; diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registry.ts b/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registry.ts index 2af355611..8089928ae 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registry.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/basenames/handlers/Registry.ts @@ -1,6 +1,6 @@ import { PluginName } from "@ensnode/ensnode-sdk"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { setupRootNode } from "@/lib/subgraph/subgraph-helpers"; import { diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/NameWrapper.ts b/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/NameWrapper.ts index 0436ce962..45a21f2e1 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/NameWrapper.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/NameWrapper.ts @@ -1,6 +1,6 @@ import { PluginName } from "@ensnode/ensnode-sdk"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { makeNameWrapperHandlers } from "@/plugins/subgraph/shared-handlers/NameWrapper"; diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registrar.ts b/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registrar.ts index 52c26920f..d4f11cdec 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registrar.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registrar.ts @@ -1,6 +1,6 @@ import { interpretTokenIdAsLabelHash, PluginName } from "@ensnode/ensnode-sdk"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { makeRegistrarHandlers } from "@/plugins/subgraph/shared-handlers/Registrar"; diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registry.ts b/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registry.ts index 10bf36575..bcfe7a3f6 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registry.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/handlers/Registry.ts @@ -1,6 +1,6 @@ import { PluginName } from "@ensnode/ensnode-sdk"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { setupRootNode } from "@/lib/subgraph/subgraph-helpers"; import { diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/NameWrapper.ts b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/NameWrapper.ts index c53ae28b2..bda7f3b2d 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/NameWrapper.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/NameWrapper.ts @@ -1,6 +1,6 @@ import { PluginName } from "@ensnode/ensnode-sdk"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { makeNameWrapperHandlers } from "@/plugins/subgraph/shared-handlers/NameWrapper"; diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registrar.ts b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registrar.ts index 221793a77..09dd49bca 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registrar.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registrar.ts @@ -1,6 +1,6 @@ import { interpretTokenIdAsLabelHash, PluginName } from "@ensnode/ensnode-sdk"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { makeRegistrarHandlers } from "@/plugins/subgraph/shared-handlers/Registrar"; diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts index 1d417ce15..a93c76ccf 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts @@ -3,7 +3,7 @@ import schema from "ponder:schema"; import { makeSubdomainNode, type Node, PluginName, ROOT_NODE } from "@ensnode/ensnode-sdk"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { setupRootNode } from "@/lib/subgraph/subgraph-helpers"; import { diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSResolver.ts b/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSResolver.ts index 4e1d680ea..799cae430 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSResolver.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSResolver.ts @@ -1,6 +1,6 @@ import { PluginName } from "@ensnode/ensnode-sdk"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { handleABIChanged, diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSToken.ts b/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSToken.ts index bfee5e584..227a906bb 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSToken.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/threedns/handlers/ThreeDNSToken.ts @@ -1,6 +1,6 @@ import { PluginName } from "@ensnode/ensnode-sdk"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { setupRootNode } from "@/lib/subgraph/subgraph-helpers"; import { diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/multi-chain/Resolver.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/multi-chain/Resolver.ts index 5cf49489e..abc9d115d 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/multi-chain/Resolver.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/multi-chain/Resolver.ts @@ -1,4 +1,4 @@ -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { handleABIChanged, diff --git a/apps/ensindexer/src/plugins/tokenscope/handlers/BaseRegistrars.ts b/apps/ensindexer/src/plugins/tokenscope/handlers/BaseRegistrars.ts index 8ca6ec1ed..9aedf952c 100644 --- a/apps/ensindexer/src/plugins/tokenscope/handlers/BaseRegistrars.ts +++ b/apps/ensindexer/src/plugins/tokenscope/handlers/BaseRegistrars.ts @@ -3,7 +3,7 @@ import config from "@/config"; import { DatasourceNames } from "@ensnode/datasources"; import { type NFTTransferEventMetadata, PluginName } from "@ensnode/ensnode-sdk"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { buildSupportedNFT } from "@/lib/tokenscope/nft-issuers"; diff --git a/apps/ensindexer/src/plugins/tokenscope/handlers/NameWrapper.ts b/apps/ensindexer/src/plugins/tokenscope/handlers/NameWrapper.ts index 355986403..3330113e8 100644 --- a/apps/ensindexer/src/plugins/tokenscope/handlers/NameWrapper.ts +++ b/apps/ensindexer/src/plugins/tokenscope/handlers/NameWrapper.ts @@ -3,7 +3,7 @@ import config from "@/config"; import { DatasourceNames } from "@ensnode/datasources"; import { type NFTTransferEventMetadata, PluginName } from "@ensnode/ensnode-sdk"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { buildSupportedNFT } from "@/lib/tokenscope/nft-issuers"; diff --git a/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts b/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts index da3ec2ea9..80af30d1e 100644 --- a/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts +++ b/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts @@ -4,7 +4,7 @@ import schema from "ponder:schema"; import { formatAssetId, PluginName } from "@ensnode/ensnode-sdk"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { upsertAccount } from "@/lib/subgraph/db-helpers"; import { makeEventId } from "@/lib/subgraph/ids"; diff --git a/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts b/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts index 52c1336ce..102d6fb4c 100644 --- a/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts +++ b/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts @@ -5,7 +5,7 @@ import { base, optimism } from "viem/chains"; import { type DatasourceName, DatasourceNames } from "@ensnode/datasources"; import { type ChainId, type NFTTransferEventMetadata, PluginName } from "@ensnode/ensnode-sdk"; -import { addOnchainEventListener } from "@/lib/onchain-events/add-onchain-event-listener"; +import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { buildSupportedNFT } from "@/lib/tokenscope/nft-issuers"; From 074ac56b9ca11acdd163481794b15bebbbc723ea Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Sat, 28 Mar 2026 16:11:43 +0100 Subject: [PATCH 07/11] Update naming convention used in event handlers Mechanical changes only: updateed `context.db` to `context.ensDb`, and `schema` to `ensIndexerSchema`. --- .../src/lib/ensv2/account-db-helpers.ts | 12 ++- .../src/lib/ensv2/domain-db-helpers.ts | 10 ++- .../src/lib/ensv2/event-db-helpers.ts | 33 +++++--- .../src/lib/ensv2/label-db-helpers.ts | 19 +++-- .../src/lib/ensv2/registration-db-helpers.ts | 41 ++++----- .../ensindexer/src/lib/get-this-account-id.ts | 9 +- .../lib/heal-addr-reverse-subname-label.ts | 4 +- ...domain-resolver-relationship-db-helpers.ts | 13 +-- .../registry-migration-status.ts | 13 +-- .../resolver-db-helpers.ts | 40 ++++----- .../ensindexer/src/lib/subgraph/db-helpers.ts | 37 ++++---- .../src/lib/subgraph/subgraph-helpers.ts | 20 ++--- .../ensv2/handlers/ensv1/BaseRegistrar.ts | 18 ++-- .../ensv2/handlers/ensv1/ENSv1Registry.ts | 24 +++--- .../ensv2/handlers/ensv1/NameWrapper.ts | 26 +++--- .../handlers/ensv1/RegistrarController.ts | 17 ++-- .../ensv2/handlers/ensv2/ENSv2Registry.ts | 52 +++++++----- .../ensv2/handlers/ensv2/ETHRegistrar.ts | 12 +-- .../handlers/ensv2/EnhancedAccessControl.ts | 27 +++--- .../plugins/ensv2/handlers/shared/Resolver.ts | 5 +- .../handlers/ENSv1Registry.ts | 8 +- .../handlers/ENSv2Registry.ts | 4 +- .../handlers/StandaloneReverseRegistrar.ts | 8 +- .../handlers/ThreeDNSToken.ts | 4 +- .../registrars/shared/lib/registrar-action.ts | 13 +-- .../shared/lib/registrar-controller-events.ts | 24 +++--- .../registrars/shared/lib/registrar-events.ts | 11 +-- .../shared/lib/registration-lifecycle.ts | 21 ++--- .../registrars/shared/lib/subregistry.ts | 17 ++-- ...-registrar-renewal-with-referrer-events.ts | 24 +++--- .../plugins/subgraph/handlers/Registry.ts | 8 +- .../subgraph/shared-handlers/NameWrapper.ts | 78 +++++++++-------- .../subgraph/shared-handlers/Registrar.ts | 54 ++++++------ .../subgraph/shared-handlers/Registry.ts | 50 +++++------ .../subgraph/shared-handlers/Resolver.ts | 84 ++++++++++--------- .../subgraph/shared-handlers/ThreeDNSToken.ts | 55 +++++++----- .../plugins/tokenscope/handlers/Seaport.ts | 4 +- .../tokenscope/handlers/ThreeDNSToken.ts | 4 +- .../tokenscope/lib/handle-nft-transfer.ts | 20 ++--- 39 files changed, 506 insertions(+), 417 deletions(-) diff --git a/apps/ensindexer/src/lib/ensv2/account-db-helpers.ts b/apps/ensindexer/src/lib/ensv2/account-db-helpers.ts index a7c2e40be..c0efe78ea 100644 --- a/apps/ensindexer/src/lib/ensv2/account-db-helpers.ts +++ b/apps/ensindexer/src/lib/ensv2/account-db-helpers.ts @@ -1,16 +1,20 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import type { Address } from "viem"; import { interpretAddress } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; + /** * Ensures that the account identified by `address` exists. * If `address` is the zeroAddress, no-op. */ -export async function ensureAccount(context: Context, address: Address) { +export async function ensureAccount(context: IndexingEngineContext, address: Address) { const interpreted = interpretAddress(address); if (interpreted === null) return; - await context.db.insert(schema.account).values({ id: interpreted }).onConflictDoNothing(); + await context.ensDb + .insert(ensIndexerSchema.account) + .values({ id: interpreted }) + .onConflictDoNothing(); } diff --git a/apps/ensindexer/src/lib/ensv2/domain-db-helpers.ts b/apps/ensindexer/src/lib/ensv2/domain-db-helpers.ts index 90097edbe..9c761f2c3 100644 --- a/apps/ensindexer/src/lib/ensv2/domain-db-helpers.ts +++ b/apps/ensindexer/src/lib/ensv2/domain-db-helpers.ts @@ -1,16 +1,16 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import type { Address } from "viem"; import { type ENSv1DomainId, interpretAddress } from "@ensnode/ensnode-sdk"; import { ensureAccount } from "@/lib/ensv2/account-db-helpers"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; /** * Sets an ENSv1 Domain's effective owner to `owner`. */ export async function materializeENSv1DomainEffectiveOwner( - context: Context, + context: IndexingEngineContext, id: ENSv1DomainId, owner: Address, ) { @@ -18,5 +18,7 @@ export async function materializeENSv1DomainEffectiveOwner( await ensureAccount(context, owner); // update v1Domain's effective owner - await context.db.update(schema.v1Domain, { id }).set({ ownerId: interpretAddress(owner) }); + await context.ensDb + .update(ensIndexerSchema.v1Domain, { id }) + .set({ ownerId: interpretAddress(owner) }); } diff --git a/apps/ensindexer/src/lib/ensv2/event-db-helpers.ts b/apps/ensindexer/src/lib/ensv2/event-db-helpers.ts index 708689aab..eca7a94e9 100644 --- a/apps/ensindexer/src/lib/ensv2/event-db-helpers.ts +++ b/apps/ensindexer/src/lib/ensv2/event-db-helpers.ts @@ -1,5 +1,4 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import type { Hash } from "viem"; import { @@ -9,6 +8,7 @@ import { makeResolverId, } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import type { LogEventBase } from "@/lib/ponder-helpers"; type Topics = [Hash, ...Hash[]]; @@ -25,7 +25,7 @@ const hasTopics = (topics: LogEventBase["log"]["topics"]): topics is Topics => * * @returns event.id */ -export async function ensureEvent(context: Context, event: LogEventBase) { +export async function ensureEvent(context: IndexingEngineContext, event: LogEventBase) { // all relevant ENS events obviously have a topic, so we can safely constrain the type of this data if (!hasTopics(event.log.topics)) { throw new Error(`Invariant: All events indexed via ensureEvent must have at least one topic.`); @@ -35,8 +35,8 @@ export async function ensureEvent(context: Context, event: LogEventBase) { // https://github.com/ponder-sh/ponder/blob/main/packages/core/src/sync-store/encode.ts#L59 const topics = event.log.topics.filter((topic): topic is Hash => topic !== null) as Topics; - await context.db - .insert(schema.event) + await context.ensDb + .insert(ensIndexerSchema.event) .values({ id: event.id, @@ -66,31 +66,38 @@ export async function ensureEvent(context: Context, event: LogEventBase) { return event.id; } -export async function ensureDomainEvent(context: Context, event: LogEventBase, domainId: DomainId) { +export async function ensureDomainEvent( + context: IndexingEngineContext, + event: LogEventBase, + domainId: DomainId, +) { const eventId = await ensureEvent(context, event); - await context.db.insert(schema.domainEvent).values({ domainId, eventId }).onConflictDoNothing(); + await context.ensDb + .insert(ensIndexerSchema.domainEvent) + .values({ domainId, eventId }) + .onConflictDoNothing(); } export async function ensureResolverEvent( - context: Context, + context: IndexingEngineContext, event: LogEventBase, resolver: AccountId, ) { const eventId = await ensureEvent(context, event); - await context.db - .insert(schema.resolverEvent) + await context.ensDb + .insert(ensIndexerSchema.resolverEvent) .values({ resolverId: makeResolverId(resolver), eventId }) .onConflictDoNothing(); } export async function ensurePermissionsEvent( - context: Context, + context: IndexingEngineContext, event: LogEventBase, contract: AccountId, ) { const eventId = await ensureEvent(context, event); - await context.db - .insert(schema.permissionsEvent) + await context.ensDb + .insert(ensIndexerSchema.permissionsEvent) .values({ permissionsId: makePermissionsId(contract), eventId }) .onConflictDoNothing(); } diff --git a/apps/ensindexer/src/lib/ensv2/label-db-helpers.ts b/apps/ensindexer/src/lib/ensv2/label-db-helpers.ts index 43a1b2574..602ffe04e 100644 --- a/apps/ensindexer/src/lib/ensv2/label-db-helpers.ts +++ b/apps/ensindexer/src/lib/ensv2/label-db-helpers.ts @@ -1,5 +1,4 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { labelhash } from "viem"; import { @@ -11,16 +10,17 @@ import { } from "@ensnode/ensnode-sdk"; import { labelByLabelHash } from "@/lib/graphnode-helpers"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; /** * Ensures that the LiteralLabel `label` is interpreted and upserted into the Label rainbow table. */ -export async function ensureLabel(context: Context, label: LiteralLabel) { +export async function ensureLabel(context: IndexingEngineContext, label: LiteralLabel) { const labelHash = labelhash(label); const interpreted = literalLabelToInterpretedLabel(label); - await context.db - .insert(schema.label) + await context.ensDb + .insert(ensIndexerSchema.label) .values({ labelHash, interpreted }) .onConflictDoUpdate({ interpreted }); } @@ -29,9 +29,9 @@ export async function ensureLabel(context: Context, label: LiteralLabel) { * Ensures that the LabelHash `labelHash` is available in the Label rainbow table, attempting an * ENSRainbow heal if this is the first time it has been encountered. */ -export async function ensureUnknownLabel(context: Context, labelHash: LabelHash) { +export async function ensureUnknownLabel(context: IndexingEngineContext, labelHash: LabelHash) { // do nothing for existing labels, they're either healed or we don't know them - const exists = await context.db.find(schema.label, { labelHash }); + const exists = await context.ensDb.find(ensIndexerSchema.label, { labelHash }); if (exists) return; // attempt ENSRainbow heal @@ -42,5 +42,8 @@ export async function ensureUnknownLabel(context: Context, labelHash: LabelHash) // otherwise upsert label entity const interpreted = encodeLabelHash(labelHash) as InterpretedLabel; - await context.db.insert(schema.label).values({ labelHash, interpreted }).onConflictDoNothing(); + await context.ensDb + .insert(ensIndexerSchema.label) + .values({ labelHash, interpreted }) + .onConflictDoNothing(); } diff --git a/apps/ensindexer/src/lib/ensv2/registration-db-helpers.ts b/apps/ensindexer/src/lib/ensv2/registration-db-helpers.ts index c4cde29c0..da9e7c79e 100644 --- a/apps/ensindexer/src/lib/ensv2/registration-db-helpers.ts +++ b/apps/ensindexer/src/lib/ensv2/registration-db-helpers.ts @@ -1,8 +1,9 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { type DomainId, makeRegistrationId, makeRenewalId } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; + /** * Latest Registration & Renewals * @@ -22,19 +23,21 @@ import { type DomainId, makeRegistrationId, makeRenewalId } from "@ensnode/ensno /** * Gets the latest Registration for the provided `domainId`. */ -export async function getLatestRegistration(context: Context, domainId: DomainId) { - const pointer = await context.db.find(schema.latestRegistrationIndex, { domainId }); +export async function getLatestRegistration(context: IndexingEngineContext, domainId: DomainId) { + const pointer = await context.ensDb.find(ensIndexerSchema.latestRegistrationIndex, { domainId }); if (!pointer) return null; - return context.db.find(schema.registration, { id: makeRegistrationId(domainId, pointer.index) }); + return context.ensDb.find(ensIndexerSchema.registration, { + id: makeRegistrationId(domainId, pointer.index), + }); } /** * Inserts a Registration and updates the latestRegistration pointer for its `domainId`. */ export async function insertLatestRegistration( - context: Context, - values: Omit, + context: IndexingEngineContext, + values: Omit, ) { const { domainId } = values; @@ -43,15 +46,15 @@ export async function insertLatestRegistration( const index = previous ? previous.index + 1 : 0; // insert new Registration - await context.db.insert(schema.registration).values({ + await context.ensDb.insert(ensIndexerSchema.registration).values({ id: makeRegistrationId(domainId, index), index, ...values, }); // ensure this Registration is the latest - await context.db - .insert(schema.latestRegistrationIndex) + await context.ensDb + .insert(ensIndexerSchema.latestRegistrationIndex) .values({ domainId, index }) .onConflictDoUpdate({ index }); } @@ -60,17 +63,17 @@ export async function insertLatestRegistration( * Gets the latest Renewal for the provided `domainId` and `registrationIndex`. */ export async function getLatestRenewal( - context: Context, + context: IndexingEngineContext, domainId: DomainId, registrationIndex: number, ) { - const pointer = await context.db.find(schema.latestRenewalIndex, { + const pointer = await context.ensDb.find(ensIndexerSchema.latestRenewalIndex, { domainId, registrationIndex, }); if (!pointer) return null; - return context.db.find(schema.renewal, { + return context.ensDb.find(ensIndexerSchema.renewal, { id: makeRenewalId(domainId, registrationIndex, pointer.index), }); } @@ -79,9 +82,9 @@ export async function getLatestRenewal( * Inserts a Renewal and updates the latestRenewal pointer for its `domainId` and `registrationIndex`. */ export async function insertLatestRenewal( - context: Context, - registration: Pick, - values: Omit, + context: IndexingEngineContext, + registration: Pick, + values: Omit, ) { const { index: registrationIndex } = registration; const { domainId } = values; @@ -91,7 +94,7 @@ export async function insertLatestRenewal( const index = previous ? previous.index + 1 : 0; // insert new Renewal - await context.db.insert(schema.renewal).values({ + await context.ensDb.insert(ensIndexerSchema.renewal).values({ id: makeRenewalId(domainId, registrationIndex, index), registrationIndex, index, @@ -99,8 +102,8 @@ export async function insertLatestRenewal( }); // ensure this Renewal is the latest - await context.db - .insert(schema.latestRenewalIndex) + await context.ensDb + .insert(ensIndexerSchema.latestRenewalIndex) .values({ domainId, registrationIndex, index }) .onConflictDoUpdate({ index }); } diff --git a/apps/ensindexer/src/lib/get-this-account-id.ts b/apps/ensindexer/src/lib/get-this-account-id.ts index efe625cf0..b6e88a732 100644 --- a/apps/ensindexer/src/lib/get-this-account-id.ts +++ b/apps/ensindexer/src/lib/get-this-account-id.ts @@ -1,7 +1,6 @@ -import type { Context } from "ponder:registry"; - import type { AccountId } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import type { LogEventBase } from "@/lib/ponder-helpers"; /** @@ -10,5 +9,7 @@ import type { LogEventBase } from "@/lib/ponder-helpers"; * @example * const { chainId, address } = getThisAccountId(context, event); */ -export const getThisAccountId = (context: Context, event: Pick) => - ({ chainId: context.chain.id, address: event.log.address }) satisfies AccountId; +export const getThisAccountId = ( + context: IndexingEngineContext, + event: Pick, +) => ({ chainId: context.chain.id, address: event.log.address }) satisfies AccountId; diff --git a/apps/ensindexer/src/lib/heal-addr-reverse-subname-label.ts b/apps/ensindexer/src/lib/heal-addr-reverse-subname-label.ts index 6c4bc79cb..c57c5970d 100644 --- a/apps/ensindexer/src/lib/heal-addr-reverse-subname-label.ts +++ b/apps/ensindexer/src/lib/heal-addr-reverse-subname-label.ts @@ -1,11 +1,11 @@ import config from "@/config"; -import type { Context } from "ponder:registry"; import type { Address } from "viem"; import { getENSRootChainId } from "@ensnode/datasources"; import type { LabelHash, LiteralLabel } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { maybeHealLabelByAddrReverseSubname } from "@/lib/maybe-heal-label-by-addr-reverse-subname"; import type { EventWithArgs } from "@/lib/ponder-helpers"; @@ -21,7 +21,7 @@ import { * @throws if unable to heal the addr.reverse subname's label */ export async function healAddrReverseSubnameLabel( - context: Context, + context: IndexingEngineContext, event: EventWithArgs<{ owner: Address }>, labelHash: LabelHash, ): Promise { diff --git a/apps/ensindexer/src/lib/protocol-acceleration/domain-resolver-relationship-db-helpers.ts b/apps/ensindexer/src/lib/protocol-acceleration/domain-resolver-relationship-db-helpers.ts index 28e33a533..79583444a 100644 --- a/apps/ensindexer/src/lib/protocol-acceleration/domain-resolver-relationship-db-helpers.ts +++ b/apps/ensindexer/src/lib/protocol-acceleration/domain-resolver-relationship-db-helpers.ts @@ -1,25 +1,26 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { type Address, isAddressEqual, zeroAddress } from "viem"; import type { AccountId, DomainId } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; + /** * Ensures that the Domain-Resolver Relationship for the provided `domainId` in `registry` is set * to `resolver`. If `resolver` is zeroAddress, it is interpreted as a deletion, and the relationship * is removed. */ export async function ensureDomainResolverRelation( - context: Context, + context: IndexingEngineContext, registry: AccountId, domainId: DomainId, resolver: Address, ) { if (isAddressEqual(zeroAddress, resolver)) { - await context.db.delete(schema.domainResolverRelation, { ...registry, domainId }); + await context.ensDb.delete(ensIndexerSchema.domainResolverRelation, { ...registry, domainId }); } else { - await context.db - .insert(schema.domainResolverRelation) + await context.ensDb + .insert(ensIndexerSchema.domainResolverRelation) .values({ ...registry, domainId, resolver }) .onConflictDoUpdate({ resolver }); } diff --git a/apps/ensindexer/src/lib/protocol-acceleration/registry-migration-status.ts b/apps/ensindexer/src/lib/protocol-acceleration/registry-migration-status.ts index b5f1a2207..1a3a5f29e 100644 --- a/apps/ensindexer/src/lib/protocol-acceleration/registry-migration-status.ts +++ b/apps/ensindexer/src/lib/protocol-acceleration/registry-migration-status.ts @@ -1,36 +1,37 @@ import config from "@/config"; -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { getENSRootChainId } from "@ensnode/datasources"; import type { Node } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; + const ensRootChainId = getENSRootChainId(config.namespace); /** * Returns whether the `node` has migrated to the new Registry contract. */ -export async function nodeIsMigrated(context: Context, node: Node) { +export async function nodeIsMigrated(context: IndexingEngineContext, node: Node) { if (context.chain.id !== ensRootChainId) { throw new Error( `Invariant(nodeIsMigrated): Node migration status is only relevant on the ENS Root Chain, and this function was called in the context of ${context.chain.id}.`, ); } - const record = await context.db.find(schema.migratedNode, { node }); + const record = await context.ensDb.find(ensIndexerSchema.migratedNode, { node }); return !!record; } /** * Record that the `node` has migrated to the new Registry contract. */ -export async function migrateNode(context: Context, node: Node) { +export async function migrateNode(context: IndexingEngineContext, node: Node) { if (context.chain.id !== ensRootChainId) { throw new Error( `Invariant(migrateNode): Node migration status is only relevant on the ENS Root Chain, and this function was called in the context of ${context.chain.id}.`, ); } - await context.db.insert(schema.migratedNode).values({ node }).onConflictDoNothing(); + await context.ensDb.insert(ensIndexerSchema.migratedNode).values({ node }).onConflictDoNothing(); } diff --git a/apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts b/apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts index a3d42e14e..7862c2aa5 100644 --- a/apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts +++ b/apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts @@ -1,5 +1,4 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import type { Address } from "viem"; import { @@ -16,13 +15,14 @@ import { interpretTextRecordValue, } from "@ensnode/ensnode-sdk/internal"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import type { EventWithArgs } from "@/lib/ponder-helpers"; /** * Infer the type of the ResolverRecord entity's composite key. */ type ResolverRecordsCompositeKey = Pick< - typeof schema.resolverRecords.$inferInsert, + typeof ensIndexerSchema.resolverRecords.$inferInsert, "chainId" | "address" | "node" >; @@ -44,9 +44,9 @@ export function makeResolverRecordsCompositeKey( /** * Ensures that the Resolver contract described by `resolver` exists. */ -export async function ensureResolver(context: Context, resolver: AccountId) { - await context.db - .insert(schema.resolver) +export async function ensureResolver(context: IndexingEngineContext, resolver: AccountId) { + await context.ensDb + .insert(ensIndexerSchema.resolver) .values({ id: makeResolverId(resolver), ...resolver, @@ -58,7 +58,7 @@ export async function ensureResolver(context: Context, resolver: AccountId) { * Ensures that the ResolverRecords entity described by `resolverRecordsKey` exists. */ export async function ensureResolverRecords( - context: Context, + context: IndexingEngineContext, resolverRecordsKey: ResolverRecordsCompositeKey, ) { const resolver: AccountId = { @@ -68,8 +68,8 @@ export async function ensureResolverRecords( const resolverRecordsId = makeResolverRecordsId(resolver, resolverRecordsKey.node); // ensure ResolverRecords - await context.db - .insert(schema.resolverRecords) + await context.ensDb + .insert(ensIndexerSchema.resolverRecords) .values({ id: resolverRecordsId, ...resolverRecordsKey, @@ -81,7 +81,7 @@ export async function ensureResolverRecords( * Updates the `name` record value for the ResolverRecords described by `id`. */ export async function handleResolverNameUpdate( - context: Context, + context: IndexingEngineContext, resolverRecordsKey: ResolverRecordsCompositeKey, name: string, ) { @@ -90,8 +90,8 @@ export async function handleResolverNameUpdate( resolverRecordsKey.node, ); - await context.db - .update(schema.resolverRecords, { id: resolverRecordsId }) + await context.ensDb + .update(ensIndexerSchema.resolverRecords, { id: resolverRecordsId }) .set({ name: interpretNameRecordValue(name) }); } @@ -99,7 +99,7 @@ export async function handleResolverNameUpdate( * Updates the `address` record value by `coinType` for the ResolverRecords described by `id`. */ export async function handleResolverAddressRecordUpdate( - context: Context, + context: IndexingEngineContext, resolverRecordsKey: ResolverRecordsCompositeKey, coinType: CoinType, address: Address, @@ -114,11 +114,11 @@ export async function handleResolverAddressRecordUpdate( const isDeletion = interpretedValue === null; if (isDeletion) { // delete - await context.db.delete(schema.resolverAddressRecord, id); + await context.ensDb.delete(ensIndexerSchema.resolverAddressRecord, id); } else { // upsert - await context.db - .insert(schema.resolverAddressRecord) + await context.ensDb + .insert(ensIndexerSchema.resolverAddressRecord) .values({ ...id, value: interpretedValue }) .onConflictDoUpdate({ value: interpretedValue }); } @@ -130,7 +130,7 @@ export async function handleResolverAddressRecordUpdate( * If `value` is null, it will be interpreted as a deletion of the associated record. */ export async function handleResolverTextRecordUpdate( - context: Context, + context: IndexingEngineContext, resolverRecordsId: ResolverRecordsCompositeKey, key: string, value: string | null, @@ -150,11 +150,11 @@ export async function handleResolverTextRecordUpdate( const isDeletion = interpretedValue === null; if (isDeletion) { // delete - await context.db.delete(schema.resolverTextRecord, id); + await context.ensDb.delete(ensIndexerSchema.resolverTextRecord, id); } else { // upsert - await context.db - .insert(schema.resolverTextRecord) + await context.ensDb + .insert(ensIndexerSchema.resolverTextRecord) .values({ ...id, value: interpretedValue }) .onConflictDoUpdate({ value: interpretedValue }); } diff --git a/apps/ensindexer/src/lib/subgraph/db-helpers.ts b/apps/ensindexer/src/lib/subgraph/db-helpers.ts index ec2f62559..8645c5479 100644 --- a/apps/ensindexer/src/lib/subgraph/db-helpers.ts +++ b/apps/ensindexer/src/lib/subgraph/db-helpers.ts @@ -1,43 +1,52 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import type { Address } from "viem"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import type { LogEventBase } from "@/lib/ponder-helpers"; import { makeEventId } from "@/lib/subgraph/ids"; -export async function upsertAccount(context: Context, address: Address) { - return context.db.insert(schema.subgraph_account).values({ id: address }).onConflictDoNothing(); +export async function upsertAccount(context: IndexingEngineContext, address: Address) { + return context.ensDb + .insert(ensIndexerSchema.subgraph_account) + .values({ id: address }) + .onConflictDoNothing(); } export async function upsertDomain( - context: Context, - values: typeof schema.subgraph_domain.$inferInsert, + context: IndexingEngineContext, + values: typeof ensIndexerSchema.subgraph_domain.$inferInsert, ) { // biome-ignore lint/correctness/noUnusedVariables: remove id primary key for update values const { id, ...otherValues } = values; - return context.db.insert(schema.subgraph_domain).values(values).onConflictDoUpdate(otherValues); + return context.ensDb + .insert(ensIndexerSchema.subgraph_domain) + .values(values) + .onConflictDoUpdate(otherValues); } export async function upsertResolver( - context: Context, - values: typeof schema.subgraph_resolver.$inferInsert, + context: IndexingEngineContext, + values: typeof ensIndexerSchema.subgraph_resolver.$inferInsert, ) { // biome-ignore lint/correctness/noUnusedVariables: remove id primary key for update values const { id, ...otherValues } = values; - return context.db.insert(schema.subgraph_resolver).values(values).onConflictDoUpdate(otherValues); + return context.ensDb + .insert(ensIndexerSchema.subgraph_resolver) + .values(values) + .onConflictDoUpdate(otherValues); } export async function upsertRegistration( - context: Context, - values: typeof schema.subgraph_registration.$inferInsert, + context: IndexingEngineContext, + values: typeof ensIndexerSchema.subgraph_registration.$inferInsert, ) { // biome-ignore lint/correctness/noUnusedVariables: remove id primary key for update values const { id, ...otherValues } = values; - return context.db - .insert(schema.subgraph_registration) + return context.ensDb + .insert(ensIndexerSchema.subgraph_registration) .values(values) .onConflictDoUpdate(otherValues); } diff --git a/apps/ensindexer/src/lib/subgraph/subgraph-helpers.ts b/apps/ensindexer/src/lib/subgraph/subgraph-helpers.ts index e172e8013..883179189 100644 --- a/apps/ensindexer/src/lib/subgraph/subgraph-helpers.ts +++ b/apps/ensindexer/src/lib/subgraph/subgraph-helpers.ts @@ -1,11 +1,11 @@ import config from "@/config"; -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { isAddressEqual, zeroAddress } from "viem"; import { type Node, ROOT_NODE } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { upsertAccount } from "@/lib/subgraph/db-helpers"; /** @@ -19,14 +19,14 @@ import { upsertAccount } from "@/lib/subgraph/db-helpers"; * entirely idempotent (i.e. with `.onConflictDoNothing()`). * https://ponder.sh/docs/api-reference/indexing-functions#setup-event */ -export async function setupRootNode({ context }: { context: Context }) { +export async function setupRootNode({ context }: { context: IndexingEngineContext }) { // Each domain must reference an account of its owner, // so we ensure the account exists before inserting the domain await upsertAccount(context, zeroAddress); // create the ENS root domain (if not exists) - await context.db - .insert(schema.subgraph_domain) + await context.ensDb + .insert(ensIndexerSchema.subgraph_domain) .values({ id: ROOT_NODE, ownerId: zeroAddress, @@ -49,7 +49,7 @@ export async function setupRootNode({ context }: { context: Context }) { // a domain is 'empty' if it has no resolver, no owner, and no subdomains // via https://github.com/ensdomains/ens-subgraph/blob/c844791/src/ensRegistry.ts#L65 -function isDomainEmpty(domain: typeof schema.subgraph_domain.$inferSelect) { +function isDomainEmpty(domain: typeof ensIndexerSchema.subgraph_domain.$inferSelect) { return ( domain.resolverId === null && isAddressEqual(domain.ownerId, zeroAddress) && @@ -60,16 +60,16 @@ function isDomainEmpty(domain: typeof schema.subgraph_domain.$inferSelect) { // a more accurate name for 'recurseDomainDelete' // https://github.com/ensdomains/ens-subgraph/blob/c68a889/src/ensRegistry.ts#L64 export async function recursivelyRemoveEmptyDomainFromParentSubdomainCount( - context: Context, + context: IndexingEngineContext, node: Node, ) { - const domain = await context.db.find(schema.subgraph_domain, { id: node }); + const domain = await context.ensDb.find(ensIndexerSchema.subgraph_domain, { id: node }); if (!domain) throw new Error(`Domain not found: ${node}`); if (isDomainEmpty(domain) && domain.parentId !== null) { // decrement parent's subdomain count - await context.db - .update(schema.subgraph_domain, { id: domain.parentId }) + await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: domain.parentId }) .set((row) => ({ subdomainCount: row.subdomainCount - 1 })); // recurse to parent diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts index c2363afc8..a23377cf3 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts @@ -1,5 +1,4 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { GRACE_PERIOD_SECONDS } from "@ensdomains/ensjs/utils"; import { type Address, isAddressEqual, zeroAddress } from "viem"; @@ -21,6 +20,7 @@ import { insertLatestRenewal, } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { getManagedName } from "@/lib/managed-names"; @@ -49,7 +49,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ from: Address; to: Address; @@ -82,7 +82,7 @@ export default function () { } // materialize Domain owner if exists - const domain = await context.db.find(schema.v1Domain, { id: domainId }); + const domain = await context.ensDb.find(ensIndexerSchema.v1Domain, { id: domainId }); if (domain) await materializeENSv1DomainEffectiveOwner(context, domainId, to); // push event to domain history @@ -94,7 +94,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ id: bigint; owner: Address; @@ -137,7 +137,7 @@ export default function () { }); // materialize Domain owner if exists - const domain = await context.db.find(schema.v1Domain, { id: domainId }); + const domain = await context.ensDb.find(ensIndexerSchema.v1Domain, { id: domainId }); if (domain) await materializeENSv1DomainEffectiveOwner(context, domainId, owner); // push event to domain history @@ -159,7 +159,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ id: bigint; expires: bigint }>; }) => { const { id: tokenId, expires: expiry } = event.args; @@ -224,7 +224,9 @@ export default function () { const duration = expiry - registration.expiry; // update the registration - await context.db.update(schema.registration, { id: registration.id }).set({ expiry }); + await context.ensDb + .update(ensIndexerSchema.registration, { id: registration.id }) + .set({ expiry }); // insert Renewal await insertLatestRenewal(context, registration, { diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts index e8d2d080d..55650f661 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts @@ -1,7 +1,6 @@ import config from "@/config"; -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { type Address, isAddressEqual, zeroAddress } from "viem"; import { @@ -20,6 +19,7 @@ import { materializeENSv1DomainEffectiveOwner } from "@/lib/ensv2/domain-db-help import { ensureDomainEvent } from "@/lib/ensv2/event-db-helpers"; import { ensureLabel, ensureUnknownLabel } from "@/lib/ensv2/label-db-helpers"; import { healAddrReverseSubnameLabel } from "@/lib/heal-addr-reverse-subname-label"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; @@ -39,7 +39,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ // NOTE: `node` event arg represents a `Node` that is the _parent_ of the node the NewOwner event is about node: Node; @@ -76,14 +76,14 @@ export default function () { } // upsert domain - await context.db - .insert(schema.v1Domain) + await context.ensDb + .insert(ensIndexerSchema.v1Domain) .values({ id: domainId, parentId, labelHash }) .onConflictDoNothing(); // update rootRegistryOwner - await context.db - .update(schema.v1Domain, { id: domainId }) + await context.ensDb + .update(ensIndexerSchema.v1Domain, { id: domainId }) .set({ rootRegistryOwnerId: interpretAddress(owner) }); // materialize domain owner @@ -102,7 +102,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; owner: Address }>; }) { const { node, owner } = event.args; @@ -113,8 +113,8 @@ export default function () { const domainId = makeENSv1DomainId(node); // set the domain's rootRegistryOwner to `owner` - await context.db - .update(schema.v1Domain, { id: domainId }) + await context.ensDb + .update(ensIndexerSchema.v1Domain, { id: domainId }) .set({ rootRegistryOwnerId: interpretAddress(owner) }); // materialize domain owner @@ -133,7 +133,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node }>; }) { const { node } = event.args; @@ -150,7 +150,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node }>; }) { const { node } = event.args; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts index b6c28079d..9befad436 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts @@ -1,5 +1,4 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { type Address, isAddressEqual, zeroAddress } from "viem"; import { @@ -30,6 +29,7 @@ import { insertLatestRenewal, } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { getManagedName } from "@/lib/managed-names"; @@ -90,7 +90,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ operator: Address; from: Address; @@ -145,7 +145,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; name: DNSEncodedName; @@ -222,7 +222,7 @@ export default function () { throw new Error("Wrapper expiry exceeds registrar expiry + grace period"); } - await context.db.update(schema.registration, { id: registration.id }).set({ + await context.ensDb.update(ensIndexerSchema.registration, { id: registration.id }).set({ wrapped: true, fuses, // expiry, // TODO: NameWrapper expiry logic @@ -265,7 +265,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; owner: Address }>; }) => { const { node } = event.args; @@ -279,14 +279,14 @@ export default function () { if (registration.type === "BaseRegistrar") { // if this is a wrapped BaseRegistrar Registration, unwrap it - await context.db.update(schema.registration, { id: registration.id }).set({ + await context.ensDb.update(ensIndexerSchema.registration, { id: registration.id }).set({ wrapped: false, fuses: null, // expiry: null // TODO: NameWrapper expiry logic? maybe nothing to do here }); } else { // otherwise, deactivate the latest registration by setting its expiry to this block - await context.db.update(schema.registration, { id: registration.id }).set({ + await context.ensDb.update(ensIndexerSchema.registration, { id: registration.id }).set({ expiry: event.block.timestamp, }); } @@ -307,7 +307,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; fuses: number }>; }) => { const { node, fuses } = event.args; @@ -323,7 +323,7 @@ export default function () { } // upsert fuses - await context.db.update(schema.registration, { id: registration.id }).set({ + await context.ensDb.update(ensIndexerSchema.registration, { id: registration.id }).set({ fuses, // expiry: // TODO: NameWrapper expiry logic ? }); @@ -342,7 +342,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; expiry: bigint }>; }) => { const { node, expiry: _expiry } = event.args; @@ -358,7 +358,9 @@ export default function () { ); } - await context.db.update(schema.registration, { id: registration.id }).set({ expiry }); + await context.ensDb + .update(ensIndexerSchema.registration, { id: registration.id }) + .set({ expiry }); // push event to domain history await ensureDomainEvent(context, event, domainId); diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts index 796b1f936..c9587bb21 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts @@ -1,6 +1,6 @@ /** biome-ignore-all lint/correctness/noUnusedVariables: ignore for now */ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; + +import ensIndexerSchema from "ponder:schema"; import { type EncodedReferrer, @@ -17,6 +17,7 @@ import { ensureDomainEvent } from "@/lib/ensv2/event-db-helpers"; import { ensureLabel, ensureUnknownLabel } from "@/lib/ensv2/label-db-helpers"; import { getLatestRegistration, getLatestRenewal } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { getManagedName } from "@/lib/managed-names"; @@ -30,7 +31,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ label?: Label; labelHash: LabelHash; @@ -71,8 +72,8 @@ export default function () { // update registration's base/premium // TODO(paymentToken): add payment token tracking here - await context.db - .update(schema.registration, { id: registration.id }) + await context.ensDb + .update(ensIndexerSchema.registration, { id: registration.id }) .set({ base, premium, referrer }); // push event to domain history @@ -83,7 +84,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ label?: string; labelHash: LabelHash; @@ -146,7 +147,9 @@ export default function () { // update renewal info // TODO(paymentToken): add payment token tracking here - await context.db.update(schema.renewal, { id: renewal.id }).set({ base, premium, referrer }); + await context.ensDb + .update(ensIndexerSchema.renewal, { id: renewal.id }) + .set({ base, premium, referrer }); // push event to domain history await ensureDomainEvent(context, event, domainId); diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts index 8746df5e1..ff70480f4 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts @@ -1,5 +1,4 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { type Address, hexToBigInt, labelhash } from "viem"; import { @@ -22,6 +21,7 @@ import { insertLatestRegistration, } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { namespaceContract } from "@/lib/plugin-helpers"; @@ -36,7 +36,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ tokenId: bigint; labelHash: LabelHash; @@ -72,8 +72,8 @@ export default function () { // upsert Registry // TODO(signals) — move to NewRegistry and add invariant here - await context.db - .insert(schema.registry) + await context.ensDb + .insert(ensIndexerSchema.registry) .values({ id: registryId, type: "RegistryContract", @@ -99,8 +99,8 @@ export default function () { // insert or update v2Domain // console.log(`NameRegistered: '${label}'\n ↳ ${domainId}`); - await context.db - .insert(schema.v2Domain) + await context.ensDb + .insert(ensIndexerSchema.v2Domain) .values({ id: domainId, tokenId, @@ -135,7 +135,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ tokenId: bigint; newExpiry: bigint; @@ -164,7 +164,9 @@ export default function () { } // update Registration - await context.db.update(schema.registration, { id: registration.id }).set({ expiry }); + await context.ensDb + .update(ensIndexerSchema.registration, { id: registration.id }) + .set({ expiry }); // push event to domain history await ensureDomainEvent(context, event, domainId); @@ -177,7 +179,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ tokenId: bigint; subregistry: Address; @@ -196,26 +198,30 @@ export default function () { // subregistry. i.e. the (sub)Registry's Canonical Domain becomes null, making it disjoint because // we don't track other domains who have set it as a Subregistry. This is acceptable for now, // and obviously isn't an issue once ENS Team implements Canonical Names - const previous = await context.db.find(schema.v2Domain, { id: domainId }); + const previous = await context.ensDb.find(ensIndexerSchema.v2Domain, { id: domainId }); if (previous?.subregistryId) { - await context.db.delete(schema.registryCanonicalDomain, { + await context.ensDb.delete(ensIndexerSchema.registryCanonicalDomain, { registryId: previous.subregistryId, }); } - await context.db.update(schema.v2Domain, { id: domainId }).set({ subregistryId: null }); + await context.ensDb + .update(ensIndexerSchema.v2Domain, { id: domainId }) + .set({ subregistryId: null }); } else { const subregistryAccountId: AccountId = { chainId: context.chain.id, address: subregistry }; const subregistryId = makeRegistryId(subregistryAccountId); // TODO(canonical-names): this implements last-write-wins heuristic for a Registry's canonical name, // replace with real logic once ENS Team implements Canonical Names - await context.db - .insert(schema.registryCanonicalDomain) + await context.ensDb + .insert(ensIndexerSchema.registryCanonicalDomain) .values({ registryId: subregistryId, domainId }) .onConflictDoUpdate({ domainId }); - await context.db.update(schema.v2Domain, { id: domainId }).set({ subregistryId }); + await context.ensDb + .update(ensIndexerSchema.v2Domain, { id: domainId }) + .set({ subregistryId }); } // push event to domain history @@ -229,7 +235,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ oldTokenId: bigint; newTokenId: bigint; @@ -246,7 +252,9 @@ export default function () { const registryAccountId = getThisAccountId(context, event); const domainId = makeENSv2DomainId(registryAccountId, canonicalId); - await context.db.update(schema.v2Domain, { id: domainId }).set({ tokenId: newTokenId }); + await context.ensDb + .update(ensIndexerSchema.v2Domain, { id: domainId }) + .set({ tokenId: newTokenId }); // push event to domain history await ensureDomainEvent(context, event, domainId); @@ -257,7 +265,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ id: bigint; to: Address }>; }) { const { id: tokenId, to: owner } = event.args; @@ -268,13 +276,13 @@ export default function () { // TODO(signals): remove this const registryId = makeRegistryId(registry); - const exists = await context.db.find(schema.registry, { id: registryId }); + const exists = await context.ensDb.find(ensIndexerSchema.registry, { id: registryId }); if (!exists) return; // no-op non-Registry ERC1155 Transfers // just update the owner // any _burns are always followed by a _mint, which would set the owner correctly - await context.db - .update(schema.v2Domain, { id: domainId }) + await context.ensDb + .update(ensIndexerSchema.v2Domain, { id: domainId }) .set({ ownerId: interpretAddress(owner) }); // push event to domain history diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts index 745714932..9c3b52e10 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts @@ -1,5 +1,4 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import type { Address } from "viem"; import { @@ -17,6 +16,7 @@ import { ensureAccount } from "@/lib/ensv2/account-db-helpers"; import { ensureDomainEvent, ensureEvent } from "@/lib/ensv2/event-db-helpers"; import { getLatestRegistration, insertLatestRenewal } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { namespaceContract } from "@/lib/plugin-helpers"; @@ -24,7 +24,7 @@ import type { EventWithArgs, LogEventBase } from "@/lib/ponder-helpers"; const pluginName = PluginName.ENSv2; -async function getRegistrarAndRegistry(context: Context, event: LogEventBase) { +async function getRegistrarAndRegistry(context: IndexingEngineContext, event: LogEventBase) { const registrar = getThisAccountId(context, event); const registry: AccountId = { chainId: context.chain.id, @@ -46,7 +46,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ tokenId: TokenId; label: string; @@ -99,7 +99,7 @@ export default function () { await ensureAccount(context, owner); // update latest Registration - await context.db.update(schema.registration, { id: registration.id }).set({ + await context.ensDb.update(ensIndexerSchema.registration, { id: registration.id }).set({ // TODO: reconsider 'Registration.registrant' if ENSv2 doesn't provide explicit 'registrant' registrantId: interpretAddress(owner), @@ -125,7 +125,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ tokenId: TokenId; label: string; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts index 45de2155b..04789919e 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts @@ -1,5 +1,4 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { type Address, isAddressEqual, zeroAddress } from "viem"; import { @@ -12,6 +11,7 @@ import { import { ensureAccount } from "@/lib/ensv2/account-db-helpers"; import { ensurePermissionsEvent } from "@/lib/ensv2/event-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; @@ -19,10 +19,13 @@ import type { EventWithArgs } from "@/lib/ponder-helpers"; /** * Infer the type of the Permission entity's composite key. */ -type PermissionsCompositeKey = Pick; +type PermissionsCompositeKey = Pick< + typeof ensIndexerSchema.permissions.$inferInsert, + "chainId" | "address" +>; const ensurePermissionsResource = async ( - context: Context, + context: IndexingEngineContext, contract: PermissionsCompositeKey, resource: bigint, ) => { @@ -30,14 +33,14 @@ const ensurePermissionsResource = async ( const permissionsResourceId = makePermissionsResourceId(contract, resource); // ensure permissions - await context.db - .insert(schema.permissions) + await context.ensDb + .insert(ensIndexerSchema.permissions) .values({ id: permissionsId, ...contract }) .onConflictDoNothing(); // ensure permissions resource - await context.db - .insert(schema.permissionsResource) + await context.ensDb + .insert(ensIndexerSchema.permissionsResource) .values({ id: permissionsResourceId, ...contract, resource }) .onConflictDoNothing(); }; @@ -51,7 +54,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ resource: bigint; account: Address; @@ -78,11 +81,11 @@ export default function () { const roles = newRoleBitmap; if (isZeroRoles(roles)) { // ensure deleted - await context.db.delete(schema.permissionsUser, { id: permissionsUserId }); + await context.ensDb.delete(ensIndexerSchema.permissionsUser, { id: permissionsUserId }); } else { // ensure upserted - await context.db - .insert(schema.permissionsUser) + await context.ensDb + .insert(ensIndexerSchema.permissionsUser) .values({ id: permissionsUserId, ...contract, resource, user, roles }) .onConflictDoUpdate({ roles }); } diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts b/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts index 4f08972a1..8e04a0862 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts @@ -1,9 +1,8 @@ -import type { Context } from "ponder:registry"; - import { PluginName } from "@ensnode/ensnode-sdk"; import { ensureResolverEvent } from "@/lib/ensv2/event-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { LogEventBase } from "@/lib/ponder-helpers"; @@ -21,7 +20,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: LogEventBase; }) { const resolver = getThisAccountId(context, event); diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts index 5352af56f..2cb137eef 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts @@ -1,6 +1,5 @@ import config from "@/config"; -import type { Context } from "ponder:registry"; import type { Address } from "viem"; import { getENSRootChainId } from "@ensnode/datasources"; @@ -13,6 +12,7 @@ import { } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; @@ -33,7 +33,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; resolver: Address }>; }) { const { node, resolver } = event.args; @@ -54,7 +54,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ // NOTE: `node` event arg represents a `Node` that is the _parent_ of the node the NewOwner event is about node: Node; @@ -82,7 +82,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; resolver: Address }>; }) => { // ignore the event on ENSv1RegistryOld if node is migrated to new Registry diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts index d111a0cd7..212f839ca 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts @@ -1,9 +1,9 @@ -import type { Context } from "ponder:registry"; import type { Address } from "viem"; import { getCanonicalId, makeENSv2DomainId, PluginName } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; @@ -18,7 +18,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ tokenId: bigint; resolver: Address; diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts index e4b24efc9..3d5ae2f88 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts @@ -1,6 +1,6 @@ import config from "@/config"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { getENSRootChainId } from "@ensnode/datasources"; import { DEFAULT_EVM_COIN_TYPE, evmChainIdToCoinType, PluginName } from "@ensnode/ensnode-sdk"; @@ -40,11 +40,11 @@ export default function () { const isDeletion = interpretedValue === null; if (isDeletion) { // delete - await context.db.delete(schema.reverseNameRecord, id); + await context.ensDb.delete(ensIndexerSchema.reverseNameRecord, id); } else { // upsert - await context.db - .insert(schema.reverseNameRecord) + await context.ensDb + .insert(ensIndexerSchema.reverseNameRecord) .values({ ...id, value: interpretedValue }) .onConflictDoUpdate({ value: interpretedValue }); } diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts index b0bd09b71..2b3548a81 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts @@ -1,6 +1,5 @@ import config from "@/config"; -import type { Context } from "ponder:registry"; import type { Address } from "viem"; import { DatasourceNames, maybeGetDatasource } from "@ensnode/datasources"; @@ -14,6 +13,7 @@ import { } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; @@ -45,7 +45,7 @@ export default function () { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ // NOTE: `node` event arg represents a `Node` that is the _parent_ of the node the NewOwner event is about node: Node; diff --git a/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-action.ts b/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-action.ts index c4d6f3fa7..501d01b74 100644 --- a/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-action.ts +++ b/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-action.ts @@ -1,9 +1,10 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import type { Hash } from "viem"; import { formatAccountId, type Node, type RegistrarAction } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; + /** * Logical Event Key * @@ -32,7 +33,7 @@ export function makeLogicalEventKey({ * Insert a record for the "logical registrar action". */ export async function insertRegistrarAction( - context: Context, + context: IndexingEngineContext, { id, type, @@ -58,8 +59,8 @@ export async function insertRegistrarAction( // we update it to point to the current logical event key and id. // This ensures that there is always at most one record in ENSDb // for the current "logical registrar action". - await context.db - .insert(schema.internal_registrarActionMetadata) + await context.ensDb + .insert(ensIndexerSchema.internal_registrarActionMetadata) .values({ metadataType: "CURRENT_LOGICAL_REGISTRAR_ACTION", logicalEventKey, @@ -71,7 +72,7 @@ export async function insertRegistrarAction( })); // 3. Store initial record for the "logical registrar action" - await context.db.insert(schema.registrarActions).values({ + await context.ensDb.insert(ensIndexerSchema.registrarActions).values({ id, type, subregistryId: formatAccountId(subregistryId), diff --git a/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-controller-events.ts b/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-controller-events.ts index 75f65e370..eda954dca 100644 --- a/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-controller-events.ts +++ b/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-controller-events.ts @@ -1,5 +1,4 @@ -import type { Context, Event } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import type { Address, Hash } from "viem"; import { @@ -11,6 +10,8 @@ import { type RegistrarActionReferral, } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext, IndexingEngineEvent } from "@/lib/indexing-engines/ponder"; + import { makeLogicalEventKey } from "./registrar-action"; /** @@ -20,7 +21,7 @@ import { makeLogicalEventKey } from "./registrar-action"; * - append new event ID to `eventIds` */ export async function handleRegistrarControllerEvent( - context: Context, + context: IndexingEngineContext, { id, node, @@ -28,7 +29,7 @@ export async function handleRegistrarControllerEvent( referral, transactionHash, }: { - id: Event["id"]; + id: IndexingEngineEvent["id"]; node: Node; pricing: RegistrarActionPricing; referral: RegistrarActionReferral; @@ -45,9 +46,12 @@ export async function handleRegistrarControllerEvent( // which needs to be updated. // 2. a) Find registrarActionMetadata record for the current "logical registrar action". - const registrarActionMetadata = await context.db.find(schema.internal_registrarActionMetadata, { - metadataType: "CURRENT_LOGICAL_REGISTRAR_ACTION", - }); + const registrarActionMetadata = await context.ensDb.find( + ensIndexerSchema.internal_registrarActionMetadata, + { + metadataType: "CURRENT_LOGICAL_REGISTRAR_ACTION", + }, + ); // Invariant: the registrarActionMetadata record must exist if (!registrarActionMetadata) { @@ -64,7 +68,7 @@ export async function handleRegistrarControllerEvent( } // 2. b) Find "logical registrar action" record by `logicalEventId`. - const logicalRegistrarAction = await context.db.find(schema.registrarActions, { + const logicalRegistrarAction = await context.ensDb.find(ensIndexerSchema.registrarActions, { id: registrarActionMetadata.logicalEventId, }); @@ -106,8 +110,8 @@ export async function handleRegistrarControllerEvent( // - pricing data, // - referral data // - new event ID appended to `eventIds` - await context.db - .update(schema.registrarActions, { id: logicalRegistrarAction.id }) + await context.ensDb + .update(ensIndexerSchema.registrarActions, { id: logicalRegistrarAction.id }) .set(({ eventIds }) => ({ baseCost, premium, diff --git a/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-events.ts b/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-events.ts index 18bbaceae..a6a739efd 100644 --- a/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-events.ts +++ b/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-events.ts @@ -2,7 +2,6 @@ * This file contains handlers used in event handlers for a Registrar contract. */ -import type { Context, Event } from "ponder:registry"; import type { Address, Hash } from "viem"; import { @@ -16,6 +15,8 @@ import { type UnixTimestamp, } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext, IndexingEngineEvent } from "@/lib/indexing-engines/ponder"; + import { insertRegistrarAction } from "./registrar-action"; import { getRegistrationLifecycle, @@ -28,7 +29,7 @@ import { getSubregistry } from "./subregistry"; * Handle Registrar Event: Registration */ export async function handleRegistrarEventRegistration( - context: Context, + context: IndexingEngineContext, { id, subregistryId, @@ -38,7 +39,7 @@ export async function handleRegistrarEventRegistration( block, transactionHash, }: { - id: Event["id"]; + id: IndexingEngineEvent["id"]; subregistryId: AccountId; node: Node; registrant: Address; @@ -104,7 +105,7 @@ export async function handleRegistrarEventRegistration( * Handle Registrar Event: Renewal */ export async function handleRegistrarEventRenewal( - context: Context, + context: IndexingEngineContext, { id, subregistryId, @@ -114,7 +115,7 @@ export async function handleRegistrarEventRenewal( block, transactionHash, }: { - id: Event["id"]; + id: IndexingEngineEvent["id"]; subregistryId: AccountId; node: Node; registrant: Address; diff --git a/apps/ensindexer/src/plugins/registrars/shared/lib/registration-lifecycle.ts b/apps/ensindexer/src/plugins/registrars/shared/lib/registration-lifecycle.ts index dcf375921..a67755941 100644 --- a/apps/ensindexer/src/plugins/registrars/shared/lib/registration-lifecycle.ts +++ b/apps/ensindexer/src/plugins/registrars/shared/lib/registration-lifecycle.ts @@ -1,5 +1,4 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { type AccountId, @@ -8,14 +7,16 @@ import { type UnixTimestamp, } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; + /** * Get RegistrationLifecycle by node value. */ export async function getRegistrationLifecycle( - context: Context, + context: IndexingEngineContext, { node }: { node: Node }, -): Promise { - return context.db.find(schema.registrationLifecycles, { node }); +): Promise { + return context.ensDb.find(ensIndexerSchema.registrationLifecycles, { node }); } /** @@ -25,7 +26,7 @@ export async function getRegistrationLifecycle( * the Registration Lifecycle by node value. */ export async function insertRegistrationLifecycle( - context: Context, + context: IndexingEngineContext, { subregistryId, node, @@ -36,7 +37,7 @@ export async function insertRegistrationLifecycle( expiresAt: UnixTimestamp; }, ): Promise { - await context.db.insert(schema.registrationLifecycles).values({ + await context.ensDb.insert(ensIndexerSchema.registrationLifecycles).values({ subregistryId: formatAccountId(subregistryId), node, expiresAt: BigInt(expiresAt), @@ -49,7 +50,7 @@ export async function insertRegistrationLifecycle( * Updates the current state of the Registration Lifecycle by node value. */ export async function updateRegistrationLifecycle( - context: Context, + context: IndexingEngineContext, { node, expiresAt, @@ -58,7 +59,7 @@ export async function updateRegistrationLifecycle( expiresAt: UnixTimestamp; }, ): Promise { - await context.db - .update(schema.registrationLifecycles, { node }) + await context.ensDb + .update(ensIndexerSchema.registrationLifecycles, { node }) .set({ expiresAt: BigInt(expiresAt) }); } diff --git a/apps/ensindexer/src/plugins/registrars/shared/lib/subregistry.ts b/apps/ensindexer/src/plugins/registrars/shared/lib/subregistry.ts index 51427f994..33b96f2a1 100644 --- a/apps/ensindexer/src/plugins/registrars/shared/lib/subregistry.ts +++ b/apps/ensindexer/src/plugins/registrars/shared/lib/subregistry.ts @@ -2,18 +2,19 @@ * This file contains handlers used in event handlers for a subregistry contract. */ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { type AccountId, formatAccountId, type Node } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; + /** * Upsert Subregistry record * * If the record already exists, do nothing. */ export async function upsertSubregistry( - context: Context, + context: IndexingEngineContext, { subregistryId, node, @@ -22,8 +23,8 @@ export async function upsertSubregistry( node: Node; }, ): Promise { - await context.db - .insert(schema.subregistries) + await context.ensDb + .insert(ensIndexerSchema.subregistries) .values({ subregistryId: formatAccountId(subregistryId), node, @@ -35,10 +36,10 @@ export async function upsertSubregistry( * Get Subregistry record by AccountId. */ export async function getSubregistry( - context: Context, + context: IndexingEngineContext, { subregistryId }: { subregistryId: AccountId }, -): Promise { - return context.db.find(schema.subregistries, { +): Promise { + return context.ensDb.find(ensIndexerSchema.subregistries, { subregistryId: formatAccountId(subregistryId), }); } diff --git a/apps/ensindexer/src/plugins/registrars/shared/lib/universal-registrar-renewal-with-referrer-events.ts b/apps/ensindexer/src/plugins/registrars/shared/lib/universal-registrar-renewal-with-referrer-events.ts index fe3e92b85..0d0cfb182 100644 --- a/apps/ensindexer/src/plugins/registrars/shared/lib/universal-registrar-renewal-with-referrer-events.ts +++ b/apps/ensindexer/src/plugins/registrars/shared/lib/universal-registrar-renewal-with-referrer-events.ts @@ -1,5 +1,4 @@ -import type { Context, Event } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import type { Address, Hash } from "viem"; import { @@ -9,6 +8,8 @@ import { type RegistrarActionReferral, } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext, IndexingEngineEvent } from "@/lib/indexing-engines/ponder"; + import { makeLogicalEventKey } from "./registrar-action"; /** @@ -17,14 +18,14 @@ import { makeLogicalEventKey } from "./registrar-action"; * - append new event ID to `eventIds` */ export async function handleUniversalRegistrarRenewalEvent( - context: Context, + context: IndexingEngineContext, { id, node, referral, transactionHash, }: { - id: Event["id"]; + id: IndexingEngineEvent["id"]; node: Node; referral: RegistrarActionReferral; transactionHash: Hash; @@ -40,9 +41,12 @@ export async function handleUniversalRegistrarRenewalEvent( // which needs to be updated. // 2. a) Find registrarActionMetadata record for the current "logical registrar action". - const registrarActionMetadata = await context.db.find(schema.internal_registrarActionMetadata, { - metadataType: "CURRENT_LOGICAL_REGISTRAR_ACTION", - }); + const registrarActionMetadata = await context.ensDb.find( + ensIndexerSchema.internal_registrarActionMetadata, + { + metadataType: "CURRENT_LOGICAL_REGISTRAR_ACTION", + }, + ); // Invariant: the registrarActionMetadata record must exist if (!registrarActionMetadata) { @@ -59,7 +63,7 @@ export async function handleUniversalRegistrarRenewalEvent( } // 2. b) Find "logical registrar action" record by `logicalEventId`. - const logicalRegistrarAction = await context.db.find(schema.registrarActions, { + const logicalRegistrarAction = await context.ensDb.find(ensIndexerSchema.registrarActions, { id: registrarActionMetadata.logicalEventId, }); @@ -85,8 +89,8 @@ export async function handleUniversalRegistrarRenewalEvent( // 4. Update the "logical registrar action" record with // - referral data // - new event ID appended to `eventIds` - await context.db - .update(schema.registrarActions, { id: logicalRegistrarAction.id }) + await context.ensDb + .update(ensIndexerSchema.registrarActions, { id: logicalRegistrarAction.id }) .set(({ eventIds }) => ({ encodedReferrer, decodedReferrer, diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts index a93c76ccf..8c92e6d0a 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts @@ -1,8 +1,8 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { makeSubdomainNode, type Node, PluginName, ROOT_NODE } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { setupRootNode } from "@/lib/subgraph/subgraph-helpers"; @@ -21,8 +21,8 @@ import { // these handlers should ignore 'RegistryOld' events for a given domain if it has been migrated to the // (new) Registry, which is tracked in the `Domain.isMigrated` field -async function shouldIgnoreRegistryOldEvents(context: Context, node: Node) { - const domain = await context.db.find(schema.subgraph_domain, { id: node }); +async function shouldIgnoreRegistryOldEvents(context: IndexingEngineContext, node: Node) { + const domain = await context.ensDb.find(ensIndexerSchema.subgraph_domain, { id: node }); return domain?.isMigrated ?? false; } diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/NameWrapper.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/NameWrapper.ts index 845995078..cdd9a3a39 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/NameWrapper.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/NameWrapper.ts @@ -1,7 +1,6 @@ import config from "@/config"; -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; /** * NOTE: the subgraph has a helper function called `checkPccBurned` which checks if the bit is SET: * https://github.com/ensdomains/ens-subgraph/blob/c844791/src/nameWrapper.ts#L63 @@ -35,6 +34,7 @@ import { import { subgraph_decodeDNSEncodedLiteralName } from "@/lib/dns-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { bigintMax } from "@/lib/lib-helpers"; import { getManagedName } from "@/lib/managed-names"; import type { EventWithArgs } from "@/lib/ponder-helpers"; @@ -98,15 +98,17 @@ function decodeSubgraphInterpretedNameWrapperName( * If the WrappedDomain fuses has PCC set ('the parent cannot control this subdomain'), then * materialize the relevant Domain entity's expiryDate to the greater of the two. */ -async function materializeDomainExpiryDate(context: Context, node: Node) { - const wrappedDomain = await context.db.find(schema.subgraph_wrappedDomain, { id: node }); +async function materializeDomainExpiryDate(context: IndexingEngineContext, node: Node) { + const wrappedDomain = await context.ensDb.find(ensIndexerSchema.subgraph_wrappedDomain, { + id: node, + }); if (!wrappedDomain) throw new Error(`Expected WrappedDomain(${node})`); // if PCC fuse is SET ('burned'), update the expiry // translated: if the parent CANNOT control the subname, update the subname's expiry if (isPccFuseSet(BigInt(wrappedDomain.fuses))) { // update the domain's expiry to the greater of the two - await context.db.update(schema.subgraph_domain, { id: node }).set((domain) => ({ + await context.ensDb.update(ensIndexerSchema.subgraph_domain, { id: node }).set((domain) => ({ expiryDate: bigintMax(domain.expiryDate ?? 0n, wrappedDomain.expiryDate), })); } @@ -117,7 +119,7 @@ async function materializeDomainExpiryDate(context: Context, node: Node) { */ export const makeNameWrapperHandlers = () => { async function handleTransfer( - context: Context, + context: IndexingEngineContext, event: EventWithArgs, eventId: string, tokenId: bigint, @@ -131,15 +133,15 @@ export const makeNameWrapperHandlers = () => { // NOTE: subgraph technically upserts domain with `createOrLoadDomain()` here, but domain // is guaranteed to exist. we encode this stricter logic here to illustrate that fact. // via https://github.com/ensdomains/ens-subgraph/blob/c8447914e8743671fb4b20cffe5a0a97020b3cee/src/nameWrapper.ts#L197C18-L197C36 - const domain = await context.db.find(schema.subgraph_domain, { id: node }); + const domain = await context.ensDb.find(ensIndexerSchema.subgraph_domain, { id: node }); if (!domain) { console.table({ ...event.args, node }); throw new Error(`NameWrapper:handleTransfer called before domain '${node}' exists.`); } // upsert the WrappedDomain - await context.db - .insert(schema.subgraph_wrappedDomain) + await context.ensDb + .insert(ensIndexerSchema.subgraph_wrappedDomain) .values({ id: node, ownerId: to, @@ -153,10 +155,12 @@ export const makeNameWrapperHandlers = () => { .onConflictDoUpdate({ ownerId: to }); // materialize `Domain.wrappedOwner` - await context.db.update(schema.subgraph_domain, { id: node }).set({ wrappedOwnerId: to }); + await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: node }) + .set({ wrappedOwnerId: to }); // log DomainEvent - await context.db.insert(schema.subgraph_wrappedTransfer).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_wrappedTransfer).values({ ...sharedEventValues(context.chain.id, event), id: eventId, // NOTE: override the shared id in this case, to account for TransferBatch domainId: node, @@ -169,7 +173,7 @@ export const makeNameWrapperHandlers = () => { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; owner: Address; @@ -187,7 +191,7 @@ export const makeNameWrapperHandlers = () => { ? decodeSubgraphInterpretedNameWrapperName(event.args.name as DNSEncodedLiteralName) : decodeInterpretedNameWrapperName(event.args.name as DNSEncodedLiteralName); - const domain = await context.db.find(schema.subgraph_domain, { id: node }); + const domain = await context.ensDb.find(ensIndexerSchema.subgraph_domain, { id: node }); if (!domain) throw new Error("domain is guaranteed to already exist"); // upsert the healed name iff !domain.labelName && label @@ -199,26 +203,28 @@ export const makeNameWrapperHandlers = () => { // name will _not_ use the newly healed label emitted by the NameWrapper contract, and will // continue to have an un-healed EncodedLabelHash in its name field // ex: domain id 0x0093b7095a35094ecbd246f5d5638cb094c3061a5f29679f5969ad0abcfae27f - await context.db - .update(schema.subgraph_domain, { id: node }) + await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: node }) .set({ labelName: label, name }); } // update the WrappedDomain that was created in handleTransfer - await context.db.update(schema.subgraph_wrappedDomain, { id: node }).set({ + await context.ensDb.update(ensIndexerSchema.subgraph_wrappedDomain, { id: node }).set({ name, expiryDate: expiry, fuses, }); // materialize wrappedOwner relation - await context.db.update(schema.subgraph_domain, { id: node }).set({ wrappedOwnerId: owner }); + await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: node }) + .set({ wrappedOwnerId: owner }); // materialize domain expiryDate await materializeDomainExpiryDate(context, node); // log DomainEvent - await context.db.insert(schema.subgraph_nameWrapped).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_nameWrapped).values({ ...sharedEventValues(context.chain.id, event), domainId: node, name, @@ -232,7 +238,7 @@ export const makeNameWrapperHandlers = () => { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; owner: Address }>; }) { const { node, owner } = event.args; @@ -241,7 +247,7 @@ export const makeNameWrapperHandlers = () => { await upsertAccount(context, owner); - await context.db.update(schema.subgraph_domain, { id: node }).set((domain) => ({ + await context.ensDb.update(ensIndexerSchema.subgraph_domain, { id: node }).set((domain) => ({ // when a WrappedDomain is Unwrapped, reset any PCC-materialized expiryDate on the Domain entity // i.e if the domain in question normally has an expiry date (is a direct subname of a // Registrar that implements expiries), keep the domain's expiry date, otherwise, set its @@ -253,10 +259,10 @@ export const makeNameWrapperHandlers = () => { })); // delete the WrappedDomain - await context.db.delete(schema.subgraph_wrappedDomain, { id: node }); + await context.ensDb.delete(ensIndexerSchema.subgraph_wrappedDomain, { id: node }); // log DomainEvent - await context.db.insert(schema.subgraph_nameUnwrapped).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_nameUnwrapped).values({ ...sharedEventValues(context.chain.id, event), domainId: node, ownerId: owner, @@ -267,24 +273,28 @@ export const makeNameWrapperHandlers = () => { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; fuses: number }>; }) { const { node, fuses } = event.args; // NOTE: subgraph no-ops this event if there's not a wrappedDomain already in the db. // via https://github.com/ensdomains/ens-subgraph/blob/c844791/src/nameWrapper.ts#L144 - const wrappedDomain = await context.db.find(schema.subgraph_wrappedDomain, { id: node }); + const wrappedDomain = await context.ensDb.find(ensIndexerSchema.subgraph_wrappedDomain, { + id: node, + }); if (wrappedDomain) { // set fuses - await context.db.update(schema.subgraph_wrappedDomain, { id: node }).set({ fuses }); + await context.ensDb + .update(ensIndexerSchema.subgraph_wrappedDomain, { id: node }) + .set({ fuses }); // materialize the domain's expiryDate because the fuses have potentially changed await materializeDomainExpiryDate(context, node); } // log DomainEvent - await context.db.insert(schema.subgraph_fusesSet).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_fusesSet).values({ ...sharedEventValues(context.chain.id, event), domainId: node, fuses, @@ -294,18 +304,20 @@ export const makeNameWrapperHandlers = () => { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; expiry: bigint }>; }) { const { node, expiry } = event.args; // NOTE: subgraph no-ops this event if there's not a wrappedDomain already in the db. // https://github.com/ensdomains/ens-subgraph/blob/c844791/src/nameWrapper.ts#L169 - const wrappedDomain = await context.db.find(schema.subgraph_wrappedDomain, { id: node }); + const wrappedDomain = await context.ensDb.find(ensIndexerSchema.subgraph_wrappedDomain, { + id: node, + }); if (wrappedDomain) { // update expiryDate - await context.db - .update(schema.subgraph_wrappedDomain, { id: node }) + await context.ensDb + .update(ensIndexerSchema.subgraph_wrappedDomain, { id: node }) .set({ expiryDate: expiry }); // materialize the domain's expiryDate @@ -313,7 +325,7 @@ export const makeNameWrapperHandlers = () => { } // log DomainEvent - await context.db.insert(schema.subgraph_expiryExtended).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_expiryExtended).values({ ...sharedEventValues(context.chain.id, event), domainId: node, expiryDate: expiry, @@ -323,7 +335,7 @@ export const makeNameWrapperHandlers = () => { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ id: bigint; to: Address }>; }) { const { id: tokenId, to } = event.args; @@ -345,7 +357,7 @@ export const makeNameWrapperHandlers = () => { context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ ids: readonly bigint[]; to: Address }>; }) { const { ids: tokenIds, to } = event.args; diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registrar.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registrar.ts index 862598405..3a8959954 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registrar.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registrar.ts @@ -1,7 +1,6 @@ import config from "@/config"; -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import type { Address } from "viem"; import { @@ -20,6 +19,7 @@ import { import { getThisAccountId } from "@/lib/get-this-account-id"; import { labelByLabelHash } from "@/lib/graphnode-helpers"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { getManagedName } from "@/lib/managed-names"; import { pluginSupportsPremintedNames } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; @@ -37,7 +37,7 @@ const GRACE_PERIOD_SECONDS = 7776000n; // 90 days in seconds */ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName }) => { async function setNamePreimage( - context: Context, + context: IndexingEngineContext, event: EventWithArgs<{ label: LiteralLabel; labelHash: LabelHash; @@ -61,7 +61,7 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } getThisAccountId(context, event), ); const node = makeSubdomainNode(labelHash, managedNode); - const domain = await context.db.find(schema.subgraph_domain, { id: node }); + const domain = await context.ensDb.find(ensIndexerSchema.subgraph_domain, { id: node }); // encode the runtime assertion here https://github.com/ensdomains/ens-subgraph/blob/c68a889/src/ethRegistrar.ts#L101 if (!domain) throw new Error("domain expected in setNamePreimage but not found"); @@ -73,14 +73,14 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } | InterpretedName | SubgraphInterpretedName; - await context.db - .update(schema.subgraph_domain, { id: node }) + await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: node }) .set({ labelName: interpretedLabel, name: interpretedName }); } // update the registration's labelName - await context.db - .update(schema.subgraph_registration, { id: makeRegistrationId(labelHash, node) }) + await context.ensDb + .update(ensIndexerSchema.subgraph_registration, { id: makeRegistrationId(labelHash, node) }) .set({ labelName: interpretedLabel, cost }); } @@ -89,7 +89,7 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ labelHash: LabelHash; owner: Address; @@ -129,7 +129,7 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } // Therefore, if a Domain does not exist in Registrar#NameRegistered, it _must_ be a 'preminted' // name, tracked only in the Registrar. If/when these 'preminted' names are _actually_ registered // in the future, they will emit NewOwner as expected. - const domain = await context.db.find(schema.subgraph_domain, { id: node }); + const domain = await context.ensDb.find(ensIndexerSchema.subgraph_domain, { id: node }); if (!domain) { // invariant: if the domain does not exist and the plugin does not support preminted names, panic if (!pluginSupportsPremintedNames(pluginName)) { @@ -186,7 +186,7 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } } // update Domain - await context.db.update(schema.subgraph_domain, { id: node }).set({ + await context.ensDb.update(ensIndexerSchema.subgraph_domain, { id: node }).set({ registrantId: owner, expiryDate: expires + GRACE_PERIOD_SECONDS, labelName: label, @@ -207,7 +207,7 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } }); // log RegistrationEvent - await context.db.insert(schema.subgraph_nameRegistered).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_nameRegistered).values({ ...sharedEventValues(context.chain.id, event), registrationId, registrantId: owner, @@ -219,7 +219,7 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ label: Label; labelHash: LabelHash; @@ -236,7 +236,7 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ label: Label; labelHash: LabelHash; @@ -253,7 +253,7 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ labelHash: LabelHash; expires: bigint }>; }) { const { labelHash, expires } = event.args; @@ -263,15 +263,17 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } const id = makeRegistrationId(labelHash, node); // update Registration expiry - await context.db.update(schema.subgraph_registration, { id }).set({ expiryDate: expires }); + await context.ensDb + .update(ensIndexerSchema.subgraph_registration, { id }) + .set({ expiryDate: expires }); // update Domain expiry - await context.db - .update(schema.subgraph_domain, { id: node }) + await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: node }) .set({ expiryDate: expires + GRACE_PERIOD_SECONDS }); // log RegistrationEvent - await context.db.insert(schema.subgraph_nameRenewed).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_nameRenewed).values({ ...sharedEventValues(context.chain.id, event), registrationId: id, expiryDate: expires, @@ -282,7 +284,7 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ labelHash: LabelHash; from: Address; to: Address }>; }) { const { labelHash, to } = event.args; @@ -296,17 +298,21 @@ export const makeRegistrarHandlers = ({ pluginName }: { pluginName: PluginName } // if the Transfer event occurs before the Registration entity exists (i.e. the initial // registration, which is Transfer -> NewOwner -> NameRegistered), no-op - const registration = await context.db.find(schema.subgraph_registration, { id }); + const registration = await context.ensDb.find(ensIndexerSchema.subgraph_registration, { id }); if (!registration) return; // update registration registrant - await context.db.update(schema.subgraph_registration, { id }).set({ registrantId: to }); + await context.ensDb + .update(ensIndexerSchema.subgraph_registration, { id }) + .set({ registrantId: to }); // update domain registrant - await context.db.update(schema.subgraph_domain, { id: node }).set({ registrantId: to }); + await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: node }) + .set({ registrantId: to }); // log RegistrationEvent - await context.db.insert(schema.subgraph_nameTransferred).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_nameTransferred).values({ ...sharedEventValues(context.chain.id, event), registrationId: id, newOwnerId: to, diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registry.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registry.ts index bd9ffec99..1833e06a3 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registry.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registry.ts @@ -1,7 +1,6 @@ import config from "@/config"; -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { type Address, isAddressEqual, zeroAddress } from "viem"; import { getENSRootChainId } from "@ensnode/datasources"; @@ -21,6 +20,7 @@ import { import { labelByLabelHash } from "@/lib/graphnode-helpers"; import { healAddrReverseSubnameLabel } from "@/lib/heal-addr-reverse-subname-label"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { sharedEventValues, upsertAccount, upsertResolver } from "@/lib/subgraph/db-helpers"; import { makeResolverId } from "@/lib/subgraph/ids"; @@ -37,7 +37,7 @@ export const handleNewOwner = context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ // NOTE: `node` event arg represents a `Node` that is the _parent_ of the node the NewOwner event is about node: Node; @@ -53,18 +53,18 @@ export const handleNewOwner = // the domain in question is a subdomain of `parentNode` const node = makeSubdomainNode(labelHash, parentNode); - let domain = await context.db.find(schema.subgraph_domain, { id: node }); + let domain = await context.ensDb.find(ensIndexerSchema.subgraph_domain, { id: node }); // note that we set isMigrated in each branch such that if this domain is being // interacted with on the new registry, its migration status is set here if (domain) { // if the domain already exists, this is just an update of the owner record (& isMigrated) - domain = await context.db - .update(schema.subgraph_domain, { id: node }) + domain = await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: node }) .set({ ownerId: owner, isMigrated }); } else { // otherwise create the domain (w/ isMigrated) - domain = await context.db.insert(schema.subgraph_domain).values({ + domain = await context.ensDb.insert(ensIndexerSchema.subgraph_domain).values({ id: node, ownerId: owner, parentId: parentNode, @@ -74,14 +74,14 @@ export const handleNewOwner = }); // and increment parent subdomainCount - await context.db - .update(schema.subgraph_domain, { id: parentNode }) + await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: parentNode }) .set((row) => ({ subdomainCount: row.subdomainCount + 1 })); } // if the domain doesn't yet have a name, attempt to construct it here if (domain.name === null) { - const parent = await context.db.find(schema.subgraph_domain, { id: parentNode }); + const parent = await context.ensDb.find(ensIndexerSchema.subgraph_domain, { id: parentNode }); let healedLabel: LiteralLabel | null = null; @@ -124,7 +124,7 @@ export const handleNewOwner = parent?.name ? `${subgraphInterpretedLabel}.${parent.name}` : subgraphInterpretedLabel ) as SubgraphInterpretedName; - await context.db.update(schema.subgraph_domain, { id: node }).set({ + await context.ensDb.update(ensIndexerSchema.subgraph_domain, { id: node }).set({ name: subgraphInterpretedName, // NOTE(subgraph-compat): update Domain.labelName iff label is subgraph-indexable // via: https://github.com/ensdomains/ens-subgraph/blob/c68a889/src/ensRegistry.ts#L113 @@ -149,7 +149,7 @@ export const handleNewOwner = parent?.name ? `${interpretedLabel}.${parent.name}` : interpretedLabel ) as InterpretedName; - await context.db.update(schema.subgraph_domain, { id: node }).set({ + await context.ensDb.update(ensIndexerSchema.subgraph_domain, { id: node }).set({ name: interpretedName, labelName: interpretedLabel, }); @@ -163,7 +163,7 @@ export const handleNewOwner = } // log DomainEvent - await context.db.insert(schema.subgraph_newOwner).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_newOwner).values({ ...sharedEventValues(context.chain.id, event), parentDomainId: parentNode, domainId: node, @@ -175,7 +175,7 @@ export async function handleTransfer({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; owner: Address }>; }) { const { node, owner } = event.args; @@ -183,8 +183,8 @@ export async function handleTransfer({ await upsertAccount(context, owner); // ensure domain & update owner - await context.db - .insert(schema.subgraph_domain) + await context.ensDb + .insert(ensIndexerSchema.subgraph_domain) .values([{ id: node, ownerId: owner, createdAt: event.block.timestamp }]) .onConflictDoUpdate({ ownerId: owner }); @@ -194,7 +194,7 @@ export async function handleTransfer({ } // log DomainEvent - await context.db.insert(schema.subgraph_transfer).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_transfer).values({ ...sharedEventValues(context.chain.id, event), domainId: node, ownerId: owner, @@ -205,7 +205,7 @@ export async function handleNewTTL({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; ttl: bigint }>; }) { const { node, ttl } = event.args; @@ -214,10 +214,10 @@ export async function handleNewTTL({ // never deleted, so we avoid implementing that check here // via https://github.com/ensdomains/ens-subgraph/blob/c68a889/src/ensRegistry.ts#L215 - await context.db.update(schema.subgraph_domain, { id: node }).set({ ttl }); + await context.ensDb.update(ensIndexerSchema.subgraph_domain, { id: node }).set({ ttl }); // log DomainEvent - await context.db.insert(schema.subgraph_newTTL).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_newTTL).values({ ...sharedEventValues(context.chain.id, event), domainId: node, ttl, @@ -228,7 +228,7 @@ export async function handleNewResolver({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; resolver: Address }>; }) { const { node, resolver: resolverAddress } = event.args; @@ -242,8 +242,8 @@ export async function handleNewResolver({ if (isZeroResolver) { // NOTE(resolver-relations): unlink subgraph-schema Domain-Resolver relationship iff this is the ENSRoot's chain if (context.chain.id === ensRootChainId) { - await context.db - .update(schema.subgraph_domain, { id: node }) + await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: node }) .set({ resolverId: null, resolvedAddressId: null }); } @@ -261,7 +261,7 @@ export async function handleNewResolver({ if (context.chain.id === ensRootChainId) { // update the domain to point to it, and materialize the eth addr // via https://github.com/ensdomains/ens-subgraph/blob/c68a889/src/ensRegistry.ts#L193 - await context.db.update(schema.subgraph_domain, { id: node }).set({ + await context.ensDb.update(ensIndexerSchema.subgraph_domain, { id: node }).set({ resolverId, resolvedAddressId: resolver.addrId, }); @@ -269,7 +269,7 @@ export async function handleNewResolver({ } // log DomainEvent - await context.db.insert(schema.subgraph_newResolver).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_newResolver).values({ ...sharedEventValues(context.chain.id, event), domainId: node, // NOTE: this actually produces a bug in the subgraph's graphql layer — `resolver` is not nullable diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Resolver.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Resolver.ts index ada490aa7..6a397eea1 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Resolver.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Resolver.ts @@ -1,12 +1,12 @@ import config from "@/config"; -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import type { Address, Hash, Hex } from "viem"; import { hasNullByte, type Node, stripNullBytes, uniq } from "@ensnode/ensnode-sdk"; import { parseDnsTxtRecordArgs } from "@/lib/dns-helpers"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { sharedEventValues, upsertAccount, upsertResolver } from "@/lib/subgraph/db-helpers"; import { makeResolverId } from "@/lib/subgraph/ids"; @@ -25,7 +25,7 @@ export async function handleAddrChanged({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; a: Address }>; }) { const { a: address, node } = event.args; @@ -40,15 +40,15 @@ export async function handleAddrChanged({ }); // materialize the Domain's resolvedAddress field iff exists and is set to this Resolver - const domain = await context.db.find(schema.subgraph_domain, { id: node }); + const domain = await context.ensDb.find(ensIndexerSchema.subgraph_domain, { id: node }); if (domain?.resolverId === id) { - await context.db - .update(schema.subgraph_domain, { id: node }) + await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: node }) .set({ resolvedAddressId: address }); } // log ResolverEvent - await context.db.insert(schema.subgraph_addrChanged).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_addrChanged).values({ ...sharedEventValues(context.chain.id, event), resolverId: id, addrId: address, @@ -59,7 +59,7 @@ export async function handleAddressChanged({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; coinType: bigint; newAddress: Address }>; }) { const { node, coinType, newAddress } = event.args; @@ -72,12 +72,12 @@ export async function handleAddressChanged({ }); // upsert the new coinType - await context.db - .update(schema.subgraph_resolver, { id }) + await context.ensDb + .update(ensIndexerSchema.subgraph_resolver, { id }) .set({ coinTypes: uniq([...(resolver.coinTypes ?? []), coinType]) }); // log ResolverEvent - await context.db.insert(schema.subgraph_multicoinAddrChanged).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_multicoinAddrChanged).values({ ...sharedEventValues(context.chain.id, event), resolverId: id, coinType, @@ -89,7 +89,7 @@ export async function handleNameChanged({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; name: string }>; }) { const { node, name } = event.args; @@ -103,7 +103,7 @@ export async function handleNameChanged({ }); // log ResolverEvent - await context.db.insert(schema.subgraph_nameChanged).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_nameChanged).values({ ...sharedEventValues(context.chain.id, event), resolverId: id, name, @@ -114,7 +114,7 @@ export async function handleABIChanged({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; contentType: bigint }>; }) { const { node, contentType } = event.args; @@ -129,7 +129,7 @@ export async function handleABIChanged({ }); // log ResolverEvent - await context.db.insert(schema.subgraph_abiChanged).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_abiChanged).values({ ...sharedEventValues(context.chain.id, event), resolverId: id, contentType, @@ -140,7 +140,7 @@ export async function handlePubkeyChanged({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; x: Hex; y: Hex }>; }) { const { node, x, y } = event.args; @@ -154,7 +154,7 @@ export async function handlePubkeyChanged({ }); // log ResolverEvent - await context.db.insert(schema.subgraph_pubkeyChanged).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_pubkeyChanged).values({ ...sharedEventValues(context.chain.id, event), resolverId: id, x, @@ -166,7 +166,7 @@ export async function handleTextChanged({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; indexedKey: string; @@ -197,12 +197,12 @@ export async function handleTextChanged({ // upsert new key // NOTE(subgraph-compat): we insert sanitized key even if it's empty string to match subgraph behavior // of implicitly stripping null bytes - await context.db - .update(schema.subgraph_resolver, { id }) + await context.ensDb + .update(ensIndexerSchema.subgraph_resolver, { id }) .set({ texts: uniq([...(resolver.texts ?? []), sanitizedKey]) }); // log ResolverEvent - await context.db.insert(schema.subgraph_textChanged).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_textChanged).values({ ...sharedEventValues(context.chain.id, event), resolverId: id, key: sanitizedKey, @@ -214,7 +214,7 @@ export async function handleContenthashChanged({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; hash: Hash }>; }) { const { node, hash } = event.args; @@ -227,7 +227,7 @@ export async function handleContenthashChanged({ }); // log ResolverEvent - await context.db.insert(schema.subgraph_contenthashChanged).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_contenthashChanged).values({ ...sharedEventValues(context.chain.id, event), resolverId: id, hash, @@ -238,7 +238,7 @@ export async function handleInterfaceChanged({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; interfaceID: Hex; implementer: Hex }>; }) { const { node, interfaceID, implementer } = event.args; @@ -250,7 +250,7 @@ export async function handleInterfaceChanged({ }); // log ResolverEvent - await context.db.insert(schema.subgraph_interfaceChanged).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_interfaceChanged).values({ ...sharedEventValues(context.chain.id, event), resolverId: id, interfaceID, @@ -262,7 +262,7 @@ export async function handleAuthorisationChanged({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; owner: Address; @@ -280,7 +280,7 @@ export async function handleAuthorisationChanged({ }); // log ResolverEvent - await context.db.insert(schema.subgraph_authorisationChanged).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_authorisationChanged).values({ ...sharedEventValues(context.chain.id, event), resolverId: id, owner, @@ -294,16 +294,18 @@ export async function handleVersionChanged({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; newVersion: bigint }>; }) { const { node, newVersion } = event.args; const id = makeResolverId(context.chain.id, event.log.address, node); // materialize the Domain's resolvedAddress field iff exists and is set to this Resolver - const domain = await context.db.find(schema.subgraph_domain, { id: node }); + const domain = await context.ensDb.find(ensIndexerSchema.subgraph_domain, { id: node }); if (domain?.resolverId === id) { - await context.db.update(schema.subgraph_domain, { id: node }).set({ resolvedAddressId: null }); + await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: node }) + .set({ resolvedAddressId: null }); } await upsertResolver(context, { @@ -319,7 +321,7 @@ export async function handleVersionChanged({ }); // log ResolverEvent - await context.db.insert(schema.subgraph_versionChanged).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_versionChanged).values({ ...sharedEventValues(context.chain.id, event), resolverId: id, version: newVersion, @@ -333,7 +335,7 @@ export async function handleDNSRecordChanged({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; name: Hex; @@ -365,12 +367,12 @@ export async function handleDNSRecordChanged({ }); // upsert new key - await context.db - .update(schema.subgraph_resolver, { id }) + await context.ensDb + .update(ensIndexerSchema.subgraph_resolver, { id }) .set({ texts: uniq([...(resolver.texts ?? []), key]) }); // log ResolverEvent - await context.db.insert(schema.subgraph_textChanged).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_textChanged).values({ ...sharedEventValues(context.chain.id, event), resolverId: id, key, @@ -382,7 +384,7 @@ export async function handleDNSRecordDeleted({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; name: Hex; @@ -407,12 +409,12 @@ export async function handleDNSRecordDeleted({ }); // remove relevant key - await context.db - .update(schema.subgraph_resolver, { id }) + await context.ensDb + .update(ensIndexerSchema.subgraph_resolver, { id }) .set({ texts: (resolver.texts ?? []).filter((text) => text !== key) }); // log ResolverEvent - await context.db.insert(schema.subgraph_textChanged).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_textChanged).values({ ...sharedEventValues(context.chain.id, event), resolverId: id, key, @@ -426,7 +428,7 @@ export async function handleDNSZonehashChanged({ // biome-ignore lint/correctness/noUnusedFunctionParameters: explicitly ignored event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; zonehash: Hash }>; }) { // explicitly ignored / not implemented @@ -438,7 +440,7 @@ export async function handleZoneCreated({ // biome-ignore lint/correctness/noUnusedFunctionParameters: explicitly ignored event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; version: bigint }>; }) { // explicitly ignored / not implemented diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/ThreeDNSToken.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/ThreeDNSToken.ts index 8221a9101..004e047d6 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/ThreeDNSToken.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/ThreeDNSToken.ts @@ -1,5 +1,4 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { type Address, isAddressEqual, zeroAddress, zeroHash } from "viem"; import { @@ -19,6 +18,7 @@ import { } from "@ensnode/ensnode-sdk"; import { labelByLabelHash } from "@/lib/graphnode-helpers"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { parseLabelAndNameFromOnChainMetadata } from "@/lib/json-metadata"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { @@ -35,7 +35,10 @@ import { getThreeDNSTokenId } from "@/lib/threedns-helpers"; /** * Gets the `uri` for a given tokenId using the relevant ThreeDNSToken from `context` */ -const getUriForTokenId = async (context: Context, tokenId: bigint): Promise => { +const getUriForTokenId = async ( + context: IndexingEngineContext, + tokenId: bigint, +): Promise => { // ThreeDNSToken is chain-specific in ponder multi-chain usage // https://ponder.sh/docs/indexing/read-contracts#multiple-chains return context.client.readContract({ @@ -100,7 +103,7 @@ export async function handleNewOwner({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ // NOTE: `node` event arg represents a `Node` that is the _parent_ of the node the NewOwner event is about node: Node; @@ -115,7 +118,7 @@ export async function handleNewOwner({ // the domain in question is a subdomain of `parentNode` const node = makeSubdomainNode(labelHash, parentNode); - let domain = await context.db.find(schema.subgraph_domain, { id: node }); + let domain = await context.ensDb.find(ensIndexerSchema.subgraph_domain, { id: node }); // biome-ignore lint/style/noNonNullAssertion: NetworkConfig#address is `Address | Address[] | undefined`, but we know this is a single address const resolverAddress = context.contracts["threedns/Resolver"].address! as Address; @@ -131,10 +134,12 @@ export async function handleNewOwner({ if (domain) { // if the domain already exists, this is just an update of the owner record - domain = await context.db.update(schema.subgraph_domain, { id: node }).set({ ownerId: owner }); + domain = await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: node }) + .set({ ownerId: owner }); } else { // otherwise create the domain - domain = await context.db.insert(schema.subgraph_domain).values({ + domain = await context.ensDb.insert(ensIndexerSchema.subgraph_domain).values({ id: node, ownerId: owner, parentId: parentNode, @@ -147,8 +152,8 @@ export async function handleNewOwner({ }); // and increment parent subdomainCount - await context.db - .update(schema.subgraph_domain, { id: parentNode }) + await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: parentNode }) .set((row) => ({ subdomainCount: row.subdomainCount + 1 })); } @@ -157,7 +162,7 @@ export async function handleNewOwner({ // always emit `RegistrationCreated`, including Domain's `name`, before this `NewOwner` event // is indexed. if (domain.name === null) { - const parent = await context.db.find(schema.subgraph_domain, { id: parentNode }); + const parent = await context.ensDb.find(ensIndexerSchema.subgraph_domain, { id: parentNode }); // 1. attempt metadata retrieval const tokenId = getThreeDNSTokenId(node); @@ -184,13 +189,13 @@ export async function handleNewOwner({ parent?.name ? `${interpretedLabel}.${parent.name}` : interpretedLabel ) as InterpretedName; - await context.db - .update(schema.subgraph_domain, { id: node }) + await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: node }) .set({ name: interpretedName, labelName: interpretedLabel }); } // log DomainEvent - await context.db.insert(schema.subgraph_newOwner).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_newOwner).values({ ...sharedEventValues(context.chain.id, event), parentDomainId: parentNode, domainId: node, @@ -202,7 +207,7 @@ export async function handleTransfer({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; owner: Address }>; }) { const { node, owner } = event.args; @@ -210,7 +215,9 @@ export async function handleTransfer({ await upsertAccount(context, owner); // update owner (Domain is guaranteed to exist because NewOwner fires before Transfer) - await context.db.update(schema.subgraph_domain, { id: node }).set({ ownerId: owner }); + await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: node }) + .set({ ownerId: owner }); // garbage collect newly 'empty' domain iff necessary if (isAddressEqual(owner, zeroAddress)) { @@ -218,7 +225,7 @@ export async function handleTransfer({ } // log DomainEvent - await context.db.insert(schema.subgraph_transfer).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_transfer).values({ ...sharedEventValues(context.chain.id, event), domainId: node, ownerId: owner, @@ -229,7 +236,7 @@ export async function handleRegistrationCreated({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ // NOTE: `node` event arg represents a `Node` that is the domain this registration is about node: Node; @@ -284,7 +291,7 @@ export async function handleRegistrationCreated({ }); // log RegistrationEvent - await context.db.insert(schema.subgraph_nameRegistered).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_nameRegistered).values({ ...sharedEventValues(context.chain.id, event), registrationId, registrantId: registrant, @@ -296,22 +303,24 @@ export async function handleRegistrationExtended({ context, event, }: { - context: Context; + context: IndexingEngineContext; event: EventWithArgs<{ node: Node; duration: bigint; newExpiry: bigint }>; }) { const { node, newExpiry } = event.args; // update domain expiry date - await context.db.update(schema.subgraph_domain, { id: node }).set({ expiryDate: newExpiry }); + await context.ensDb + .update(ensIndexerSchema.subgraph_domain, { id: node }) + .set({ expiryDate: newExpiry }); // udpate registration expiry date const registrationId = makeRegistrationId(zeroHash, node); - await context.db - .update(schema.subgraph_registration, { id: registrationId }) + await context.ensDb + .update(ensIndexerSchema.subgraph_registration, { id: registrationId }) .set({ expiryDate: newExpiry }); // log RegistratioEvent - await context.db.insert(schema.subgraph_nameRenewed).values({ + await context.ensDb.insert(ensIndexerSchema.subgraph_nameRenewed).values({ ...sharedEventValues(context.chain.id, event), registrationId, expiryDate: newExpiry, diff --git a/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts b/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts index 80af30d1e..b48b3005c 100644 --- a/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts +++ b/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts @@ -1,6 +1,6 @@ import config from "@/config"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { formatAssetId, PluginName } from "@ensnode/ensnode-sdk"; @@ -44,7 +44,7 @@ export default function () { const assetIdString = formatAssetId(sale.nft); // insert NameSale entity - await context.db.insert(schema.nameSales).values({ + await context.ensDb.insert(ensIndexerSchema.nameSales).values({ id: makeEventId(context.chain.id, event.block.number, event.log.logIndex), chainId: sale.nft.contract.chainId, blockNumber: event.block.number, diff --git a/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts b/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts index 102d6fb4c..45b7898c5 100644 --- a/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts +++ b/apps/ensindexer/src/plugins/tokenscope/handlers/ThreeDNSToken.ts @@ -150,7 +150,7 @@ export default function () { // // to look it up in the database. this query is then repeated in handleTransfer which // // is a bit of a bummer but better to keep our logic simple. // const serializedAssetId = serializeAssetId(nft); - // const indexedNft = await context.db.find(schema.nameTokens, { id: serializedAssetId }); + // const indexedNft = await context.ensDb.find(ensIndexerSchema.nameTokens, { id: serializedAssetId }); // const metadata: NFTTransferEventMetadata = { // chainId: context.chain.id, @@ -185,7 +185,7 @@ export default function () { // // to look it up in the database. this query is then repeated in handleTransfer which // // is a bit of a bummer but better to keep our logic simple. // const serializedAssetId = serializeAssetId(nft); - // const indexedNft = await context.db.find(schema.nameTokens, { id: serializedAssetId }); + // const indexedNft = await context.ensDb.find(ensIndexerSchema.nameTokens, { id: serializedAssetId }); // const metadata: NFTTransferEventMetadata = { // chainId: context.chain.id, diff --git a/apps/ensindexer/src/plugins/tokenscope/lib/handle-nft-transfer.ts b/apps/ensindexer/src/plugins/tokenscope/lib/handle-nft-transfer.ts index 523118a5e..4ebcdee26 100644 --- a/apps/ensindexer/src/plugins/tokenscope/lib/handle-nft-transfer.ts +++ b/apps/ensindexer/src/plugins/tokenscope/lib/handle-nft-transfer.ts @@ -1,5 +1,4 @@ -import type { Context } from "ponder:registry"; -import schema from "ponder:schema"; +import ensIndexerSchema from "ponder:schema"; import { type Address, zeroAddress } from "viem"; import { @@ -12,10 +11,11 @@ import { NFTTransferTypes, } from "@ensnode/ensnode-sdk"; +import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { upsertAccount } from "@/lib/subgraph/db-helpers"; export const handleERC1155Transfer = async ( - context: Context, + context: IndexingEngineContext, from: Address, to: Address, allowMintedRemint: boolean, @@ -35,7 +35,7 @@ export const handleERC1155Transfer = async ( }; export const handleNFTTransfer = async ( - context: Context, + context: IndexingEngineContext, from: Address, to: Address, allowMintedRemint: boolean, @@ -45,7 +45,7 @@ export const handleNFTTransfer = async ( const assetIdString = formatAssetId(nft); // get the previously indexed record for the assetId (if it exists) - const previous = await context.db.find(schema.nameTokens, { id: assetIdString }); + const previous = await context.ensDb.find(ensIndexerSchema.nameTokens, { id: assetIdString }); const transferType = getNFTTransferType(from, to, allowMintedRemint, metadata, previous?.owner); switch (transferType) { @@ -53,7 +53,7 @@ export const handleNFTTransfer = async ( // mint status transition from unindexed -> minted // insert the record of the nft that has been minted for the first time await upsertAccount(context, to); - await context.db.insert(schema.nameTokens).values({ + await context.ensDb.insert(ensIndexerSchema.nameTokens).values({ id: assetIdString, chainId: nft.contract.chainId, contractAddress: nft.contract.address, @@ -72,7 +72,7 @@ export const handleNFTTransfer = async ( // it's state as burned // TODO: should we remove this upsertAccount call with the zeroAddress? await upsertAccount(context, zeroAddress); - await context.db.insert(schema.nameTokens).values({ + await context.ensDb.insert(ensIndexerSchema.nameTokens).values({ id: assetIdString, chainId: nft.contract.chainId, contractAddress: nft.contract.address, @@ -88,7 +88,7 @@ export const handleNFTTransfer = async ( // mint status transition from burned -> minted // update the mint status and owner of the previously indexed nft await upsertAccount(context, to); - await context.db.update(schema.nameTokens, { id: assetIdString }).set({ + await context.ensDb.update(ensIndexerSchema.nameTokens, { id: assetIdString }).set({ owner: to, mintStatus: NFTMintStatuses.Minted, }); @@ -101,7 +101,7 @@ export const handleNFTTransfer = async ( // update the mint status and owner of the previously indexed nft // TODO: should we remove this upsertAccount call with the zeroAddress? await upsertAccount(context, zeroAddress); - await context.db.update(schema.nameTokens, { id: assetIdString }).set({ + await context.ensDb.update(ensIndexerSchema.nameTokens, { id: assetIdString }).set({ owner: zeroAddress, mintStatus: NFTMintStatuses.Burned, }); @@ -113,7 +113,7 @@ export const handleNFTTransfer = async ( // mint status remains minted (no change) // update owner of the previously indexed nft await upsertAccount(context, to); - await context.db.update(schema.nameTokens, { id: assetIdString }).set({ + await context.ensDb.update(ensIndexerSchema.nameTokens, { id: assetIdString }).set({ owner: to, }); break; From 9993dae8b47688024d3100367221de6f47db99ae Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Sat, 28 Mar 2026 17:02:07 +0100 Subject: [PATCH 08/11] Apply AI feedback --- .../src/lib/indexing-engines/ponder.test.ts | 16 ++++------------ .../src/lib/indexing-engines/ponder.ts | 2 +- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/apps/ensindexer/src/lib/indexing-engines/ponder.test.ts b/apps/ensindexer/src/lib/indexing-engines/ponder.test.ts index 0e85fb28d..8751f7cc5 100644 --- a/apps/ensindexer/src/lib/indexing-engines/ponder.test.ts +++ b/apps/ensindexer/src/lib/indexing-engines/ponder.test.ts @@ -1,5 +1,5 @@ import type { Context, EventNames } from "ponder:registry"; -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeEach, describe, expect, expectTypeOf, it, vi } from "vitest"; import { addOnchainEventListener, @@ -7,7 +7,7 @@ import { type IndexingEngineEvent, } from "./ponder"; -const mockPonderOn = vi.fn(); +const { mockPonderOn } = vi.hoisted(() => ({ mockPonderOn: vi.fn() })); vi.mock("ponder:registry", () => ({ ponder: { @@ -189,15 +189,7 @@ describe("addOnchainEventListener", () => { }); describe("IndexingEngineContext type", () => { - it("should have ensDb property extending from Ponder context", () => { - const mockContext: IndexingEngineContext = { - db: vi.fn(), - ensDb: vi.fn(), - chain: { id: 1 }, - block: { number: 100n }, - client: vi.fn(), - } as unknown as IndexingEngineContext; - - expect(mockContext.ensDb).toBeDefined(); + it("exposes ensDb matching the Ponder db type", () => { + expectTypeOf().toEqualTypeOf["db"]>(); }); }); diff --git a/apps/ensindexer/src/lib/indexing-engines/ponder.ts b/apps/ensindexer/src/lib/indexing-engines/ponder.ts index c7fe2f2d7..8cf687b85 100644 --- a/apps/ensindexer/src/lib/indexing-engines/ponder.ts +++ b/apps/ensindexer/src/lib/indexing-engines/ponder.ts @@ -48,7 +48,7 @@ function buildIndexingEngineContext( /** * A thin wrapper around `ponder.on` that allows us to: * - Provide custom context to event handlers. - * - Execute additional logic before or after the event handler, if needed. + * - Execute additional logic before or after the event handler, if needed. * * Note that this function is called on every event, so it should be * efficient and avoid doing any heavy computations or database queries. From dbea54c4c0d1c4da8010e424578d2e2edc9a27a1 Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Sun, 29 Mar 2026 08:54:47 +0200 Subject: [PATCH 09/11] Code formatting update --- apps/ensindexer/src/lib/indexing-engines/ponder.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/ensindexer/src/lib/indexing-engines/ponder.ts b/apps/ensindexer/src/lib/indexing-engines/ponder.ts index 8cf687b85..184e0f7ef 100644 --- a/apps/ensindexer/src/lib/indexing-engines/ponder.ts +++ b/apps/ensindexer/src/lib/indexing-engines/ponder.ts @@ -49,13 +49,12 @@ function buildIndexingEngineContext( * A thin wrapper around `ponder.on` that allows us to: * - Provide custom context to event handlers. * - Execute additional logic before or after the event handler, if needed. - * + * * Note that this function is called on every event, so it should be * efficient and avoid doing any heavy computations or database queries. - * + * * For more details on `ponder.on`, see the Ponder indexing guide. * @see https://ponder.sh/docs/indexing/overview#register-an-indexing-function - */ export function addOnchainEventListener( eventName: EventName, From 1a46168d7aa05b5094cc0150a2bd6c516c0464f4 Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Mon, 30 Mar 2026 07:21:16 +0200 Subject: [PATCH 10/11] Replace `"ponder:schema"` import with `@/lib/indexing-engines/ponder` Separates Ponder modules from being directly tied to event handlers. --- apps/ensindexer/src/lib/ensv2/account-db-helpers.ts | 3 +-- apps/ensindexer/src/lib/ensv2/domain-db-helpers.ts | 3 +-- apps/ensindexer/src/lib/ensv2/event-db-helpers.ts | 3 +-- apps/ensindexer/src/lib/ensv2/label-db-helpers.ts | 3 +-- apps/ensindexer/src/lib/ensv2/registration-db-helpers.ts | 4 +--- apps/ensindexer/src/lib/indexing-engines/ponder.test.ts | 4 ++++ apps/ensindexer/src/lib/indexing-engines/ponder.ts | 2 ++ .../domain-resolver-relationship-db-helpers.ts | 3 +-- .../protocol-acceleration/registry-migration-status.ts | 4 +--- .../src/lib/protocol-acceleration/resolver-db-helpers.ts | 3 +-- apps/ensindexer/src/lib/subgraph/db-helpers.ts | 3 +-- apps/ensindexer/src/lib/subgraph/subgraph-helpers.ts | 3 +-- .../src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts | 8 +++++--- .../src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts | 8 +++++--- .../src/plugins/ensv2/handlers/ensv1/NameWrapper.ts | 8 +++++--- .../plugins/ensv2/handlers/ensv1/RegistrarController.ts | 9 +++++---- .../src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts | 8 +++++--- .../src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts | 8 +++++--- .../ensv2/handlers/ensv2/EnhancedAccessControl.ts | 8 +++++--- .../src/plugins/ensv2/handlers/shared/Resolver.ts | 3 +-- .../protocol-acceleration/handlers/ENSv1Registry.ts | 3 +-- .../protocol-acceleration/handlers/ENSv2Registry.ts | 3 +-- .../handlers/StandaloneReverseRegistrar.ts | 4 +--- .../protocol-acceleration/handlers/ThreeDNSToken.ts | 3 +-- .../plugins/registrars/shared/lib/registrar-action.ts | 3 +-- .../registrars/shared/lib/registrar-controller-events.ts | 7 +++++-- .../registrars/shared/lib/registration-lifecycle.ts | 4 +--- .../src/plugins/registrars/shared/lib/subregistry.ts | 4 +--- .../universal-registrar-renewal-with-referrer-events.ts | 7 +++++-- .../subgraph/plugins/subgraph/handlers/Registry.ts | 9 +++++---- .../src/plugins/subgraph/shared-handlers/NameWrapper.ts | 3 +-- .../src/plugins/subgraph/shared-handlers/Registrar.ts | 3 +-- .../src/plugins/subgraph/shared-handlers/Registry.ts | 3 +-- .../src/plugins/subgraph/shared-handlers/Resolver.ts | 3 +-- .../plugins/subgraph/shared-handlers/ThreeDNSToken.ts | 3 +-- .../src/plugins/tokenscope/handlers/Seaport.ts | 4 +--- .../src/plugins/tokenscope/lib/handle-nft-transfer.ts | 3 +-- 37 files changed, 81 insertions(+), 86 deletions(-) diff --git a/apps/ensindexer/src/lib/ensv2/account-db-helpers.ts b/apps/ensindexer/src/lib/ensv2/account-db-helpers.ts index c0efe78ea..fe7def041 100644 --- a/apps/ensindexer/src/lib/ensv2/account-db-helpers.ts +++ b/apps/ensindexer/src/lib/ensv2/account-db-helpers.ts @@ -1,9 +1,8 @@ -import ensIndexerSchema from "ponder:schema"; import type { Address } from "viem"; import { interpretAddress } from "@ensnode/ensnode-sdk"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; /** * Ensures that the account identified by `address` exists. diff --git a/apps/ensindexer/src/lib/ensv2/domain-db-helpers.ts b/apps/ensindexer/src/lib/ensv2/domain-db-helpers.ts index 9c761f2c3..1b018a656 100644 --- a/apps/ensindexer/src/lib/ensv2/domain-db-helpers.ts +++ b/apps/ensindexer/src/lib/ensv2/domain-db-helpers.ts @@ -1,10 +1,9 @@ -import ensIndexerSchema from "ponder:schema"; import type { Address } from "viem"; import { type ENSv1DomainId, interpretAddress } from "@ensnode/ensnode-sdk"; import { ensureAccount } from "@/lib/ensv2/account-db-helpers"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; /** * Sets an ENSv1 Domain's effective owner to `owner`. diff --git a/apps/ensindexer/src/lib/ensv2/event-db-helpers.ts b/apps/ensindexer/src/lib/ensv2/event-db-helpers.ts index eca7a94e9..03c37b39b 100644 --- a/apps/ensindexer/src/lib/ensv2/event-db-helpers.ts +++ b/apps/ensindexer/src/lib/ensv2/event-db-helpers.ts @@ -1,4 +1,3 @@ -import ensIndexerSchema from "ponder:schema"; import type { Hash } from "viem"; import { @@ -8,7 +7,7 @@ import { makeResolverId, } from "@ensnode/ensnode-sdk"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import type { LogEventBase } from "@/lib/ponder-helpers"; type Topics = [Hash, ...Hash[]]; diff --git a/apps/ensindexer/src/lib/ensv2/label-db-helpers.ts b/apps/ensindexer/src/lib/ensv2/label-db-helpers.ts index 602ffe04e..a6b7edd9f 100644 --- a/apps/ensindexer/src/lib/ensv2/label-db-helpers.ts +++ b/apps/ensindexer/src/lib/ensv2/label-db-helpers.ts @@ -1,4 +1,3 @@ -import ensIndexerSchema from "ponder:schema"; import { labelhash } from "viem"; import { @@ -10,7 +9,7 @@ import { } from "@ensnode/ensnode-sdk"; import { labelByLabelHash } from "@/lib/graphnode-helpers"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; /** * Ensures that the LiteralLabel `label` is interpreted and upserted into the Label rainbow table. diff --git a/apps/ensindexer/src/lib/ensv2/registration-db-helpers.ts b/apps/ensindexer/src/lib/ensv2/registration-db-helpers.ts index da9e7c79e..2be2f74da 100644 --- a/apps/ensindexer/src/lib/ensv2/registration-db-helpers.ts +++ b/apps/ensindexer/src/lib/ensv2/registration-db-helpers.ts @@ -1,8 +1,6 @@ -import ensIndexerSchema from "ponder:schema"; - import { type DomainId, makeRegistrationId, makeRenewalId } from "@ensnode/ensnode-sdk"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; /** * Latest Registration & Renewals diff --git a/apps/ensindexer/src/lib/indexing-engines/ponder.test.ts b/apps/ensindexer/src/lib/indexing-engines/ponder.test.ts index 8751f7cc5..4bb7f5a79 100644 --- a/apps/ensindexer/src/lib/indexing-engines/ponder.test.ts +++ b/apps/ensindexer/src/lib/indexing-engines/ponder.test.ts @@ -15,6 +15,10 @@ vi.mock("ponder:registry", () => ({ }, })); +vi.mock("ponder:schema", () => ({ + ensIndexerSchema: {}, +})); + describe("addOnchainEventListener", () => { beforeEach(() => { vi.clearAllMocks(); diff --git a/apps/ensindexer/src/lib/indexing-engines/ponder.ts b/apps/ensindexer/src/lib/indexing-engines/ponder.ts index 184e0f7ef..b5131f358 100644 --- a/apps/ensindexer/src/lib/indexing-engines/ponder.ts +++ b/apps/ensindexer/src/lib/indexing-engines/ponder.ts @@ -1,3 +1,5 @@ +export * as ensIndexerSchema from "ponder:schema"; + import { type EventNames, type Context as PonderIndexingContext, diff --git a/apps/ensindexer/src/lib/protocol-acceleration/domain-resolver-relationship-db-helpers.ts b/apps/ensindexer/src/lib/protocol-acceleration/domain-resolver-relationship-db-helpers.ts index 79583444a..163dcf3e1 100644 --- a/apps/ensindexer/src/lib/protocol-acceleration/domain-resolver-relationship-db-helpers.ts +++ b/apps/ensindexer/src/lib/protocol-acceleration/domain-resolver-relationship-db-helpers.ts @@ -1,9 +1,8 @@ -import ensIndexerSchema from "ponder:schema"; import { type Address, isAddressEqual, zeroAddress } from "viem"; import type { AccountId, DomainId } from "@ensnode/ensnode-sdk"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; /** * Ensures that the Domain-Resolver Relationship for the provided `domainId` in `registry` is set diff --git a/apps/ensindexer/src/lib/protocol-acceleration/registry-migration-status.ts b/apps/ensindexer/src/lib/protocol-acceleration/registry-migration-status.ts index 1a3a5f29e..c0713f45d 100644 --- a/apps/ensindexer/src/lib/protocol-acceleration/registry-migration-status.ts +++ b/apps/ensindexer/src/lib/protocol-acceleration/registry-migration-status.ts @@ -1,11 +1,9 @@ import config from "@/config"; -import ensIndexerSchema from "ponder:schema"; - import { getENSRootChainId } from "@ensnode/datasources"; import type { Node } from "@ensnode/ensnode-sdk"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; const ensRootChainId = getENSRootChainId(config.namespace); diff --git a/apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts b/apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts index 7862c2aa5..dbfc07bfc 100644 --- a/apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts +++ b/apps/ensindexer/src/lib/protocol-acceleration/resolver-db-helpers.ts @@ -1,4 +1,3 @@ -import ensIndexerSchema from "ponder:schema"; import type { Address } from "viem"; import { @@ -15,7 +14,7 @@ import { interpretTextRecordValue, } from "@ensnode/ensnode-sdk/internal"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import type { EventWithArgs } from "@/lib/ponder-helpers"; /** diff --git a/apps/ensindexer/src/lib/subgraph/db-helpers.ts b/apps/ensindexer/src/lib/subgraph/db-helpers.ts index 8645c5479..badd42f5f 100644 --- a/apps/ensindexer/src/lib/subgraph/db-helpers.ts +++ b/apps/ensindexer/src/lib/subgraph/db-helpers.ts @@ -1,7 +1,6 @@ -import ensIndexerSchema from "ponder:schema"; import type { Address } from "viem"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import type { LogEventBase } from "@/lib/ponder-helpers"; import { makeEventId } from "@/lib/subgraph/ids"; diff --git a/apps/ensindexer/src/lib/subgraph/subgraph-helpers.ts b/apps/ensindexer/src/lib/subgraph/subgraph-helpers.ts index 883179189..7654b8e91 100644 --- a/apps/ensindexer/src/lib/subgraph/subgraph-helpers.ts +++ b/apps/ensindexer/src/lib/subgraph/subgraph-helpers.ts @@ -1,11 +1,10 @@ import config from "@/config"; -import ensIndexerSchema from "ponder:schema"; import { isAddressEqual, zeroAddress } from "viem"; import { type Node, ROOT_NODE } from "@ensnode/ensnode-sdk"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { upsertAccount } from "@/lib/subgraph/db-helpers"; /** diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts index a23377cf3..68c1f6af4 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/BaseRegistrar.ts @@ -1,4 +1,3 @@ -import ensIndexerSchema from "ponder:schema"; import { GRACE_PERIOD_SECONDS } from "@ensdomains/ensjs/utils"; import { type Address, isAddressEqual, zeroAddress } from "viem"; @@ -20,8 +19,11 @@ import { insertLatestRenewal, } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; -import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; +import { + addOnchainEventListener, + ensIndexerSchema, + type IndexingEngineContext, +} from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { getManagedName } from "@/lib/managed-names"; import { namespaceContract } from "@/lib/plugin-helpers"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts index 55650f661..50c204b95 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/ENSv1Registry.ts @@ -1,6 +1,5 @@ import config from "@/config"; -import ensIndexerSchema from "ponder:schema"; import { type Address, isAddressEqual, zeroAddress } from "viem"; import { @@ -19,8 +18,11 @@ import { materializeENSv1DomainEffectiveOwner } from "@/lib/ensv2/domain-db-help import { ensureDomainEvent } from "@/lib/ensv2/event-db-helpers"; import { ensureLabel, ensureUnknownLabel } from "@/lib/ensv2/label-db-helpers"; import { healAddrReverseSubnameLabel } from "@/lib/heal-addr-reverse-subname-label"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; -import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; +import { + addOnchainEventListener, + ensIndexerSchema, + type IndexingEngineContext, +} from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { nodeIsMigrated } from "@/lib/protocol-acceleration/registry-migration-status"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts index 9befad436..e2165ebd7 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/NameWrapper.ts @@ -1,4 +1,3 @@ -import ensIndexerSchema from "ponder:schema"; import { type Address, isAddressEqual, zeroAddress } from "viem"; import { @@ -29,8 +28,11 @@ import { insertLatestRenewal, } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; -import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; +import { + addOnchainEventListener, + ensIndexerSchema, + type IndexingEngineContext, +} from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { getManagedName } from "@/lib/managed-names"; import { namespaceContract } from "@/lib/plugin-helpers"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts index c9587bb21..cf48cc7ac 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv1/RegistrarController.ts @@ -1,7 +1,5 @@ /** biome-ignore-all lint/correctness/noUnusedVariables: ignore for now */ -import ensIndexerSchema from "ponder:schema"; - import { type EncodedReferrer, type Label, @@ -17,8 +15,11 @@ import { ensureDomainEvent } from "@/lib/ensv2/event-db-helpers"; import { ensureLabel, ensureUnknownLabel } from "@/lib/ensv2/label-db-helpers"; import { getLatestRegistration, getLatestRenewal } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; -import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; +import { + addOnchainEventListener, + ensIndexerSchema, + type IndexingEngineContext, +} from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { getManagedName } from "@/lib/managed-names"; import { namespaceContract } from "@/lib/plugin-helpers"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts index ff70480f4..c54058aba 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts @@ -1,4 +1,3 @@ -import ensIndexerSchema from "ponder:schema"; import { type Address, hexToBigInt, labelhash } from "viem"; import { @@ -21,8 +20,11 @@ import { insertLatestRegistration, } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; -import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; +import { + addOnchainEventListener, + ensIndexerSchema, + type IndexingEngineContext, +} from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts index 9c3b52e10..e72267bfd 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts @@ -1,4 +1,3 @@ -import ensIndexerSchema from "ponder:schema"; import type { Address } from "viem"; import { @@ -16,8 +15,11 @@ import { ensureAccount } from "@/lib/ensv2/account-db-helpers"; import { ensureDomainEvent, ensureEvent } from "@/lib/ensv2/event-db-helpers"; import { getLatestRegistration, insertLatestRenewal } from "@/lib/ensv2/registration-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; -import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; +import { + addOnchainEventListener, + ensIndexerSchema, + type IndexingEngineContext, +} from "@/lib/indexing-engines/ponder"; import { toJson } from "@/lib/json-stringify-with-bigints"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs, LogEventBase } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts index 04789919e..d8b7ef208 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/EnhancedAccessControl.ts @@ -1,4 +1,3 @@ -import ensIndexerSchema from "ponder:schema"; import { type Address, isAddressEqual, zeroAddress } from "viem"; import { @@ -11,8 +10,11 @@ import { import { ensureAccount } from "@/lib/ensv2/account-db-helpers"; import { ensurePermissionsEvent } from "@/lib/ensv2/event-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; -import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; +import { + addOnchainEventListener, + ensIndexerSchema, + type IndexingEngineContext, +} from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts b/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts index 8e04a0862..2c852fd0e 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/shared/Resolver.ts @@ -2,8 +2,7 @@ import { PluginName } from "@ensnode/ensnode-sdk"; import { ensureResolverEvent } from "@/lib/ensv2/event-db-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; -import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; +import { addOnchainEventListener, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { LogEventBase } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts index 2cb137eef..326e04180 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv1Registry.ts @@ -12,8 +12,7 @@ import { } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; -import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; +import { addOnchainEventListener, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { ensureDomainResolverRelation } from "@/lib/protocol-acceleration/domain-resolver-relationship-db-helpers"; diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts index 212f839ca..69d8f60d4 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ENSv2Registry.ts @@ -3,8 +3,7 @@ import type { Address } from "viem"; import { getCanonicalId, makeENSv2DomainId, PluginName } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; -import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; +import { addOnchainEventListener, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { ensureDomainResolverRelation } from "@/lib/protocol-acceleration/domain-resolver-relationship-db-helpers"; diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts index 3d5ae2f88..d53bff186 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/StandaloneReverseRegistrar.ts @@ -1,12 +1,10 @@ import config from "@/config"; -import ensIndexerSchema from "ponder:schema"; - import { getENSRootChainId } from "@ensnode/datasources"; import { DEFAULT_EVM_COIN_TYPE, evmChainIdToCoinType, PluginName } from "@ensnode/ensnode-sdk"; import { interpretNameRecordValue } from "@ensnode/ensnode-sdk/internal"; -import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; +import { addOnchainEventListener, ensIndexerSchema } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; /** diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts index 2b3548a81..acf45a948 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/handlers/ThreeDNSToken.ts @@ -13,8 +13,7 @@ import { } from "@ensnode/ensnode-sdk"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; -import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; +import { addOnchainEventListener, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { ensureDomainResolverRelation } from "@/lib/protocol-acceleration/domain-resolver-relationship-db-helpers"; diff --git a/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-action.ts b/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-action.ts index 501d01b74..fd89a9448 100644 --- a/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-action.ts +++ b/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-action.ts @@ -1,9 +1,8 @@ -import ensIndexerSchema from "ponder:schema"; import type { Hash } from "viem"; import { formatAccountId, type Node, type RegistrarAction } from "@ensnode/ensnode-sdk"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; /** * Logical Event Key diff --git a/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-controller-events.ts b/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-controller-events.ts index eda954dca..0e0a36794 100644 --- a/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-controller-events.ts +++ b/apps/ensindexer/src/plugins/registrars/shared/lib/registrar-controller-events.ts @@ -1,4 +1,3 @@ -import ensIndexerSchema from "ponder:schema"; import type { Address, Hash } from "viem"; import { @@ -10,7 +9,11 @@ import { type RegistrarActionReferral, } from "@ensnode/ensnode-sdk"; -import type { IndexingEngineContext, IndexingEngineEvent } from "@/lib/indexing-engines/ponder"; +import { + ensIndexerSchema, + type IndexingEngineContext, + type IndexingEngineEvent, +} from "@/lib/indexing-engines/ponder"; import { makeLogicalEventKey } from "./registrar-action"; diff --git a/apps/ensindexer/src/plugins/registrars/shared/lib/registration-lifecycle.ts b/apps/ensindexer/src/plugins/registrars/shared/lib/registration-lifecycle.ts index a67755941..ecad5342a 100644 --- a/apps/ensindexer/src/plugins/registrars/shared/lib/registration-lifecycle.ts +++ b/apps/ensindexer/src/plugins/registrars/shared/lib/registration-lifecycle.ts @@ -1,5 +1,3 @@ -import ensIndexerSchema from "ponder:schema"; - import { type AccountId, formatAccountId, @@ -7,7 +5,7 @@ import { type UnixTimestamp, } from "@ensnode/ensnode-sdk"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; /** * Get RegistrationLifecycle by node value. diff --git a/apps/ensindexer/src/plugins/registrars/shared/lib/subregistry.ts b/apps/ensindexer/src/plugins/registrars/shared/lib/subregistry.ts index 33b96f2a1..ce0364105 100644 --- a/apps/ensindexer/src/plugins/registrars/shared/lib/subregistry.ts +++ b/apps/ensindexer/src/plugins/registrars/shared/lib/subregistry.ts @@ -2,11 +2,9 @@ * This file contains handlers used in event handlers for a subregistry contract. */ -import ensIndexerSchema from "ponder:schema"; - import { type AccountId, formatAccountId, type Node } from "@ensnode/ensnode-sdk"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; /** * Upsert Subregistry record diff --git a/apps/ensindexer/src/plugins/registrars/shared/lib/universal-registrar-renewal-with-referrer-events.ts b/apps/ensindexer/src/plugins/registrars/shared/lib/universal-registrar-renewal-with-referrer-events.ts index 0d0cfb182..1bc0643d6 100644 --- a/apps/ensindexer/src/plugins/registrars/shared/lib/universal-registrar-renewal-with-referrer-events.ts +++ b/apps/ensindexer/src/plugins/registrars/shared/lib/universal-registrar-renewal-with-referrer-events.ts @@ -1,4 +1,3 @@ -import ensIndexerSchema from "ponder:schema"; import type { Address, Hash } from "viem"; import { @@ -8,7 +7,11 @@ import { type RegistrarActionReferral, } from "@ensnode/ensnode-sdk"; -import type { IndexingEngineContext, IndexingEngineEvent } from "@/lib/indexing-engines/ponder"; +import { + ensIndexerSchema, + type IndexingEngineContext, + type IndexingEngineEvent, +} from "@/lib/indexing-engines/ponder"; import { makeLogicalEventKey } from "./registrar-action"; diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts index 8c92e6d0a..fca6ac45a 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/handlers/Registry.ts @@ -1,9 +1,10 @@ -import ensIndexerSchema from "ponder:schema"; - import { makeSubdomainNode, type Node, PluginName, ROOT_NODE } from "@ensnode/ensnode-sdk"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; -import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; +import { + addOnchainEventListener, + ensIndexerSchema, + type IndexingEngineContext, +} from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { setupRootNode } from "@/lib/subgraph/subgraph-helpers"; import { diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/NameWrapper.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/NameWrapper.ts index cdd9a3a39..3d13b635c 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/NameWrapper.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/NameWrapper.ts @@ -1,6 +1,5 @@ import config from "@/config"; -import ensIndexerSchema from "ponder:schema"; /** * NOTE: the subgraph has a helper function called `checkPccBurned` which checks if the bit is SET: * https://github.com/ensdomains/ens-subgraph/blob/c844791/src/nameWrapper.ts#L63 @@ -34,7 +33,7 @@ import { import { subgraph_decodeDNSEncodedLiteralName } from "@/lib/dns-helpers"; import { getThisAccountId } from "@/lib/get-this-account-id"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { bigintMax } from "@/lib/lib-helpers"; import { getManagedName } from "@/lib/managed-names"; import type { EventWithArgs } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registrar.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registrar.ts index 3a8959954..354554745 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registrar.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registrar.ts @@ -1,6 +1,5 @@ import config from "@/config"; -import ensIndexerSchema from "ponder:schema"; import type { Address } from "viem"; import { @@ -19,7 +18,7 @@ import { import { getThisAccountId } from "@/lib/get-this-account-id"; import { labelByLabelHash } from "@/lib/graphnode-helpers"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { getManagedName } from "@/lib/managed-names"; import { pluginSupportsPremintedNames } from "@/lib/plugin-helpers"; import type { EventWithArgs } from "@/lib/ponder-helpers"; diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registry.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registry.ts index 1833e06a3..ccc5048ba 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registry.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Registry.ts @@ -1,6 +1,5 @@ import config from "@/config"; -import ensIndexerSchema from "ponder:schema"; import { type Address, isAddressEqual, zeroAddress } from "viem"; import { getENSRootChainId } from "@ensnode/datasources"; @@ -20,7 +19,7 @@ import { import { labelByLabelHash } from "@/lib/graphnode-helpers"; import { healAddrReverseSubnameLabel } from "@/lib/heal-addr-reverse-subname-label"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { sharedEventValues, upsertAccount, upsertResolver } from "@/lib/subgraph/db-helpers"; import { makeResolverId } from "@/lib/subgraph/ids"; diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Resolver.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Resolver.ts index 6a397eea1..7aed738c8 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/Resolver.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/Resolver.ts @@ -1,12 +1,11 @@ import config from "@/config"; -import ensIndexerSchema from "ponder:schema"; import type { Address, Hash, Hex } from "viem"; import { hasNullByte, type Node, stripNullBytes, uniq } from "@ensnode/ensnode-sdk"; import { parseDnsTxtRecordArgs } from "@/lib/dns-helpers"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { sharedEventValues, upsertAccount, upsertResolver } from "@/lib/subgraph/db-helpers"; import { makeResolverId } from "@/lib/subgraph/ids"; diff --git a/apps/ensindexer/src/plugins/subgraph/shared-handlers/ThreeDNSToken.ts b/apps/ensindexer/src/plugins/subgraph/shared-handlers/ThreeDNSToken.ts index 004e047d6..c394f33b1 100644 --- a/apps/ensindexer/src/plugins/subgraph/shared-handlers/ThreeDNSToken.ts +++ b/apps/ensindexer/src/plugins/subgraph/shared-handlers/ThreeDNSToken.ts @@ -1,4 +1,3 @@ -import ensIndexerSchema from "ponder:schema"; import { type Address, isAddressEqual, zeroAddress, zeroHash } from "viem"; import { @@ -18,7 +17,7 @@ import { } from "@ensnode/ensnode-sdk"; import { labelByLabelHash } from "@/lib/graphnode-helpers"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { parseLabelAndNameFromOnChainMetadata } from "@/lib/json-metadata"; import type { EventWithArgs } from "@/lib/ponder-helpers"; import { diff --git a/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts b/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts index b48b3005c..4e8eb8026 100644 --- a/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts +++ b/apps/ensindexer/src/plugins/tokenscope/handlers/Seaport.ts @@ -1,10 +1,8 @@ import config from "@/config"; -import ensIndexerSchema from "ponder:schema"; - import { formatAssetId, PluginName } from "@ensnode/ensnode-sdk"; -import { addOnchainEventListener } from "@/lib/indexing-engines/ponder"; +import { addOnchainEventListener, ensIndexerSchema } from "@/lib/indexing-engines/ponder"; import { namespaceContract } from "@/lib/plugin-helpers"; import { upsertAccount } from "@/lib/subgraph/db-helpers"; import { makeEventId } from "@/lib/subgraph/ids"; diff --git a/apps/ensindexer/src/plugins/tokenscope/lib/handle-nft-transfer.ts b/apps/ensindexer/src/plugins/tokenscope/lib/handle-nft-transfer.ts index 4ebcdee26..5f36c4736 100644 --- a/apps/ensindexer/src/plugins/tokenscope/lib/handle-nft-transfer.ts +++ b/apps/ensindexer/src/plugins/tokenscope/lib/handle-nft-transfer.ts @@ -1,4 +1,3 @@ -import ensIndexerSchema from "ponder:schema"; import { type Address, zeroAddress } from "viem"; import { @@ -11,7 +10,7 @@ import { NFTTransferTypes, } from "@ensnode/ensnode-sdk"; -import type { IndexingEngineContext } from "@/lib/indexing-engines/ponder"; +import { ensIndexerSchema, type IndexingEngineContext } from "@/lib/indexing-engines/ponder"; import { upsertAccount } from "@/lib/subgraph/db-helpers"; export const handleERC1155Transfer = async ( From 5fca5f532bf6601c21dbb5aa10995062aae3d696 Mon Sep 17 00:00:00 2001 From: Tomasz Kopacki Date: Mon, 30 Mar 2026 08:00:03 +0200 Subject: [PATCH 11/11] Apply PR feedback --- .../src/lib/indexing-engines/ponder.ts | 56 +++++++++++++++++-- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/apps/ensindexer/src/lib/indexing-engines/ponder.ts b/apps/ensindexer/src/lib/indexing-engines/ponder.ts index b5131f358..fca836a2b 100644 --- a/apps/ensindexer/src/lib/indexing-engines/ponder.ts +++ b/apps/ensindexer/src/lib/indexing-engines/ponder.ts @@ -1,3 +1,11 @@ +/** + * This module is an abstraction layer for the Indexing Engine of ENSIndexer. + * It decouples core indexing logic from Ponder-specific implementation details. + * Benefits of this decoupling include: + * - Building a custom context data model. + * - Implementing shared logic before or after event handlers, if needed. + */ + export * as ensIndexerSchema from "ponder:schema"; import { @@ -12,6 +20,43 @@ import { * {@link addOnchainEventListener}. */ export interface IndexingEngineContext extends PonderIndexingContext { + /** + * Store API for ENSDb. + * + * There are two ways to write to the ENSIndexer Schema in ENSDb: + * 1) Store API — the recommended way, available via `context.ensDb`. + * 2) Raw SQL API — available via `context.ensDb.sql`. This is + * a Drizzle client for the ENSIndexer Schema in ENSDb. + * Use only when necessary. + * + * The Store API is a SQL-like query builder optimized for common indexing + * workloads. It's 100-1000x faster than raw SQL. All operations run + * in-memory and rows are flushed to the database periodically using + * efficient `COPY` statements. + * + * @example Using the Store API: + * ```ts + * // Insert a single row + * await context.ensDb.insert(ensIndexerSchema.account) + * .values({ id: interpretedAddress }); + * // Insert multiple rows + * await context.ensDb.insert(ensIndexerSchema.account) + * .values([ + * { id: interpretedAddress1 }, + * { id: interpretedAddress2 }, + * ]); + * // Find a single row by primary key + * await context.ensDb.find(ensIndexerSchema.registry, { id: registryId }); + * // Update a row by primary key + * await context.ensDb.update(ensIndexerSchema.subgraph_domain, { id: node }) + * .set({ resolverId, resolvedAddressId: resolver.addrId }); + * // Delete a row by primary key + * await context.ensDb.delete(ensIndexerSchema.resolverAddressRecord, id); + * ``` + * + * For more details on the Store API and Raw SQL API, see the Ponder documentation. + * @see https://ponder.sh/docs/indexing/write#write-to-the-database + */ ensDb: PonderIndexingContext["db"]; } @@ -32,11 +77,10 @@ export interface IndexingEngineEventHandlerArgs, @@ -50,7 +94,7 @@ function buildIndexingEngineContext( /** * A thin wrapper around `ponder.on` that allows us to: * - Provide custom context to event handlers. - * - Execute additional logic before or after the event handler, if needed. + * - Execute additional logic before or after event handlers, if needed. * * Note that this function is called on every event, so it should be * efficient and avoid doing any heavy computations or database queries.