diff --git a/.changeset/tricky-clouds-dress.md b/.changeset/tricky-clouds-dress.md new file mode 100644 index 000000000..a62ac85e5 --- /dev/null +++ b/.changeset/tricky-clouds-dress.md @@ -0,0 +1,5 @@ +--- +"ensapi": minor +--- + +Omnigraph API (BREAKING): Removed `Resolver.dedicated` field in advance of PermissionedResolver integration. diff --git a/AGENTS.md b/AGENTS.md index dd62b4538..abbc539a7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -42,7 +42,7 @@ Runnable commands for validating changes; lint and format with Biome. - Run tests for a single package/app: `pnpm --filter test` (e.g. `pnpm --filter ensapi test`) - Lint and format: `pnpm lint` (fixes where applicable); CI lint: `pnpm lint:ci` - Type checking: `pnpm typecheck` (runs typecheck in all workspaces) -- Build (validate tsup/tsx bundling for the package you changed): `pnpm --filter build` + - Always prefer `pnpm -F typecheck` over `tsc` ## Testing diff --git a/apps/ensapi/src/graphql-api/schema/account.integration.test.ts b/apps/ensapi/src/graphql-api/schema/account.integration.test.ts index 7dd780369..0125ccc92 100644 --- a/apps/ensapi/src/graphql-api/schema/account.integration.test.ts +++ b/apps/ensapi/src/graphql-api/schema/account.integration.test.ts @@ -25,7 +25,7 @@ import { // via devnet const DEVNET_DEPLOYER: Address = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266"; const DEFAULT_OWNER: Address = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8"; -const NEW_OWNER: Address = "0x90f79bf6eb2c4f870365e785982e1f101e93b906"; +const NEW_OWNER_OWNER: Address = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC"; describe("Account.domains", () => { type AccountDomainsResult = { @@ -66,7 +66,9 @@ describe("Account.domains", () => { }); it("returns domains owned by the new owner", async () => { - const result = await request(AccountDomains, { address: NEW_OWNER }); + const result = await request(AccountDomains, { + address: NEW_OWNER_OWNER, + }); const domains = flattenConnection(result.account.domains); const names = domains.map((d) => d.name); diff --git a/apps/ensapi/src/graphql-api/schema/registration.ts b/apps/ensapi/src/graphql-api/schema/registration.ts index 7d2faf2da..fb192e2ec 100644 --- a/apps/ensapi/src/graphql-api/schema/registration.ts +++ b/apps/ensapi/src/graphql-api/schema/registration.ts @@ -14,6 +14,7 @@ import { builder } from "@/graphql-api/builder"; import { orderPaginationBy, paginateByInt } from "@/graphql-api/lib/connection-helpers"; import { getModelId } from "@/graphql-api/lib/get-model-id"; import { lazyConnection } from "@/graphql-api/lib/lazy-connection"; +import { AccountRef } from "@/graphql-api/schema/account"; import { AccountIdRef } from "@/graphql-api/schema/account-id"; import { INDEX_PAGINATED_CONNECTION_ARGS } from "@/graphql-api/schema/constants"; import { DomainInterfaceRef } from "@/graphql-api/schema/domain"; @@ -42,6 +43,7 @@ export type RegistrationInterface = Pick< | "registrarChainId" | "registrarAddress" | "registrantId" + | "unregistrantId" | "referrer" >; export type NameWrapperRegistration = RequiredAndNotNull; @@ -54,6 +56,7 @@ export type BaseRegistrarRegistration = RequiredAndNotNull< }; export type ThreeDNSRegistration = Registration; export type ENSv2RegistryRegistration = Registration; +export type ENSv2RegistryReservation = Registration; RegistrationInterfaceRef.implement({ description: @@ -130,6 +133,26 @@ RegistrationInterfaceRef.implement({ resolve: (parent) => parent.referrer, }), + /////////////////////////// + // Registration.registrant + /////////////////////////// + registrant: t.field({ + description: "The Registrant of a Registration, if exists.", + type: AccountRef, + nullable: true, + resolve: (parent) => parent.registrantId, + }), + + ///////////////////////////// + // Registration.unregistrant + ///////////////////////////// + unregistrant: t.field({ + description: "The Unregistrant of a Registration, if exists.", + type: AccountRef, + nullable: true, + resolve: (parent) => parent.unregistrantId, + }), + ///////////////////////// // Registration.renewals ///////////////////////// @@ -275,7 +298,20 @@ export const ENSv2RegistryRegistrationRef = builder.objectRef (value as RegistrationInterface).type === "ENSv2Registry", + isTypeOf: (value) => (value as RegistrationInterface).type === "ENSv2RegistryRegistration", + fields: (t) => ({}), +}); + +//////////////////////////// +// ENSv2RegistryReservation +//////////////////////////// +export const ENSv2RegistryReservationRef = builder.objectRef( + "ENSv2RegistryReservation", +); +ENSv2RegistryReservationRef.implement({ + description: "ENSv2RegistryReservation represents a Reservation within an ENSv2 Registry.", + interfaces: [RegistrationInterfaceRef], + isTypeOf: (value) => (value as RegistrationInterface).type === "ENSv2RegistryReservation", fields: (t) => ({}), }); diff --git a/apps/ensapi/src/graphql-api/schema/resolver.ts b/apps/ensapi/src/graphql-api/schema/resolver.ts index f3119b100..de194f89b 100644 --- a/apps/ensapi/src/graphql-api/schema/resolver.ts +++ b/apps/ensapi/src/graphql-api/schema/resolver.ts @@ -4,13 +4,7 @@ import { type ResolveCursorConnectionArgs, resolveCursorConnection } from "@poth import { and, eq } from "drizzle-orm"; import { namehash } from "viem"; -import { - makePermissionsId, - makeResolverRecordsId, - NODE_ANY, - type ResolverId, - ROOT_RESOURCE, -} from "@ensnode/ensnode-sdk"; +import { makePermissionsId, makeResolverRecordsId, type ResolverId } from "@ensnode/ensnode-sdk"; import { isBridgedResolver } from "@ensnode/ensnode-sdk/internal"; import { builder } from "@/graphql-api/builder"; @@ -18,12 +12,11 @@ import { orderPaginationBy, paginateBy } from "@/graphql-api/lib/connection-help import { resolveFindEvents } from "@/graphql-api/lib/find-events/find-events-resolver"; import { getModelId } from "@/graphql-api/lib/get-model-id"; import { lazyConnection } from "@/graphql-api/lib/lazy-connection"; -import { AccountRef } from "@/graphql-api/schema/account"; import { AccountIdInput, AccountIdRef } from "@/graphql-api/schema/account-id"; import { ID_PAGINATED_CONNECTION_ARGS } from "@/graphql-api/schema/constants"; import { EventRef, EventsWhereInput } from "@/graphql-api/schema/event"; import { NameOrNodeInput } from "@/graphql-api/schema/name-or-node"; -import { PermissionsRef, type PermissionsUserResource } from "@/graphql-api/schema/permissions"; +import { PermissionsRef } from "@/graphql-api/schema/permissions"; import { ResolverRecordsRef } from "@/graphql-api/schema/resolver-records"; import { ensDb, ensIndexerSchema } from "@/lib/ensdb/singleton"; @@ -121,24 +114,6 @@ ResolverRef.implement({ }, }), - ////////////////////// - // Resolver.dedicated - ////////////////////// - dedicated: t.field({ - description: "If Resolver is a DedicatedResolver, additional DedicatedResolverMetadata.", - type: DedicatedResolverMetadataRef, - nullable: true, - resolve: async (parent, args, context) => - ensDb.query.permissionsUser.findFirst({ - where: (t, { eq, and }) => - and( - eq(t.chainId, parent.chainId), - eq(t.address, parent.address), - eq(t.resource, ROOT_RESOURCE), - ), - }), - }), - //////////////////// // Resolver.bridged //////////////////// @@ -178,49 +153,6 @@ ResolverRef.implement({ }), }); -///////////////////////////// -// DedicatedResolverMetadata -///////////////////////////// -export const DedicatedResolverMetadataRef = builder.objectRef( - "DedicatedResolverMetadataRef", -); -DedicatedResolverMetadataRef.implement({ - description: "Represents additional metadata available for DedicatedResolvers.", - fields: (t) => ({ - /////////////////////////// - // DedicatedResolver.owner - /////////////////////////// - owner: t.field({ - description: "The Account that owns this DedicatedResolver.", - type: AccountRef, - nullable: false, - resolve: (parent) => parent.user, - }), - - ///////////////////////////////// - // DedicatedResolver.permissions - ///////////////////////////////// - permissions: t.field({ - description: "TODO", - type: PermissionsRef, - nullable: false, - // TODO: render a DedicatedResolverPermissions model that parses the backing permissions into dedicated-resolver-semantic roles? - resolve: ({ chainId, address }) => makePermissionsId({ chainId, address }), - }), - - ///////////////////////////// - // Resolver.dedicatedRecords - ///////////////////////////// - records: t.field({ - description: "The ResolverRecords issued under `NODE_ANY`.", - type: ResolverRecordsRef, - nullable: true, - resolve: ({ chainId, address }, args) => - makeResolverRecordsId({ chainId, address }, NODE_ANY), - }), - }), -}); - ///////////////////// // Inputs ///////////////////// diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts index c54058aba..5e6478964 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ENSv2Registry.ts @@ -32,8 +32,121 @@ import type { EventWithArgs } from "@/lib/ponder-helpers"; const pluginName = PluginName.ENSv2; export default function () { + /** + * In an ENSv2 Registry, a Reservation is just a Registration with no `owner`, so we unify the + * handling of these two pathways here. + */ + async function handleRegistrationOrReservation({ + context, + event, + }: { + context: IndexingEngineContext; + event: EventWithArgs<{ + tokenId: bigint; + labelHash: LabelHash; + label: string; + // NOTE: marking `owner` as optional to handle both LabelRegistered and LabelReserved events + owner?: Address; + expiry: bigint; + sender: Address; + }>; + }) { + const { tokenId, labelHash, label: _label, owner, expiry, sender: registrant } = event.args; + const label = _label as LiteralLabel; + const isReservation = owner === undefined; + + const registry = getThisAccountId(context, event); + const registryId = makeRegistryId(registry); + const canonicalId = getCanonicalId(tokenId); + const domainId = makeENSv2DomainId(registry, canonicalId); + + // Sanity Check: LabelHash must match Label + if (labelHash !== labelhash(label)) { + throw new Error(`Sanity Check: labelHash !== labelhash(label)\n${toJson(event.args)}`); + } + + // Sanity Check: CanonicalId must match LabelHash + if (canonicalId !== getCanonicalId(hexToBigInt(labelHash))) { + throw new Error( + `Sanity Check: canonicalId !== getCanonicalId(hexToBigInt(labelHash))\n${toJson(event.args)}`, + ); + } + + // ensure Registry + // TODO(signals) — move to NewRegistry and add invariant here + await context.ensDb + .insert(ensIndexerSchema.registry) + .values({ id: registryId, ...registry }) + .onConflictDoNothing(); + + // ensure discovered Label + await ensureLabel(context, label); + + const registration = await getLatestRegistration(context, domainId); + if (isReservation) { + // Invariant: if this is a Reservation, any existing Registration should be fully expired + if (registration && !isRegistrationFullyExpired(registration, event.block.timestamp)) { + throw new Error( + `Invariant(ENSv2Registry:Label[Registered|Reserved]): Existing unexpired Registration found, expected none or expired.\n${toJson(registration)}`, + ); + } + } else { + // Invariant: if this is a Registration, unless it is a Reservation, it should be fully expired + if ( + registration && + registration.type !== "ENSv2RegistryReservation" && + !isRegistrationFullyExpired(registration, event.block.timestamp) + ) { + throw new Error( + `Invariant(ENSv2Registry:Label[Registered|Reserved]): Existing unexpired Registration found, expected none or expired.\n${toJson(registration)}`, + ); + } + } + + // ensure v2Domain + await context.ensDb + .insert(ensIndexerSchema.v2Domain) + .values({ + id: domainId, + tokenId, + registryId, + labelHash, + // NOTE: we intentionally omit setting ownerId here. either + // a) this is a Registration, in which case a TransferSingle event will be emitted afterwards, or + // b) this is a Reservation, in which there is no owner + }) + // if the v2Domain exists, this is a re-register after expiration and tokenId will have changed + .onConflictDoUpdate({ tokenId }); + + // insert Registration + await ensureAccount(context, registrant); + await insertLatestRegistration(context, { + domainId, + type: isReservation ? "ENSv2RegistryReservation" : "ENSv2RegistryRegistration", + registrarChainId: registry.chainId, + registrarAddress: registry.address, + registrantId: interpretAddress(registrant), + start: event.block.timestamp, + expiry, + eventId: await ensureEvent(context, event), + }); + + // push event to domain history + await ensureDomainEvent(context, event, domainId); + } + + addOnchainEventListener( + namespaceContract(pluginName, "ENSv2Registry:LabelRegistered"), + handleRegistrationOrReservation, + ); + + addOnchainEventListener( + namespaceContract(pluginName, "ENSv2Registry:LabelReserved"), + handleRegistrationOrReservation, + ); + addOnchainEventListener( - namespaceContract(pluginName, "ENSv2Registry:NameRegistered"), + namespaceContract(pluginName, "ENSv2Registry:LabelUnregistered"), async ({ context, event, @@ -41,91 +154,40 @@ export default function () { context: IndexingEngineContext; event: EventWithArgs<{ tokenId: bigint; - labelHash: LabelHash; - label: string; - owner: Address; - expiry: bigint; sender: Address; }>; }) => { - const { tokenId, label: _label, expiry, sender: registrant } = event.args; - const label = _label as LiteralLabel; + const { tokenId, sender: unregistrant } = event.args; - const labelHash = labelhash(label); const registry = getThisAccountId(context, event); - const registryId = makeRegistryId(registry); const canonicalId = getCanonicalId(tokenId); const domainId = makeENSv2DomainId(registry, canonicalId); - // Sanity Check: Canonical Id must match emitted label - if (canonicalId !== getCanonicalId(hexToBigInt(labelhash(label)))) { - throw new Error( - `Sanity Check: Domain's Canonical Id !== getCanonicalId(uint256(labelhash(label)))\n${toJson( - { - tokenId, - canonicalId, - label, - labelHash, - hexToBigInt: hexToBigInt(labelhash(label)), - }, - )}`, - ); - } - - // upsert Registry - // TODO(signals) — move to NewRegistry and add invariant here - await context.ensDb - .insert(ensIndexerSchema.registry) - .values({ - id: registryId, - type: "RegistryContract", - ...registry, - }) - .onConflictDoNothing(); - - // TODO(bridged-registries): upon registry creation, write the registry's canonical domain here - - // ensure discovered Label - await ensureLabel(context, label); - const registration = await getLatestRegistration(context, domainId); - const isFullyExpired = - registration && isRegistrationFullyExpired(registration, event.block.timestamp); - // Invariant: If a Registration for this v2Domain exists, it must be fully expired - if (registration && !isFullyExpired) { + // Invariant: There must be an existing Registration + if (!registration) { + throw new Error(`Invariant(ENSv2Registry:LabelUnregistered): Expected registration.`); + } + + // Invariant: The existing Registration must not be expired. + if (isRegistrationFullyExpired(registration, event.block.timestamp)) { throw new Error( - `Invariant(ENSv2Registry:NameRegistered): Existing unexpired ENSv2Registry Registration found in NameRegistered, expected none or expired.\n${toJson(registration)}`, + `Invariant(ENSv2Registry:LabelUnregistered): Expected unexpired registration but got:\n${toJson(registration)}`, ); } - // insert or update v2Domain - // console.log(`NameRegistered: '${label}'\n ↳ ${domainId}`); - await context.ensDb - .insert(ensIndexerSchema.v2Domain) - .values({ - id: domainId, - tokenId, - registryId, - labelHash, - // NOTE: ownerId omitted, Transfer* events are sole source of ownership - }) - // if the v2Domain exists, this is a re-register after expiration and tokenId may have changed - .onConflictDoUpdate({ tokenId }); - - // insert ENSv2Registry Registration - await ensureAccount(context, registrant); - await insertLatestRegistration(context, { - domainId, - type: "ENSv2Registry", - registrarChainId: registry.chainId, - registrarAddress: registry.address, - registrantId: interpretAddress(registrant), - start: event.block.timestamp, - expiry, - eventId: await ensureEvent(context, event), + // unregistering a label just immediately sets its expiration to event.block.timestamp, which + // effectively removes it from resolution (which interprets expired names as non-existent) + await ensureAccount(context, unregistrant); + await context.ensDb.update(ensIndexerSchema.registration, { id: registration.id }).set({ + expiry: event.block.timestamp, + unregistrantId: interpretAddress(unregistrant), }); + // NOTE(shrugs): PermissionedRegistry also increments eacVersionId and tokenVersionId if there was a + // previous owner, but i'm not sure if we need to handle that detail here + // push event to domain history await ensureDomainEvent(context, event, domainId); }, @@ -153,15 +215,15 @@ export default function () { const registration = await getLatestRegistration(context, domainId); - // Invariant: Registration must exist + // Invariant: There must be an existing Registration if (!registration) { - throw new Error(`Invariant(ENSv2Registry:NameRenewed): Registration expected, none found.`); + throw new Error(`Invariant(ENSv2Registry:ExpiryUpdated): Expected registration.`); } - // Invariant: Registration must not be expired + // Invariant: The existing Registration must not be expired. if (isRegistrationFullyExpired(registration, event.block.timestamp)) { throw new Error( - `Invariant(ENSv2Registry:NameRenewed): Registration found but it is expired:\n${toJson(registration)}`, + `Invariant(ENSv2Registry:ExpiryUpdated): Expected unexpired Registration but got:\n${toJson(registration)}`, ); } @@ -276,13 +338,12 @@ export default function () { const registry = getThisAccountId(context, event); const domainId = makeENSv2DomainId(registry, canonicalId); - // TODO(signals): remove this + // TODO(signals): remove this invariant, since we'll only be indexing Registry contracts const registryId = makeRegistryId(registry); 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 + // update the Domain's ownerId await context.ensDb .update(ensIndexerSchema.v2Domain, { id: domainId }) .set({ ownerId: interpretAddress(owner) }); diff --git a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts index e72267bfd..0d4c54657 100644 --- a/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts +++ b/apps/ensindexer/src/plugins/ensv2/handlers/ensv2/ETHRegistrar.ts @@ -83,7 +83,7 @@ export default function () { } // Invariant: must be ENSv2Registry Registration - if (registration.type !== "ENSv2Registry") { + if (registration.type !== "ENSv2RegistryRegistration") { throw new Error( `Invariant(ETHRegistrar:NameRegistered): Registration found but not ENSv2Registry Registration:\n${toJson(registration)}`, ); @@ -156,7 +156,7 @@ export default function () { } // Invariant: Must be ENSv2Registry Registration - if (registration.type !== "ENSv2Registry") { + if (registration.type !== "ENSv2RegistryRegistration") { throw new Error( `Invariant(ETHRegistrar:NameRenewed): Registration found but not ENSv2Registry Registration:\n${toJson(registration)}`, ); diff --git a/docker-compose.yml b/docker-compose.yml index fe37eb55e..3e1bf72b7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -103,6 +103,23 @@ services: volumes: - postgres_data:/var/lib/postgresql/data + devnet: + container_name: devnet + image: ghcr.io/ensdomains/contracts-v2:main-e8696c6 + command: ./script/runDevnet.ts --testNames + pull_policy: always + ports: + - "8545:8545" + environment: + ANVIL_IP_ADDR: "0.0.0.0" + healthcheck: + test: ["CMD", "curl", "--fail", "-s", "http://localhost:8000/health"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s + start_interval: 1s + volumes: postgres_data: driver: local diff --git a/package.json b/package.json index 80da54cb7..a7b8af877 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "changeset-publish": "changeset publish", "changeset-publish:next": "changeset publish --no-git-tag --snapshot --tag next", "packages:prepublish": "pnpm -r prepublish", + "devnet": "docker compose up devnet", "docker:build:ensnode": "pnpm run -w --parallel \"/^docker:build:.*/\"", "docker:build:ensindexer": "docker build -f apps/ensindexer/Dockerfile -t ghcr.io/namehash/ensnode/ensindexer:latest .", "docker:build:ensadmin": "docker build -f apps/ensadmin/Dockerfile -t ghcr.io/namehash/ensnode/ensadmin:latest .", diff --git a/packages/datasources/src/abis/ensv2/ETHRegistrar.ts b/packages/datasources/src/abis/ensv2/ETHRegistrar.ts index d3eead1ce..1b71a1663 100644 --- a/packages/datasources/src/abis/ensv2/ETHRegistrar.ts +++ b/packages/datasources/src/abis/ensv2/ETHRegistrar.ts @@ -2,1143 +2,1143 @@ import type { Abi } from "viem"; export const ETHRegistrar = [ { + type: "constructor", inputs: [ { - internalType: "contract IPermissionedRegistry", name: "registry", type: "address", + internalType: "contract IPermissionedRegistry", }, { - internalType: "contract IHCAFactoryBasic", name: "hcaFactory", type: "address", + internalType: "contract IHCAFactoryBasic", }, { - internalType: "address", name: "beneficiary", type: "address", + internalType: "address", }, { - internalType: "uint64", name: "minCommitmentAge", type: "uint64", + internalType: "uint64", }, { - internalType: "uint64", name: "maxCommitmentAge", type: "uint64", + internalType: "uint64", }, { - internalType: "uint64", name: "minRegisterDuration", type: "uint64", + internalType: "uint64", }, { - internalType: "contract IRentPriceOracle", name: "rentPriceOracle_", type: "address", + internalType: "contract IRentPriceOracle", }, ], stateMutability: "nonpayable", - type: "constructor", }, { - inputs: [ + type: "function", + name: "BENEFICIARY", + inputs: [], + outputs: [ { - internalType: "bytes32", - name: "commitment", - type: "bytes32", + name: "", + type: "address", + internalType: "address", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "HCA_FACTORY", + inputs: [], + outputs: [ + { + name: "", + type: "address", + internalType: "contract IHCAFactoryBasic", }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "MAX_COMMITMENT_AGE", + inputs: [], + outputs: [ { - internalType: "uint64", - name: "validFrom", + name: "", type: "uint64", + internalType: "uint64", }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "MIN_COMMITMENT_AGE", + inputs: [], + outputs: [ { + name: "", + type: "uint64", internalType: "uint64", - name: "blockTimestamp", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "MIN_REGISTER_DURATION", + inputs: [], + outputs: [ + { + name: "", type: "uint64", + internalType: "uint64", }, ], - name: "CommitmentTooNew", - type: "error", + stateMutability: "view", }, { - inputs: [ + type: "function", + name: "REGISTRY", + inputs: [], + outputs: [ { - internalType: "bytes32", - name: "commitment", - type: "bytes32", + name: "", + type: "address", + internalType: "contract IPermissionedRegistry", }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "ROOT_RESOURCE", + inputs: [], + outputs: [ { - internalType: "uint64", - name: "validTo", - type: "uint64", + name: "", + type: "uint256", + internalType: "uint256", }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "commit", + inputs: [ { - internalType: "uint64", - name: "blockTimestamp", - type: "uint64", + name: "commitment", + type: "bytes32", + internalType: "bytes32", }, ], - name: "CommitmentTooOld", - type: "error", + outputs: [], + stateMutability: "nonpayable", }, { + type: "function", + name: "commitmentAt", inputs: [ { - internalType: "uint64", - name: "duration", - type: "uint64", + name: "commitment", + type: "bytes32", + internalType: "bytes32", }, + ], + outputs: [ { - internalType: "uint64", - name: "minDuration", + name: "commitTime", type: "uint64", + internalType: "uint64", }, ], - name: "DurationTooShort", - type: "error", + stateMutability: "view", }, { + type: "function", + name: "getAssigneeCount", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", + internalType: "uint256", }, { - internalType: "uint256", name: "roleBitmap", type: "uint256", + internalType: "uint256", + }, + ], + outputs: [ + { + name: "counts", + type: "uint256", + internalType: "uint256", }, { - internalType: "address", - name: "account", - type: "address", + name: "mask", + type: "uint256", + internalType: "uint256", }, ], - name: "EACCannotGrantRoles", - type: "error", + stateMutability: "view", }, { + type: "function", + name: "grantRoles", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", + internalType: "uint256", }, { - internalType: "uint256", name: "roleBitmap", type: "uint256", + internalType: "uint256", }, { - internalType: "address", name: "account", type: "address", + internalType: "address", }, ], - name: "EACCannotRevokeRoles", - type: "error", - }, - { - inputs: [], - name: "EACInvalidAccount", - type: "error", - }, - { - inputs: [ + outputs: [ { - internalType: "uint256", - name: "roleBitmap", - type: "uint256", + name: "", + type: "bool", + internalType: "bool", }, ], - name: "EACInvalidRoleBitmap", - type: "error", + stateMutability: "nonpayable", }, { + type: "function", + name: "grantRootRoles", inputs: [ { - internalType: "uint256", - name: "resource", + name: "roleBitmap", type: "uint256", + internalType: "uint256", }, { - internalType: "uint256", - name: "role", - type: "uint256", + name: "account", + type: "address", + internalType: "address", }, ], - name: "EACMaxAssignees", - type: "error", + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "nonpayable", }, { + type: "function", + name: "hasAssignees", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", + internalType: "uint256", }, { - internalType: "uint256", - name: "role", + name: "roleBitmap", type: "uint256", + internalType: "uint256", }, ], - name: "EACMinAssignees", - type: "error", - }, - { - inputs: [], - name: "EACRootResourceNotAllowed", - type: "error", + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "view", }, { + type: "function", + name: "hasRoles", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", + internalType: "uint256", }, { - internalType: "uint256", name: "roleBitmap", type: "uint256", + internalType: "uint256", }, { - internalType: "address", name: "account", type: "address", + internalType: "address", }, ], - name: "EACUnauthorizedAccountRoles", - type: "error", - }, - { - inputs: [], - name: "InvalidOwner", - type: "error", - }, - { - inputs: [], - name: "MaxCommitmentAgeTooLow", - type: "error", + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "view", }, { + type: "function", + name: "hasRootRoles", inputs: [ { - internalType: "string", - name: "label", - type: "string", + name: "roleBitmap", + type: "uint256", + internalType: "uint256", + }, + { + name: "account", + type: "address", + internalType: "address", }, ], - name: "NameIsAvailable", - type: "error", - }, - { - inputs: [ + outputs: [ { - internalType: "string", - name: "label", - type: "string", + name: "", + type: "bool", + internalType: "bool", }, ], - name: "NameNotAvailable", - type: "error", + stateMutability: "view", }, { + type: "function", + name: "isAvailable", inputs: [ { - internalType: "string", name: "label", type: "string", + internalType: "string", }, ], - name: "NotValid", - type: "error", + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "view", }, { + type: "function", + name: "isPaymentToken", inputs: [ { - internalType: "contract IERC20", name: "paymentToken", type: "address", + internalType: "contract IERC20", }, ], - name: "PaymentTokenNotSupported", - type: "error", - }, - { - inputs: [ + outputs: [ { - internalType: "address", - name: "token", - type: "address", + name: "", + type: "bool", + internalType: "bool", }, ], - name: "SafeERC20FailedOperation", - type: "error", + stateMutability: "view", }, { + type: "function", + name: "isValid", inputs: [ { - internalType: "bytes32", - name: "commitment", - type: "bytes32", + name: "label", + type: "string", + internalType: "string", }, ], - name: "UnexpiredCommitmentExists", - type: "error", - }, - { - anonymous: false, - inputs: [ + outputs: [ { - indexed: false, - internalType: "bytes32", - name: "commitment", - type: "bytes32", + name: "", + type: "bool", + internalType: "bool", }, ], - name: "CommitmentMade", - type: "event", + stateMutability: "view", }, { - anonymous: false, + type: "function", + name: "makeCommitment", inputs: [ { - indexed: true, - internalType: "uint256", - name: "resource", - type: "uint256", + name: "label", + type: "string", + internalType: "string", }, { - indexed: true, + name: "owner", + type: "address", internalType: "address", - name: "account", + }, + { + name: "secret", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "subregistry", type: "address", + internalType: "contract IRegistry", }, { - indexed: false, - internalType: "uint256", - name: "oldRoleBitmap", - type: "uint256", + name: "resolver", + type: "address", + internalType: "address", }, { - indexed: false, - internalType: "uint256", - name: "newRoleBitmap", - type: "uint256", + name: "duration", + type: "uint64", + internalType: "uint64", + }, + { + name: "referrer", + type: "bytes32", + internalType: "bytes32", }, ], - name: "EACRolesChanged", - type: "event", + outputs: [ + { + name: "", + type: "bytes32", + internalType: "bytes32", + }, + ], + stateMutability: "pure", }, { - anonymous: false, + type: "function", + name: "register", inputs: [ { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256", - }, - { - indexed: false, - internalType: "string", name: "label", type: "string", + internalType: "string", }, { - indexed: false, - internalType: "address", name: "owner", type: "address", + internalType: "address", + }, + { + name: "secret", + type: "bytes32", + internalType: "bytes32", }, { - indexed: false, - internalType: "contract IRegistry", name: "subregistry", type: "address", + internalType: "contract IRegistry", }, { - indexed: false, - internalType: "address", name: "resolver", type: "address", + internalType: "address", }, { - indexed: false, - internalType: "uint64", name: "duration", type: "uint64", + internalType: "uint64", }, { - indexed: false, - internalType: "contract IERC20", name: "paymentToken", type: "address", + internalType: "contract IERC20", }, { - indexed: false, - internalType: "bytes32", name: "referrer", type: "bytes32", + internalType: "bytes32", }, + ], + outputs: [ { - indexed: false, - internalType: "uint256", - name: "base", + name: "tokenId", type: "uint256", - }, - { - indexed: false, internalType: "uint256", - name: "premium", - type: "uint256", }, ], - name: "NameRegistered", - type: "event", + stateMutability: "nonpayable", }, { - anonymous: false, + type: "function", + name: "renew", inputs: [ { - indexed: true, - internalType: "uint256", - name: "tokenId", - type: "uint256", - }, - { - indexed: false, - internalType: "string", name: "label", type: "string", + internalType: "string", }, { - indexed: false, - internalType: "uint64", name: "duration", type: "uint64", - }, - { - indexed: false, internalType: "uint64", - name: "newExpiry", - type: "uint64", }, { - indexed: false, - internalType: "contract IERC20", name: "paymentToken", type: "address", + internalType: "contract IERC20", }, { - indexed: false, - internalType: "bytes32", name: "referrer", type: "bytes32", - }, - { - indexed: false, - internalType: "uint256", - name: "base", - type: "uint256", + internalType: "bytes32", }, ], - name: "NameRenewed", - type: "event", + outputs: [], + stateMutability: "nonpayable", }, { - anonymous: false, + type: "function", + name: "rentPrice", inputs: [ { - indexed: true, - internalType: "contract IERC20", - name: "paymentToken", + name: "label", + type: "string", + internalType: "string", + }, + { + name: "owner", type: "address", + internalType: "address", + }, + { + name: "duration", + type: "uint64", + internalType: "uint64", }, - ], - name: "PaymentTokenAdded", - type: "event", - }, - { - anonymous: false, - inputs: [ { - indexed: true, - internalType: "contract IERC20", name: "paymentToken", type: "address", + internalType: "contract IERC20", }, ], - name: "PaymentTokenRemoved", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "contract IRentPriceOracle", - name: "oracle", - type: "address", - }, - ], - name: "RentPriceOracleChanged", - type: "event", - }, - { - inputs: [], - name: "BENEFICIARY", - outputs: [ - { - internalType: "address", - name: "", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "HCA_FACTORY", - outputs: [ - { - internalType: "contract IHCAFactoryBasic", - name: "", - type: "address", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "MAX_COMMITMENT_AGE", outputs: [ { - internalType: "uint64", - name: "", - type: "uint64", + name: "base", + type: "uint256", + internalType: "uint256", }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "MIN_COMMITMENT_AGE", - outputs: [ { - internalType: "uint64", - name: "", - type: "uint64", + name: "premium", + type: "uint256", + internalType: "uint256", }, ], stateMutability: "view", - type: "function", }, { - inputs: [], - name: "MIN_REGISTER_DURATION", - outputs: [ - { - internalType: "uint64", - name: "", - type: "uint64", - }, - ], - stateMutability: "view", type: "function", - }, - { + name: "rentPriceOracle", inputs: [], - name: "REGISTRY", outputs: [ { - internalType: "contract IPermissionedRegistry", name: "", type: "address", + internalType: "contract IRentPriceOracle", }, ], stateMutability: "view", - type: "function", - }, - { - inputs: [], - name: "ROOT_RESOURCE", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "commitment", - type: "bytes32", - }, - ], - name: "commit", - outputs: [], - stateMutability: "nonpayable", - type: "function", }, { - inputs: [ - { - internalType: "bytes32", - name: "commitment", - type: "bytes32", - }, - ], - name: "commitmentAt", - outputs: [ - { - internalType: "uint64", - name: "commitTime", - type: "uint64", - }, - ], - stateMutability: "view", type: "function", - }, - { + name: "revokeRoles", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", - }, - { - internalType: "uint256", - name: "roleBitmap", - type: "uint256", - }, - ], - name: "getAssigneeCount", - outputs: [ - { - internalType: "uint256", - name: "counts", - type: "uint256", - }, - { - internalType: "uint256", - name: "mask", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { internalType: "uint256", - name: "resource", - type: "uint256", }, { - internalType: "uint256", name: "roleBitmap", type: "uint256", + internalType: "uint256", }, { - internalType: "address", name: "account", type: "address", + internalType: "address", }, ], - name: "grantRoles", outputs: [ { - internalType: "bool", name: "", type: "bool", + internalType: "bool", }, ], stateMutability: "nonpayable", - type: "function", }, { + type: "function", + name: "revokeRootRoles", inputs: [ { - internalType: "uint256", name: "roleBitmap", type: "uint256", + internalType: "uint256", }, { - internalType: "address", name: "account", type: "address", + internalType: "address", }, ], - name: "grantRootRoles", outputs: [ { - internalType: "bool", name: "", type: "bool", + internalType: "bool", }, ], stateMutability: "nonpayable", - type: "function", }, { + type: "function", + name: "roleCount", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", - }, - { internalType: "uint256", - name: "roleBitmap", - type: "uint256", }, ], - name: "hasAssignees", outputs: [ { - internalType: "bool", name: "", - type: "bool", + type: "uint256", + internalType: "uint256", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "roles", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", - }, - { internalType: "uint256", - name: "roleBitmap", - type: "uint256", }, { - internalType: "address", name: "account", type: "address", + internalType: "address", }, ], - name: "hasRoles", outputs: [ { - internalType: "bool", name: "", - type: "bool", + type: "uint256", + internalType: "uint256", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "setRentPriceOracle", inputs: [ { - internalType: "uint256", - name: "roleBitmap", - type: "uint256", - }, - { - internalType: "address", - name: "account", + name: "oracle", type: "address", + internalType: "contract IRentPriceOracle", }, ], - name: "hasRootRoles", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool", - }, - ], - stateMutability: "view", - type: "function", + outputs: [], + stateMutability: "nonpayable", }, { + type: "function", + name: "supportsInterface", inputs: [ { - internalType: "string", - name: "label", - type: "string", + name: "interfaceId", + type: "bytes4", + internalType: "bytes4", }, ], - name: "isAvailable", outputs: [ { - internalType: "bool", name: "", type: "bool", + internalType: "bool", }, ], stateMutability: "view", - type: "function", }, { + type: "event", + name: "CommitmentMade", inputs: [ { - internalType: "contract IERC20", - name: "paymentToken", - type: "address", - }, - ], - name: "isPaymentToken", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool", + name: "commitment", + type: "bytes32", + indexed: false, + internalType: "bytes32", }, ], - stateMutability: "view", - type: "function", + anonymous: false, }, { + type: "event", + name: "EACRolesChanged", inputs: [ { - internalType: "string", - name: "label", - type: "string", + name: "resource", + type: "uint256", + indexed: true, + internalType: "uint256", }, - ], - name: "isValid", - outputs: [ { - internalType: "bool", - name: "", - type: "bool", + name: "account", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "oldRoleBitmap", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "newRoleBitmap", + type: "uint256", + indexed: false, + internalType: "uint256", }, ], - stateMutability: "view", - type: "function", + anonymous: false, }, { + type: "event", + name: "NameRegistered", inputs: [ { - internalType: "string", + name: "tokenId", + type: "uint256", + indexed: true, + internalType: "uint256", + }, + { name: "label", type: "string", + indexed: false, + internalType: "string", }, { - internalType: "address", name: "owner", type: "address", + indexed: false, + internalType: "address", }, { - internalType: "bytes32", - name: "secret", - type: "bytes32", - }, - { - internalType: "contract IRegistry", name: "subregistry", type: "address", + indexed: false, + internalType: "contract IRegistry", }, { - internalType: "address", name: "resolver", type: "address", + indexed: false, + internalType: "address", }, { - internalType: "uint64", name: "duration", type: "uint64", + indexed: false, + internalType: "uint64", + }, + { + name: "paymentToken", + type: "address", + indexed: false, + internalType: "contract IERC20", }, { - internalType: "bytes32", name: "referrer", type: "bytes32", + indexed: false, + internalType: "bytes32", }, - ], - name: "makeCommitment", - outputs: [ { - internalType: "bytes32", - name: "", - type: "bytes32", + name: "base", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "premium", + type: "uint256", + indexed: false, + internalType: "uint256", }, ], - stateMutability: "pure", - type: "function", + anonymous: false, }, { + type: "event", + name: "NameRenewed", inputs: [ { - internalType: "string", - name: "label", - type: "string", - }, - { - internalType: "address", - name: "owner", - type: "address", - }, - { - internalType: "bytes32", - name: "secret", - type: "bytes32", + name: "tokenId", + type: "uint256", + indexed: true, + internalType: "uint256", }, { - internalType: "contract IRegistry", - name: "subregistry", - type: "address", + name: "label", + type: "string", + indexed: false, + internalType: "string", }, { - internalType: "address", - name: "resolver", - type: "address", + name: "duration", + type: "uint64", + indexed: false, + internalType: "uint64", }, { - internalType: "uint64", - name: "duration", + name: "newExpiry", type: "uint64", + indexed: false, + internalType: "uint64", }, { - internalType: "contract IERC20", name: "paymentToken", type: "address", + indexed: false, + internalType: "contract IERC20", }, { - internalType: "bytes32", name: "referrer", type: "bytes32", + indexed: false, + internalType: "bytes32", }, - ], - name: "register", - outputs: [ { - internalType: "uint256", - name: "tokenId", + name: "base", type: "uint256", + indexed: false, + internalType: "uint256", }, ], - stateMutability: "nonpayable", - type: "function", + anonymous: false, }, { + type: "event", + name: "PaymentTokenAdded", inputs: [ { - internalType: "string", - name: "label", - type: "string", - }, - { - internalType: "uint64", - name: "duration", - type: "uint64", + name: "paymentToken", + type: "address", + indexed: true, + internalType: "contract IERC20", }, + ], + anonymous: false, + }, + { + type: "event", + name: "PaymentTokenRemoved", + inputs: [ { - internalType: "contract IERC20", name: "paymentToken", type: "address", + indexed: true, + internalType: "contract IERC20", }, + ], + anonymous: false, + }, + { + type: "event", + name: "RentPriceOracleChanged", + inputs: [ { - internalType: "bytes32", - name: "referrer", - type: "bytes32", + name: "oracle", + type: "address", + indexed: false, + internalType: "contract IRentPriceOracle", }, ], - name: "renew", - outputs: [], - stateMutability: "nonpayable", - type: "function", + anonymous: false, }, { + type: "error", + name: "CommitmentTooNew", inputs: [ { - internalType: "string", - name: "label", - type: "string", + name: "commitment", + type: "bytes32", + internalType: "bytes32", }, { - internalType: "address", - name: "owner", - type: "address", + name: "validFrom", + type: "uint64", + internalType: "uint64", }, { - internalType: "uint64", - name: "duration", + name: "blockTimestamp", type: "uint64", + internalType: "uint64", }, + ], + }, + { + type: "error", + name: "CommitmentTooOld", + inputs: [ { - internalType: "contract IERC20", - name: "paymentToken", - type: "address", + name: "commitment", + type: "bytes32", + internalType: "bytes32", }, - ], - name: "rentPrice", - outputs: [ { - internalType: "uint256", - name: "base", - type: "uint256", + name: "validTo", + type: "uint64", + internalType: "uint64", }, { - internalType: "uint256", - name: "premium", - type: "uint256", + name: "blockTimestamp", + type: "uint64", + internalType: "uint64", }, ], - stateMutability: "view", - type: "function", }, { - inputs: [], - name: "rentPriceOracle", - outputs: [ + type: "error", + name: "DurationTooShort", + inputs: [ { - internalType: "contract IRentPriceOracle", - name: "", - type: "address", + name: "duration", + type: "uint64", + internalType: "uint64", + }, + { + name: "minDuration", + type: "uint64", + internalType: "uint64", }, ], - stateMutability: "view", - type: "function", }, { + type: "error", + name: "EACCannotGrantRoles", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", + internalType: "uint256", }, { - internalType: "uint256", name: "roleBitmap", type: "uint256", + internalType: "uint256", }, { - internalType: "address", name: "account", type: "address", + internalType: "address", }, ], - name: "revokeRoles", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool", - }, - ], - stateMutability: "nonpayable", - type: "function", }, { + type: "error", + name: "EACCannotRevokeRoles", inputs: [ { + name: "resource", + type: "uint256", internalType: "uint256", + }, + { name: "roleBitmap", type: "uint256", + internalType: "uint256", }, { - internalType: "address", name: "account", type: "address", + internalType: "address", }, ], - name: "revokeRootRoles", - outputs: [ + }, + { + type: "error", + name: "EACInvalidAccount", + inputs: [], + }, + { + type: "error", + name: "EACInvalidRoleBitmap", + inputs: [ { - internalType: "bool", - name: "", - type: "bool", + name: "roleBitmap", + type: "uint256", + internalType: "uint256", }, ], - stateMutability: "nonpayable", - type: "function", }, { + type: "error", + name: "EACMaxAssignees", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", + internalType: "uint256", + }, + { + name: "role", + type: "uint256", + internalType: "uint256", }, ], - name: "roleCount", - outputs: [ + }, + { + type: "error", + name: "EACMinAssignees", + inputs: [ { + name: "resource", + type: "uint256", internalType: "uint256", - name: "", + }, + { + name: "role", type: "uint256", + internalType: "uint256", }, ], - stateMutability: "view", - type: "function", }, { + type: "error", + name: "EACRootResourceNotAllowed", + inputs: [], + }, + { + type: "error", + name: "EACUnauthorizedAccountRoles", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", + internalType: "uint256", + }, + { + name: "roleBitmap", + type: "uint256", + internalType: "uint256", }, { - internalType: "address", name: "account", type: "address", + internalType: "address", }, ], - name: "roles", - outputs: [ + }, + { + type: "error", + name: "InvalidOwner", + inputs: [], + }, + { + type: "error", + name: "MaxCommitmentAgeTooLow", + inputs: [], + }, + { + type: "error", + name: "NameIsAvailable", + inputs: [ { - internalType: "uint256", - name: "", - type: "uint256", + name: "label", + type: "string", + internalType: "string", }, ], - stateMutability: "view", - type: "function", }, { + type: "error", + name: "NameNotAvailable", inputs: [ { - internalType: "contract IRentPriceOracle", - name: "oracle", + name: "label", + type: "string", + internalType: "string", + }, + ], + }, + { + type: "error", + name: "NotValid", + inputs: [ + { + name: "label", + type: "string", + internalType: "string", + }, + ], + }, + { + type: "error", + name: "PaymentTokenNotSupported", + inputs: [ + { + name: "paymentToken", type: "address", + internalType: "contract IERC20", }, ], - name: "setRentPriceOracle", - outputs: [], - stateMutability: "nonpayable", - type: "function", }, { + type: "error", + name: "SafeERC20FailedOperation", inputs: [ { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4", + name: "token", + type: "address", + internalType: "address", }, ], - name: "supportsInterface", - outputs: [ + }, + { + type: "error", + name: "UnexpiredCommitmentExists", + inputs: [ { - internalType: "bool", - name: "", - type: "bool", + name: "commitment", + type: "bytes32", + internalType: "bytes32", }, ], - stateMutability: "view", - type: "function", }, ] as const satisfies Abi; diff --git a/packages/datasources/src/abis/ensv2/EnhancedAccessControl.ts b/packages/datasources/src/abis/ensv2/EnhancedAccessControl.ts index adc932208..e39127ead 100644 --- a/packages/datasources/src/abis/ensv2/EnhancedAccessControl.ts +++ b/packages/datasources/src/abis/ensv2/EnhancedAccessControl.ts @@ -2,437 +2,450 @@ import type { Abi } from "viem"; export const EnhancedAccessControl = [ { - inputs: [ + type: "function", + name: "HCA_FACTORY", + inputs: [], + outputs: [ { - internalType: "uint256", - name: "resource", - type: "uint256", + name: "", + type: "address", + internalType: "contract IHCAFactoryBasic", }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "ROOT_RESOURCE", + inputs: [], + outputs: [ { - internalType: "uint256", - name: "roleBitmap", + name: "", type: "uint256", - }, - { - internalType: "address", - name: "account", - type: "address", + internalType: "uint256", }, ], - name: "EACCannotGrantRoles", - type: "error", + stateMutability: "view", }, { + type: "function", + name: "getAssigneeCount", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", + internalType: "uint256", }, { - internalType: "uint256", name: "roleBitmap", type: "uint256", - }, - { - internalType: "address", - name: "account", - type: "address", + internalType: "uint256", }, ], - name: "EACCannotRevokeRoles", - type: "error", - }, - { - inputs: [], - name: "EACInvalidAccount", - type: "error", - }, - { - inputs: [ + outputs: [ { + name: "counts", + type: "uint256", internalType: "uint256", - name: "roleBitmap", + }, + { + name: "mask", type: "uint256", + internalType: "uint256", }, ], - name: "EACInvalidRoleBitmap", - type: "error", + stateMutability: "view", }, { + type: "function", + name: "grantRoles", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", + internalType: "uint256", }, { - internalType: "uint256", - name: "role", + name: "roleBitmap", type: "uint256", + internalType: "uint256", + }, + { + name: "account", + type: "address", + internalType: "address", }, ], - name: "EACMaxAssignees", - type: "error", + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "nonpayable", }, { + type: "function", + name: "grantRootRoles", inputs: [ { - internalType: "uint256", - name: "resource", + name: "roleBitmap", type: "uint256", + internalType: "uint256", }, { - internalType: "uint256", - name: "role", - type: "uint256", + name: "account", + type: "address", + internalType: "address", }, ], - name: "EACMinAssignees", - type: "error", - }, - { - inputs: [], - name: "EACRootResourceNotAllowed", - type: "error", + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "nonpayable", }, { + type: "function", + name: "hasAssignees", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", + internalType: "uint256", }, { - internalType: "uint256", name: "roleBitmap", type: "uint256", + internalType: "uint256", }, + ], + outputs: [ { - internalType: "address", - name: "account", - type: "address", + name: "", + type: "bool", + internalType: "bool", }, ], - name: "EACUnauthorizedAccountRoles", - type: "error", + stateMutability: "view", }, { - anonymous: false, + type: "function", + name: "hasRoles", inputs: [ { - indexed: true, - internalType: "uint256", name: "resource", type: "uint256", + internalType: "uint256", }, { - indexed: true, - internalType: "address", - name: "account", - type: "address", - }, - { - indexed: false, - internalType: "uint256", - name: "oldRoleBitmap", + name: "roleBitmap", type: "uint256", + internalType: "uint256", }, { - indexed: false, - internalType: "uint256", - name: "newRoleBitmap", - type: "uint256", + name: "account", + type: "address", + internalType: "address", }, ], - name: "EACRolesChanged", - type: "event", - }, - { - inputs: [], - name: "ROOT_RESOURCE", outputs: [ { - internalType: "uint256", name: "", - type: "uint256", + type: "bool", + internalType: "bool", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "hasRootRoles", inputs: [ { - internalType: "uint256", - name: "resource", + name: "roleBitmap", type: "uint256", + internalType: "uint256", }, { - internalType: "uint256", - name: "roleBitmap", - type: "uint256", + name: "account", + type: "address", + internalType: "address", }, ], - name: "getAssigneeCount", outputs: [ { - internalType: "uint256", - name: "counts", - type: "uint256", - }, - { - internalType: "uint256", - name: "mask", - type: "uint256", + name: "", + type: "bool", + internalType: "bool", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "revokeRoles", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", + internalType: "uint256", }, { - internalType: "uint256", name: "roleBitmap", type: "uint256", + internalType: "uint256", }, { - internalType: "address", name: "account", type: "address", + internalType: "address", }, ], - name: "grantRoles", outputs: [ { - internalType: "bool", name: "", type: "bool", + internalType: "bool", }, ], stateMutability: "nonpayable", - type: "function", }, { + type: "function", + name: "revokeRootRoles", inputs: [ { - internalType: "uint256", name: "roleBitmap", type: "uint256", + internalType: "uint256", }, { - internalType: "address", name: "account", type: "address", + internalType: "address", }, ], - name: "grantRootRoles", outputs: [ { - internalType: "bool", name: "", type: "bool", + internalType: "bool", }, ], stateMutability: "nonpayable", - type: "function", }, { + type: "function", + name: "roleCount", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", - }, - { internalType: "uint256", - name: "roleBitmap", - type: "uint256", }, ], - name: "hasAssignees", outputs: [ { - internalType: "bool", name: "", - type: "bool", + type: "uint256", + internalType: "uint256", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "roles", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", - }, - { internalType: "uint256", - name: "roleBitmap", - type: "uint256", }, { - internalType: "address", name: "account", type: "address", + internalType: "address", }, ], - name: "hasRoles", outputs: [ { - internalType: "bool", name: "", - type: "bool", + type: "uint256", + internalType: "uint256", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "supportsInterface", inputs: [ { - internalType: "uint256", - name: "roleBitmap", - type: "uint256", - }, - { - internalType: "address", - name: "account", - type: "address", + name: "interfaceId", + type: "bytes4", + internalType: "bytes4", }, ], - name: "hasRootRoles", outputs: [ { - internalType: "bool", name: "", type: "bool", + internalType: "bool", }, ], stateMutability: "view", - type: "function", }, { + type: "event", + name: "EACRolesChanged", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", - }, - { + indexed: true, internalType: "uint256", - name: "roleBitmap", - type: "uint256", }, { - internalType: "address", name: "account", type: "address", + indexed: true, + internalType: "address", }, - ], - name: "revokeRoles", - outputs: [ { - internalType: "bool", - name: "", - type: "bool", + name: "oldRoleBitmap", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "newRoleBitmap", + type: "uint256", + indexed: false, + internalType: "uint256", }, ], - stateMutability: "nonpayable", - type: "function", + anonymous: false, }, { + type: "error", + name: "EACCannotGrantRoles", inputs: [ { + name: "resource", + type: "uint256", internalType: "uint256", + }, + { name: "roleBitmap", type: "uint256", + internalType: "uint256", }, { - internalType: "address", name: "account", type: "address", + internalType: "address", }, ], - name: "revokeRootRoles", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool", - }, - ], - stateMutability: "nonpayable", - type: "function", }, { + type: "error", + name: "EACCannotRevokeRoles", inputs: [ { - internalType: "uint256", name: "resource", type: "uint256", + internalType: "uint256", }, - ], - name: "roleCount", - outputs: [ { - internalType: "uint256", - name: "", + name: "roleBitmap", type: "uint256", + internalType: "uint256", + }, + { + name: "account", + type: "address", + internalType: "address", }, ], - stateMutability: "view", - type: "function", }, { + type: "error", + name: "EACInvalidAccount", + inputs: [], + }, + { + type: "error", + name: "EACInvalidRoleBitmap", inputs: [ { + name: "roleBitmap", + type: "uint256", internalType: "uint256", + }, + ], + }, + { + type: "error", + name: "EACMaxAssignees", + inputs: [ + { name: "resource", type: "uint256", + internalType: "uint256", }, { - internalType: "address", - name: "account", - type: "address", + name: "role", + type: "uint256", + internalType: "uint256", }, ], - name: "roles", - outputs: [ + }, + { + type: "error", + name: "EACMinAssignees", + inputs: [ { + name: "resource", + type: "uint256", internalType: "uint256", - name: "", + }, + { + name: "role", type: "uint256", + internalType: "uint256", }, ], - stateMutability: "view", - type: "function", }, { + type: "error", + name: "EACRootResourceNotAllowed", + inputs: [], + }, + { + type: "error", + name: "EACUnauthorizedAccountRoles", inputs: [ { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4", + name: "resource", + type: "uint256", + internalType: "uint256", }, - ], - name: "supportsInterface", - outputs: [ { - internalType: "bool", - name: "", - type: "bool", + name: "roleBitmap", + type: "uint256", + internalType: "uint256", + }, + { + name: "account", + type: "address", + internalType: "address", }, ], - stateMutability: "view", - type: "function", }, ] as const satisfies Abi; diff --git a/packages/datasources/src/abis/ensv2/Registry.ts b/packages/datasources/src/abis/ensv2/Registry.ts index 6a70bb746..8e76e49b0 100644 --- a/packages/datasources/src/abis/ensv2/Registry.ts +++ b/packages/datasources/src/abis/ensv2/Registry.ts @@ -2,589 +2,1583 @@ import type { Abi } from "viem"; export const Registry = [ { - anonymous: false, + type: "constructor", + inputs: [ + { + name: "hcaFactory", + type: "address", + internalType: "contract IHCAFactoryBasic", + }, + { + name: "metadata", + type: "address", + internalType: "contract IRegistryMetadata", + }, + { + name: "ownerAddress", + type: "address", + internalType: "address", + }, + { + name: "ownerRoles", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "HCA_FACTORY", + inputs: [], + outputs: [ + { + name: "", + type: "address", + internalType: "contract IHCAFactoryBasic", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "METADATA_PROVIDER", + inputs: [], + outputs: [ + { + name: "", + type: "address", + internalType: "contract IRegistryMetadata", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "ROOT_RESOURCE", + inputs: [], + outputs: [ + { + name: "", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "balanceOf", + inputs: [ + { + name: "account", + type: "address", + internalType: "address", + }, + { + name: "id", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [ + { + name: "", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "balanceOfBatch", + inputs: [ + { + name: "accounts", + type: "address[]", + internalType: "address[]", + }, + { + name: "ids", + type: "uint256[]", + internalType: "uint256[]", + }, + ], + outputs: [ + { + name: "", + type: "uint256[]", + internalType: "uint256[]", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getAssigneeCount", + inputs: [ + { + name: "anyId", + type: "uint256", + internalType: "uint256", + }, + { + name: "roleBitmap", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [ + { + name: "counts", + type: "uint256", + internalType: "uint256", + }, + { + name: "mask", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getExpiry", + inputs: [ + { + name: "anyId", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [ + { + name: "", + type: "uint64", + internalType: "uint64", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getParent", + inputs: [], + outputs: [ + { + name: "parent", + type: "address", + internalType: "contract IRegistry", + }, + { + name: "label", + type: "string", + internalType: "string", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getResolver", + inputs: [ + { + name: "label", + type: "string", + internalType: "string", + }, + ], + outputs: [ + { + name: "", + type: "address", + internalType: "address", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getResource", + inputs: [ + { + name: "anyId", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [ + { + name: "", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getState", + inputs: [ + { + name: "anyId", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [ + { + name: "state", + type: "tuple", + internalType: "struct IPermissionedRegistry.State", + components: [ + { + name: "status", + type: "uint8", + internalType: "enum IPermissionedRegistry.Status", + }, + { + name: "expiry", + type: "uint64", + internalType: "uint64", + }, + { + name: "latestOwner", + type: "address", + internalType: "address", + }, + { + name: "tokenId", + type: "uint256", + internalType: "uint256", + }, + { + name: "resource", + type: "uint256", + internalType: "uint256", + }, + ], + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getStatus", + inputs: [ + { + name: "anyId", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [ + { + name: "", + type: "uint8", + internalType: "enum IPermissionedRegistry.Status", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getSubregistry", + inputs: [ + { + name: "label", + type: "string", + internalType: "string", + }, + ], + outputs: [ + { + name: "", + type: "address", + internalType: "contract IRegistry", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getTokenId", + inputs: [ + { + name: "anyId", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [ + { + name: "", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "grantRoles", + inputs: [ + { + name: "anyId", + type: "uint256", + internalType: "uint256", + }, + { + name: "roleBitmap", + type: "uint256", + internalType: "uint256", + }, + { + name: "account", + type: "address", + internalType: "address", + }, + ], + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "grantRootRoles", + inputs: [ + { + name: "roleBitmap", + type: "uint256", + internalType: "uint256", + }, + { + name: "account", + type: "address", + internalType: "address", + }, + ], + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "hasAssignees", + inputs: [ + { + name: "anyId", + type: "uint256", + internalType: "uint256", + }, + { + name: "roleBitmap", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "hasRoles", + inputs: [ + { + name: "anyId", + type: "uint256", + internalType: "uint256", + }, + { + name: "roleBitmap", + type: "uint256", + internalType: "uint256", + }, + { + name: "account", + type: "address", + internalType: "address", + }, + ], + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "hasRootRoles", + inputs: [ + { + name: "roleBitmap", + type: "uint256", + internalType: "uint256", + }, + { + name: "account", + type: "address", + internalType: "address", + }, + ], + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "isApprovedForAll", + inputs: [ + { + name: "account", + type: "address", + internalType: "address", + }, + { + name: "operator", + type: "address", + internalType: "address", + }, + ], + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "latestOwnerOf", + inputs: [ + { + name: "tokenId", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [ + { + name: "", + type: "address", + internalType: "address", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "ownerOf", + inputs: [ + { + name: "tokenId", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [ + { + name: "", + type: "address", + internalType: "address", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "register", + inputs: [ + { + name: "label", + type: "string", + internalType: "string", + }, + { + name: "owner", + type: "address", + internalType: "address", + }, + { + name: "registry", + type: "address", + internalType: "contract IRegistry", + }, + { + name: "resolver", + type: "address", + internalType: "address", + }, + { + name: "roleBitmap", + type: "uint256", + internalType: "uint256", + }, + { + name: "expiry", + type: "uint64", + internalType: "uint64", + }, + ], + outputs: [ + { + name: "tokenId", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "renew", + inputs: [ + { + name: "anyId", + type: "uint256", + internalType: "uint256", + }, + { + name: "newExpiry", + type: "uint64", + internalType: "uint64", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "revokeRoles", + inputs: [ + { + name: "anyId", + type: "uint256", + internalType: "uint256", + }, + { + name: "roleBitmap", + type: "uint256", + internalType: "uint256", + }, + { + name: "account", + type: "address", + internalType: "address", + }, + ], + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "revokeRootRoles", + inputs: [ + { + name: "roleBitmap", + type: "uint256", + internalType: "uint256", + }, + { + name: "account", + type: "address", + internalType: "address", + }, + ], + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "roleCount", + inputs: [ + { + name: "anyId", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [ + { + name: "", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "roles", + inputs: [ + { + name: "anyId", + type: "uint256", + internalType: "uint256", + }, + { + name: "account", + type: "address", + internalType: "address", + }, + ], + outputs: [ + { + name: "", + type: "uint256", + internalType: "uint256", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "safeBatchTransferFrom", inputs: [ { - indexed: true, + name: "from", + type: "address", + internalType: "address", + }, + { + name: "to", + type: "address", internalType: "address", - name: "account", + }, + { + name: "ids", + type: "uint256[]", + internalType: "uint256[]", + }, + { + name: "values", + type: "uint256[]", + internalType: "uint256[]", + }, + { + name: "data", + type: "bytes", + internalType: "bytes", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "safeTransferFrom", + inputs: [ + { + name: "from", type: "address", + internalType: "address", }, { - indexed: true, + name: "to", + type: "address", internalType: "address", + }, + { + name: "id", + type: "uint256", + internalType: "uint256", + }, + { + name: "value", + type: "uint256", + internalType: "uint256", + }, + { + name: "data", + type: "bytes", + internalType: "bytes", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "setApprovalForAll", + inputs: [ + { name: "operator", type: "address", + internalType: "address", }, { - indexed: false, - internalType: "bool", name: "approved", type: "bool", + internalType: "bool", }, ], - name: "ApprovalForAll", - type: "event", + outputs: [], + stateMutability: "nonpayable", }, { - anonymous: false, + type: "function", + name: "setParent", inputs: [ { - indexed: true, + name: "parent", + type: "address", + internalType: "contract IRegistry", + }, + { + name: "label", + type: "string", + internalType: "string", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "setResolver", + inputs: [ + { + name: "anyId", + type: "uint256", + internalType: "uint256", + }, + { + name: "resolver", + type: "address", + internalType: "address", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "setSubregistry", + inputs: [ + { + name: "anyId", + type: "uint256", + internalType: "uint256", + }, + { + name: "registry", + type: "address", + internalType: "contract IRegistry", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "supportsInterface", + inputs: [ + { + name: "interfaceId", + type: "bytes4", + internalType: "bytes4", + }, + ], + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "unregister", + inputs: [ + { + name: "anyId", + type: "uint256", internalType: "uint256", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "uri", + inputs: [ + { name: "tokenId", type: "uint256", + internalType: "uint256", }, + ], + outputs: [ { - indexed: false, - internalType: "uint64", - name: "newExpiry", - type: "uint64", + name: "", + type: "string", + internalType: "string", }, + ], + stateMutability: "view", + }, + { + type: "event", + name: "Approval", + inputs: [ { + name: "owner", + type: "address", indexed: true, internalType: "address", - name: "sender", + }, + { + name: "approved", type: "address", + indexed: true, + internalType: "address", + }, + { + name: "tokenId", + type: "uint256", + indexed: true, + internalType: "uint256", }, ], - name: "ExpiryUpdated", - type: "event", + anonymous: false, }, { + type: "event", + name: "ApprovalForAll", + inputs: [ + { + name: "account", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "operator", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "approved", + type: "bool", + indexed: false, + internalType: "bool", + }, + ], anonymous: false, + }, + { + type: "event", + name: "EACRolesChanged", inputs: [ { + name: "resource", + type: "uint256", + indexed: true, + internalType: "uint256", + }, + { + name: "account", + type: "address", indexed: true, + internalType: "address", + }, + { + name: "oldRoleBitmap", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "newRoleBitmap", + type: "uint256", + indexed: false, internalType: "uint256", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "ExpiryUpdated", + inputs: [ + { name: "tokenId", type: "uint256", + indexed: true, + internalType: "uint256", }, { + name: "newExpiry", + type: "uint64", indexed: true, - internalType: "bytes32", + internalType: "uint64", + }, + { + name: "sender", + type: "address", + indexed: true, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "LabelRegistered", + inputs: [ + { + name: "tokenId", + type: "uint256", + indexed: true, + internalType: "uint256", + }, + { name: "labelHash", type: "bytes32", + indexed: true, + internalType: "bytes32", }, { - indexed: false, - internalType: "string", name: "label", type: "string", + indexed: false, + internalType: "string", }, { - indexed: false, - internalType: "address", name: "owner", type: "address", + indexed: false, + internalType: "address", }, { - indexed: false, - internalType: "uint64", name: "expiry", type: "uint64", + indexed: false, + internalType: "uint64", }, { - indexed: true, - internalType: "address", name: "sender", type: "address", + indexed: true, + internalType: "address", }, ], - name: "NameRegistered", - type: "event", + anonymous: false, }, { - anonymous: false, + type: "event", + name: "LabelReserved", inputs: [ { - indexed: true, - internalType: "uint256", name: "tokenId", type: "uint256", + indexed: true, + internalType: "uint256", }, { - indexed: true, - internalType: "bytes32", name: "labelHash", type: "bytes32", + indexed: true, + internalType: "bytes32", }, { - indexed: false, - internalType: "string", name: "label", type: "string", + indexed: false, + internalType: "string", }, { - indexed: false, - internalType: "uint64", name: "expiry", type: "uint64", + indexed: false, + internalType: "uint64", }, { - indexed: true, - internalType: "address", name: "sender", type: "address", + indexed: true, + internalType: "address", }, ], - name: "NameReserved", - type: "event", + anonymous: false, }, { - anonymous: false, + type: "event", + name: "LabelUnregistered", inputs: [ { - indexed: true, - internalType: "uint256", name: "tokenId", type: "uint256", + indexed: true, + internalType: "uint256", }, { - indexed: true, - internalType: "address", name: "sender", type: "address", + indexed: true, + internalType: "address", }, ], - name: "NameUnregistered", - type: "event", + anonymous: false, }, { - anonymous: false, + type: "event", + name: "ParentUpdated", inputs: [ { - indexed: true, - internalType: "contract IRegistry", name: "parent", type: "address", + indexed: true, + internalType: "contract IRegistry", }, { - indexed: false, - internalType: "string", name: "label", type: "string", + indexed: false, + internalType: "string", }, { - indexed: true, - internalType: "address", name: "sender", type: "address", + indexed: true, + internalType: "address", }, ], - name: "ParentUpdated", - type: "event", + anonymous: false, }, { - anonymous: false, + type: "event", + name: "ResolverUpdated", inputs: [ { - indexed: true, - internalType: "uint256", name: "tokenId", type: "uint256", + indexed: true, + internalType: "uint256", }, { - indexed: false, - internalType: "address", name: "resolver", type: "address", - }, - { indexed: true, internalType: "address", + }, + { name: "sender", type: "address", + indexed: true, + internalType: "address", }, ], - name: "ResolverUpdated", - type: "event", + anonymous: false, }, { - anonymous: false, + type: "event", + name: "SubregistryUpdated", inputs: [ { - indexed: true, - internalType: "uint256", name: "tokenId", type: "uint256", + indexed: true, + internalType: "uint256", }, { - indexed: false, - internalType: "contract IRegistry", name: "subregistry", type: "address", + indexed: true, + internalType: "contract IRegistry", }, { - indexed: true, - internalType: "address", name: "sender", type: "address", + indexed: true, + internalType: "address", }, ], - name: "SubregistryUpdated", - type: "event", + anonymous: false, }, { - anonymous: false, + type: "event", + name: "TokenRegenerated", inputs: [ { + name: "oldTokenId", + type: "uint256", indexed: true, internalType: "uint256", - name: "oldTokenId", + }, + { + name: "newTokenId", type: "uint256", + indexed: true, + internalType: "uint256", }, + ], + anonymous: false, + }, + { + type: "event", + name: "TokenResource", + inputs: [ { + name: "tokenId", + type: "uint256", indexed: true, internalType: "uint256", - name: "newTokenId", + }, + { + name: "resource", type: "uint256", + indexed: true, + internalType: "uint256", }, ], - name: "TokenRegenerated", - type: "event", + anonymous: false, }, { - anonymous: false, + type: "event", + name: "TransferBatch", inputs: [ { - indexed: true, - internalType: "address", name: "operator", type: "address", - }, - { indexed: true, internalType: "address", - name: "from", - type: "address", }, { + name: "from", + type: "address", indexed: true, internalType: "address", + }, + { name: "to", type: "address", + indexed: true, + internalType: "address", }, { - indexed: false, - internalType: "uint256[]", name: "ids", type: "uint256[]", - }, - { indexed: false, internalType: "uint256[]", + }, + { name: "values", type: "uint256[]", + indexed: false, + internalType: "uint256[]", }, ], - name: "TransferBatch", - type: "event", + anonymous: false, }, { - anonymous: false, + type: "event", + name: "TransferSingle", inputs: [ { - indexed: true, - internalType: "address", name: "operator", type: "address", - }, - { indexed: true, internalType: "address", + }, + { name: "from", type: "address", + indexed: true, + internalType: "address", }, { + name: "to", + type: "address", indexed: true, internalType: "address", - name: "to", + }, + { + name: "id", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "value", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "URI", + inputs: [ + { + name: "value", + type: "string", + indexed: false, + internalType: "string", + }, + { + name: "id", + type: "uint256", + indexed: true, + internalType: "uint256", + }, + ], + anonymous: false, + }, + { + type: "error", + name: "CannotReduceExpiry", + inputs: [ + { + name: "oldExpiry", + type: "uint64", + internalType: "uint64", + }, + { + name: "newExpiry", + type: "uint64", + internalType: "uint64", + }, + ], + }, + { + type: "error", + name: "CannotSetPastExpiry", + inputs: [ + { + name: "expiry", + type: "uint64", + internalType: "uint64", + }, + ], + }, + { + type: "error", + name: "EACCannotGrantRoles", + inputs: [ + { + name: "resource", + type: "uint256", + internalType: "uint256", + }, + { + name: "roleBitmap", + type: "uint256", + internalType: "uint256", + }, + { + name: "account", type: "address", + internalType: "address", + }, + ], + }, + { + type: "error", + name: "EACCannotRevokeRoles", + inputs: [ + { + name: "resource", + type: "uint256", + internalType: "uint256", }, { - indexed: false, - internalType: "uint256", - name: "id", + name: "roleBitmap", type: "uint256", + internalType: "uint256", }, { - indexed: false, - internalType: "uint256", - name: "value", - type: "uint256", + name: "account", + type: "address", + internalType: "address", }, ], - name: "TransferSingle", - type: "event", }, { - anonymous: false, + type: "error", + name: "EACInvalidAccount", + inputs: [], + }, + { + type: "error", + name: "EACInvalidRoleBitmap", inputs: [ { - indexed: false, - internalType: "string", - name: "value", - type: "string", - }, - { - indexed: true, - internalType: "uint256", - name: "id", + name: "roleBitmap", type: "uint256", + internalType: "uint256", }, ], - name: "URI", - type: "event", }, { + type: "error", + name: "EACMaxAssignees", inputs: [ { - internalType: "address", - name: "account", - type: "address", + name: "resource", + type: "uint256", + internalType: "uint256", }, { - internalType: "uint256", - name: "id", + name: "role", type: "uint256", + internalType: "uint256", }, ], - name: "balanceOf", - outputs: [ + }, + { + type: "error", + name: "EACMinAssignees", + inputs: [ { + name: "resource", + type: "uint256", internalType: "uint256", - name: "", + }, + { + name: "role", type: "uint256", + internalType: "uint256", }, ], - stateMutability: "view", - type: "function", }, { + type: "error", + name: "EACRootResourceNotAllowed", + inputs: [], + }, + { + type: "error", + name: "EACUnauthorizedAccountRoles", inputs: [ { - internalType: "address[]", - name: "accounts", - type: "address[]", + name: "resource", + type: "uint256", + internalType: "uint256", }, { - internalType: "uint256[]", - name: "ids", - type: "uint256[]", + name: "roleBitmap", + type: "uint256", + internalType: "uint256", }, - ], - name: "balanceOfBatch", - outputs: [ { - internalType: "uint256[]", - name: "", - type: "uint256[]", + name: "account", + type: "address", + internalType: "address", }, ], - stateMutability: "view", - type: "function", }, { - inputs: [], - name: "getParent", - outputs: [ + type: "error", + name: "ERC1155InsufficientBalance", + inputs: [ { - internalType: "contract IRegistry", - name: "parent", + name: "sender", type: "address", + internalType: "address", }, { - internalType: "string", - name: "label", - type: "string", + name: "balance", + type: "uint256", + internalType: "uint256", + }, + { + name: "needed", + type: "uint256", + internalType: "uint256", + }, + { + name: "tokenId", + type: "uint256", + internalType: "uint256", }, ], - stateMutability: "view", - type: "function", }, { + type: "error", + name: "ERC1155InvalidApprover", inputs: [ { - internalType: "string", - name: "label", - type: "string", - }, - ], - name: "getResolver", - outputs: [ - { - internalType: "address", - name: "", + name: "approver", type: "address", + internalType: "address", }, ], - stateMutability: "view", - type: "function", }, { + type: "error", + name: "ERC1155InvalidArrayLength", inputs: [ { - internalType: "string", - name: "label", - type: "string", + name: "idsLength", + type: "uint256", + internalType: "uint256", }, - ], - name: "getSubregistry", - outputs: [ { - internalType: "contract IRegistry", - name: "", - type: "address", + name: "valuesLength", + type: "uint256", + internalType: "uint256", }, ], - stateMutability: "view", - type: "function", }, { + type: "error", + name: "ERC1155InvalidOperator", inputs: [ { - internalType: "address", - name: "account", - type: "address", - }, - { - internalType: "address", name: "operator", type: "address", + internalType: "address", }, ], - name: "isApprovedForAll", - outputs: [ - { - internalType: "bool", - name: "", - type: "bool", - }, - ], - stateMutability: "view", - type: "function", }, { + type: "error", + name: "ERC1155InvalidReceiver", inputs: [ { - internalType: "uint256", - name: "id", - type: "uint256", + name: "receiver", + type: "address", + internalType: "address", }, ], - name: "ownerOf", - outputs: [ + }, + { + type: "error", + name: "ERC1155InvalidSender", + inputs: [ { - internalType: "address", - name: "owner", + name: "sender", type: "address", + internalType: "address", }, ], - stateMutability: "view", - type: "function", }, { + type: "error", + name: "ERC1155MissingApprovalForAll", inputs: [ { - internalType: "address", - name: "from", + name: "operator", type: "address", - }, - { internalType: "address", - name: "to", - type: "address", - }, - { - internalType: "uint256[]", - name: "ids", - type: "uint256[]", - }, - { - internalType: "uint256[]", - name: "values", - type: "uint256[]", }, { - internalType: "bytes", - name: "data", - type: "bytes", + name: "owner", + type: "address", + internalType: "address", }, ], - name: "safeBatchTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function", }, { + type: "error", + name: "LabelAlreadyRegistered", inputs: [ { - internalType: "address", - name: "from", - type: "address", + name: "label", + type: "string", + internalType: "string", }, + ], + }, + { + type: "error", + name: "LabelAlreadyReserved", + inputs: [ { - internalType: "address", - name: "to", - type: "address", + name: "label", + type: "string", + internalType: "string", }, + ], + }, + { + type: "error", + name: "LabelExpired", + inputs: [ { - internalType: "uint256", - name: "id", + name: "tokenId", type: "uint256", - }, - { internalType: "uint256", - name: "value", - type: "uint256", - }, - { - internalType: "bytes", - name: "data", - type: "bytes", }, ], - name: "safeTransferFrom", - outputs: [], - stateMutability: "nonpayable", - type: "function", }, { + type: "error", + name: "LabelIsEmpty", + inputs: [], + }, + { + type: "error", + name: "LabelIsTooLong", inputs: [ { - internalType: "address", - name: "operator", - type: "address", - }, - { - internalType: "bool", - name: "approved", - type: "bool", + name: "label", + type: "string", + internalType: "string", }, ], - name: "setApprovalForAll", - outputs: [], - stateMutability: "nonpayable", - type: "function", }, { + type: "error", + name: "TransferDisallowed", inputs: [ { - internalType: "bytes4", - name: "interfaceId", - type: "bytes4", + name: "tokenId", + type: "uint256", + internalType: "uint256", }, - ], - name: "supportsInterface", - outputs: [ { - internalType: "bool", - name: "", - type: "bool", + name: "from", + type: "address", + internalType: "address", }, ], - stateMutability: "view", - type: "function", }, ] as const satisfies Abi; diff --git a/packages/datasources/src/abis/ensv2/UniversalResolverV2.ts b/packages/datasources/src/abis/ensv2/UniversalResolverV2.ts index 060784e0c..827cac3f3 100644 --- a/packages/datasources/src/abis/ensv2/UniversalResolverV2.ts +++ b/packages/datasources/src/abis/ensv2/UniversalResolverV2.ts @@ -2,856 +2,875 @@ import type { Abi } from "viem"; export const UniversalResolverV2 = [ { + type: "constructor", inputs: [ { - internalType: "contract IRegistry", name: "root", type: "address", + internalType: "contract IRegistry", }, { - internalType: "contract IGatewayProvider", name: "batchGatewayProvider", type: "address", + internalType: "contract IGatewayProvider", }, ], stateMutability: "nonpayable", - type: "constructor", - }, - { - inputs: [ - { - internalType: "bytes", - name: "dns", - type: "bytes", - }, - ], - name: "DNSDecodingFailed", - type: "error", - }, - { - inputs: [ - { - internalType: "string", - name: "ens", - type: "string", - }, - ], - name: "DNSEncodingFailed", - type: "error", - }, - { - inputs: [], - name: "EmptyAddress", - type: "error", - }, - { - inputs: [ - { - internalType: "uint16", - name: "status", - type: "uint16", - }, - { - internalType: "string", - name: "message", - type: "string", - }, - ], - name: "HttpError", - type: "error", - }, - { - inputs: [], - name: "InvalidBatchGatewayResponse", - type: "error", - }, - { - inputs: [], - name: "LabelIsEmpty", - type: "error", - }, - { - inputs: [ - { - internalType: "string", - name: "label", - type: "string", - }, - ], - name: "LabelIsTooLong", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "sender", - type: "address", - }, - { - internalType: "string[]", - name: "urls", - type: "string[]", - }, - { - internalType: "bytes", - name: "callData", - type: "bytes", - }, - { - internalType: "bytes4", - name: "callbackFunction", - type: "bytes4", - }, - { - internalType: "bytes", - name: "extraData", - type: "bytes", - }, - ], - name: "OffchainLookup", - type: "error", - }, - { - inputs: [ - { - internalType: "uint256", - name: "offset", - type: "uint256", - }, - { - internalType: "uint256", - name: "length", - type: "uint256", - }, - ], - name: "OffsetOutOfBoundsError", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes", - name: "errorData", - type: "bytes", - }, - ], - name: "ResolverError", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes", - name: "name", - type: "bytes", - }, - { - internalType: "address", - name: "resolver", - type: "address", - }, - ], - name: "ResolverNotContract", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes", - name: "name", - type: "bytes", - }, - ], - name: "ResolverNotFound", - type: "error", - }, - { - inputs: [ - { - internalType: "string", - name: "primary", - type: "string", - }, - { - internalType: "bytes", - name: "primaryAddress", - type: "bytes", - }, - ], - name: "ReverseAddressMismatch", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes4", - name: "selector", - type: "bytes4", - }, - ], - name: "UnsupportedResolverProfile", - type: "error", }, { - inputs: [], + type: "function", name: "ROOT_REGISTRY", + inputs: [], outputs: [ { - internalType: "contract IRegistry", name: "", type: "address", + internalType: "contract IRegistry", }, ], stateMutability: "view", - type: "function", }, { - inputs: [], + type: "function", name: "batchGatewayProvider", + inputs: [], outputs: [ { - internalType: "contract IGatewayProvider", name: "", type: "address", + internalType: "contract IGatewayProvider", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "ccipBatch", inputs: [ { + name: "batch", + type: "tuple", + internalType: "struct CCIPBatcher.Batch", components: [ { + name: "lookups", + type: "tuple[]", + internalType: "struct CCIPBatcher.Lookup[]", components: [ { - internalType: "address", name: "target", type: "address", + internalType: "address", }, { - internalType: "bytes", name: "call", type: "bytes", + internalType: "bytes", }, { - internalType: "bytes", name: "data", type: "bytes", + internalType: "bytes", }, { - internalType: "uint256", name: "flags", type: "uint256", + internalType: "uint256", }, ], - internalType: "struct CCIPBatcher.Lookup[]", - name: "lookups", - type: "tuple[]", }, { - internalType: "string[]", name: "gateways", type: "string[]", + internalType: "string[]", }, ], - internalType: "struct CCIPBatcher.Batch", - name: "batch", - type: "tuple", }, ], - name: "ccipBatch", outputs: [ { + name: "", + type: "tuple", + internalType: "struct CCIPBatcher.Batch", components: [ { + name: "lookups", + type: "tuple[]", + internalType: "struct CCIPBatcher.Lookup[]", components: [ { - internalType: "address", name: "target", type: "address", + internalType: "address", }, { - internalType: "bytes", name: "call", type: "bytes", + internalType: "bytes", }, { - internalType: "bytes", name: "data", type: "bytes", + internalType: "bytes", }, { - internalType: "uint256", name: "flags", type: "uint256", + internalType: "uint256", }, ], - internalType: "struct CCIPBatcher.Lookup[]", - name: "lookups", - type: "tuple[]", }, { - internalType: "string[]", name: "gateways", type: "string[]", + internalType: "string[]", }, ], - internalType: "struct CCIPBatcher.Batch", - name: "", - type: "tuple", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "ccipBatchCallback", inputs: [ { - internalType: "bytes", name: "response", type: "bytes", + internalType: "bytes", }, { - internalType: "bytes", name: "extraData", type: "bytes", + internalType: "bytes", }, ], - name: "ccipBatchCallback", outputs: [ { + name: "batch", + type: "tuple", + internalType: "struct CCIPBatcher.Batch", components: [ { + name: "lookups", + type: "tuple[]", + internalType: "struct CCIPBatcher.Lookup[]", components: [ { - internalType: "address", name: "target", type: "address", + internalType: "address", }, { - internalType: "bytes", name: "call", type: "bytes", + internalType: "bytes", }, { - internalType: "bytes", name: "data", type: "bytes", + internalType: "bytes", }, { - internalType: "uint256", name: "flags", type: "uint256", + internalType: "uint256", }, ], - internalType: "struct CCIPBatcher.Lookup[]", - name: "lookups", - type: "tuple[]", }, { - internalType: "string[]", name: "gateways", type: "string[]", + internalType: "string[]", }, ], - internalType: "struct CCIPBatcher.Batch", - name: "batch", - type: "tuple", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "ccipReadCallback", inputs: [ { - internalType: "bytes", name: "response", type: "bytes", + internalType: "bytes", }, { - internalType: "bytes", name: "extraData", type: "bytes", + internalType: "bytes", }, ], - name: "ccipReadCallback", outputs: [], stateMutability: "view", - type: "function", }, { + type: "function", + name: "findCanonicalName", inputs: [ { - internalType: "contract IRegistry", name: "registry", type: "address", + internalType: "contract IRegistry", }, ], - name: "findCanonicalName", outputs: [ { - internalType: "bytes", name: "", type: "bytes", + internalType: "bytes", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "findCanonicalRegistry", inputs: [ { - internalType: "bytes", name: "name", type: "bytes", + internalType: "bytes", }, ], - name: "findCanonicalRegistry", outputs: [ { - internalType: "contract IRegistry", name: "", type: "address", + internalType: "contract IRegistry", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "findExactRegistry", inputs: [ { - internalType: "bytes", name: "name", type: "bytes", + internalType: "bytes", }, ], + outputs: [ + { + name: "", + type: "address", + internalType: "contract IRegistry", + }, + ], + stateMutability: "view", + }, + { + type: "function", name: "findRegistries", + inputs: [ + { + name: "name", + type: "bytes", + internalType: "bytes", + }, + ], outputs: [ { - internalType: "contract IRegistry[]", name: "", type: "address[]", + internalType: "contract IRegistry[]", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "findResolver", inputs: [ { - internalType: "bytes", name: "name", type: "bytes", + internalType: "bytes", }, ], - name: "findResolver", outputs: [ { - internalType: "address", name: "resolver", type: "address", + internalType: "address", }, { - internalType: "bytes32", name: "node", type: "bytes32", + internalType: "bytes32", }, { - internalType: "uint256", name: "offset", type: "uint256", + internalType: "uint256", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "requireResolver", inputs: [ { - internalType: "bytes", name: "name", type: "bytes", + internalType: "bytes", }, ], - name: "requireResolver", outputs: [ { + name: "info", + type: "tuple", + internalType: "struct AbstractUniversalResolver.ResolverInfo", components: [ { - internalType: "bytes", name: "name", type: "bytes", + internalType: "bytes", }, { - internalType: "uint256", name: "offset", type: "uint256", + internalType: "uint256", }, { - internalType: "bytes32", name: "node", type: "bytes32", + internalType: "bytes32", }, { - internalType: "address", name: "resolver", type: "address", + internalType: "address", }, { - internalType: "bool", name: "extended", type: "bool", + internalType: "bool", }, ], - internalType: "struct AbstractUniversalResolver.ResolverInfo", - name: "info", - type: "tuple", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "resolve", inputs: [ { - internalType: "bytes", name: "name", type: "bytes", + internalType: "bytes", }, { - internalType: "bytes", name: "data", type: "bytes", + internalType: "bytes", }, ], - name: "resolve", outputs: [ { - internalType: "bytes", name: "", type: "bytes", + internalType: "bytes", }, { - internalType: "address", name: "", type: "address", + internalType: "address", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "resolveBatchCallback", inputs: [ { - internalType: "bytes", name: "response", type: "bytes", + internalType: "bytes", }, { - internalType: "bytes", name: "extraData", type: "bytes", + internalType: "bytes", }, ], - name: "resolveBatchCallback", outputs: [], stateMutability: "view", - type: "function", }, { + type: "function", + name: "resolveCallback", inputs: [ { - internalType: "bytes", name: "response", type: "bytes", + internalType: "bytes", }, { - internalType: "bytes", name: "extraData", type: "bytes", + internalType: "bytes", }, ], - name: "resolveCallback", outputs: [ { - internalType: "bytes", name: "", type: "bytes", + internalType: "bytes", }, { - internalType: "address", name: "", type: "address", + internalType: "address", }, ], stateMutability: "pure", - type: "function", }, { + type: "function", + name: "resolveDirectCallback", inputs: [ { - internalType: "bytes", name: "response", type: "bytes", + internalType: "bytes", }, { - internalType: "bytes", name: "extraData", type: "bytes", + internalType: "bytes", }, ], - name: "resolveDirectCallback", outputs: [], stateMutability: "view", - type: "function", }, { + type: "function", + name: "resolveDirectCallbackError", inputs: [ { - internalType: "bytes", name: "response", type: "bytes", + internalType: "bytes", }, { - internalType: "bytes", name: "", type: "bytes", + internalType: "bytes", }, ], - name: "resolveDirectCallbackError", outputs: [], stateMutability: "pure", - type: "function", }, { + type: "function", + name: "resolveWithGateways", inputs: [ { - internalType: "bytes", name: "name", type: "bytes", + internalType: "bytes", }, { - internalType: "bytes", name: "data", type: "bytes", + internalType: "bytes", }, { - internalType: "string[]", name: "gateways", type: "string[]", + internalType: "string[]", }, ], - name: "resolveWithGateways", outputs: [ { - internalType: "bytes", name: "result", type: "bytes", + internalType: "bytes", }, { - internalType: "address", name: "resolver", type: "address", + internalType: "address", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "resolveWithResolver", inputs: [ { - internalType: "address", name: "resolver", type: "address", + internalType: "address", }, { - internalType: "bytes", name: "name", type: "bytes", + internalType: "bytes", }, { - internalType: "bytes", name: "data", type: "bytes", + internalType: "bytes", }, { - internalType: "string[]", name: "gateways", type: "string[]", + internalType: "string[]", }, ], - name: "resolveWithResolver", outputs: [ { - internalType: "bytes", name: "", type: "bytes", + internalType: "bytes", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "reverse", inputs: [ { - internalType: "bytes", name: "lookupAddress", type: "bytes", + internalType: "bytes", }, { - internalType: "uint256", name: "coinType", type: "uint256", + internalType: "uint256", }, ], - name: "reverse", outputs: [ { - internalType: "string", name: "", type: "string", + internalType: "string", }, { - internalType: "address", name: "", type: "address", + internalType: "address", }, { - internalType: "address", name: "", type: "address", + internalType: "address", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "reverseAddressCallback", inputs: [ { - internalType: "bytes", name: "response", type: "bytes", + internalType: "bytes", }, { - internalType: "bytes", name: "extraData", type: "bytes", + internalType: "bytes", }, ], - name: "reverseAddressCallback", outputs: [ { - internalType: "string", name: "primary", type: "string", + internalType: "string", }, { - internalType: "address", name: "resolver", type: "address", + internalType: "address", }, { - internalType: "address", name: "reverseResolver", type: "address", + internalType: "address", }, ], stateMutability: "pure", - type: "function", }, { + type: "function", + name: "reverseNameCallback", inputs: [ { - internalType: "bytes", name: "response", type: "bytes", + internalType: "bytes", }, { - internalType: "bytes", name: "extraData", type: "bytes", + internalType: "bytes", }, ], - name: "reverseNameCallback", outputs: [ { - internalType: "string", name: "primary", type: "string", + internalType: "string", }, { - internalType: "address", name: "", type: "address", + internalType: "address", }, { - internalType: "address", name: "", type: "address", + internalType: "address", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "reverseWithGateways", inputs: [ { - internalType: "bytes", name: "lookupAddress", type: "bytes", + internalType: "bytes", }, { - internalType: "uint256", name: "coinType", type: "uint256", + internalType: "uint256", }, { - internalType: "string[]", name: "gateways", type: "string[]", + internalType: "string[]", }, ], - name: "reverseWithGateways", outputs: [ { - internalType: "string", name: "primary", type: "string", + internalType: "string", }, { - internalType: "address", name: "resolver", type: "address", + internalType: "address", }, { - internalType: "address", name: "reverseResolver", type: "address", + internalType: "address", }, ], stateMutability: "view", - type: "function", }, { + type: "function", + name: "supportsInterface", inputs: [ { - internalType: "bytes4", name: "interfaceId", type: "bytes4", + internalType: "bytes4", }, ], - name: "supportsInterface", outputs: [ { - internalType: "bool", name: "", type: "bool", + internalType: "bool", }, ], stateMutability: "view", - type: "function", + }, + { + type: "error", + name: "DNSDecodingFailed", + inputs: [ + { + name: "dns", + type: "bytes", + internalType: "bytes", + }, + ], + }, + { + type: "error", + name: "DNSEncodingFailed", + inputs: [ + { + name: "ens", + type: "string", + internalType: "string", + }, + ], + }, + { + type: "error", + name: "EmptyAddress", + inputs: [], + }, + { + type: "error", + name: "HttpError", + inputs: [ + { + name: "status", + type: "uint16", + internalType: "uint16", + }, + { + name: "message", + type: "string", + internalType: "string", + }, + ], + }, + { + type: "error", + name: "InvalidBatchGatewayResponse", + inputs: [], + }, + { + type: "error", + name: "LabelIsEmpty", + inputs: [], + }, + { + type: "error", + name: "LabelIsTooLong", + inputs: [ + { + name: "label", + type: "string", + internalType: "string", + }, + ], + }, + { + type: "error", + name: "OffchainLookup", + inputs: [ + { + name: "sender", + type: "address", + internalType: "address", + }, + { + name: "urls", + type: "string[]", + internalType: "string[]", + }, + { + name: "callData", + type: "bytes", + internalType: "bytes", + }, + { + name: "callbackFunction", + type: "bytes4", + internalType: "bytes4", + }, + { + name: "extraData", + type: "bytes", + internalType: "bytes", + }, + ], + }, + { + type: "error", + name: "OffsetOutOfBoundsError", + inputs: [ + { + name: "offset", + type: "uint256", + internalType: "uint256", + }, + { + name: "length", + type: "uint256", + internalType: "uint256", + }, + ], + }, + { + type: "error", + name: "ResolverError", + inputs: [ + { + name: "errorData", + type: "bytes", + internalType: "bytes", + }, + ], + }, + { + type: "error", + name: "ResolverNotContract", + inputs: [ + { + name: "name", + type: "bytes", + internalType: "bytes", + }, + { + name: "resolver", + type: "address", + internalType: "address", + }, + ], + }, + { + type: "error", + name: "ResolverNotFound", + inputs: [ + { + name: "name", + type: "bytes", + internalType: "bytes", + }, + ], + }, + { + type: "error", + name: "ReverseAddressMismatch", + inputs: [ + { + name: "primary", + type: "string", + internalType: "string", + }, + { + name: "primaryAddress", + type: "bytes", + internalType: "bytes", + }, + ], + }, + { + type: "error", + name: "UnsupportedResolverProfile", + inputs: [ + { + name: "selector", + type: "bytes4", + internalType: "bytes4", + }, + ], }, ] as const satisfies Abi; diff --git a/packages/datasources/src/ens-test-env.ts b/packages/datasources/src/ens-test-env.ts index 6d6aac9df..b27f4b904 100644 --- a/packages/datasources/src/ens-test-env.ts +++ b/packages/datasources/src/ens-test-env.ts @@ -61,13 +61,13 @@ export default { // NOTE: named BaseRegistrarImplementation in devnet BaseRegistrar: { abi: root_BaseRegistrar, - address: "0xcd8a1c3ba11cf5ecfa6267617243239504a98d90", + address: "0x8a791620dd6260079bf849dc5567adc3f2fdc318", startBlock: 0, }, // NOTE: named LegacyETHRegistrarController in devnet LegacyEthRegistrarController: { abi: root_LegacyEthRegistrarController, - address: "0xd8a5a9b31c3c0232e196d518e89fd8bf83acad43", + address: "0xfbc22278a96299d91d41c453234d97b4f5eb9b2d", startBlock: 0, }, // NOTE: named WrappedETHRegistrarController in devnet @@ -79,7 +79,7 @@ export default { // NOTE: named ETHRegistrarController in devnet UnwrappedEthRegistrarController: { abi: root_UnwrappedEthRegistrarController, - address: "0x36b58f5c1969b7b6591d752ea6f5486d069010ab", + address: "0x1c85638e118b37167e9298c2268758e058ddfda0", startBlock: 0, }, // NOTE: not in devnet, set to zeroAddress @@ -90,18 +90,18 @@ export default { }, NameWrapper: { abi: root_NameWrapper, - address: "0xcbeaf3bde82155f56486fb5a1072cb8baaf547cc", + address: "0x5081a39b8a5f0e35a8d959395a630b68b74dd30f", startBlock: 0, }, UniversalResolver: { abi: UniversalResolverV1, - address: "0xd84379ceae14aa33c123af12424a37803f885889", + address: "0x5067457698fd6fa1c6964e416b3f42713513b3dd", startBlock: 0, }, // NOTE: named UniversalResolverV2 in devnet UniversalResolverV2: { abi: UniversalResolverV2, - address: "0x162a433068f51e18b7d13932f27e66a3f99e6890", + address: "0x8198f5d8f8cffe8f9c413d98a0a55aeb8ab9fbb7", startBlock: 0, }, }, @@ -120,12 +120,12 @@ export default { }, ETHRegistry: { abi: Registry, - address: "0x9e545e3c0baab3e08cdfd552c960a1050f373042", + address: "0x8f86403a4de0bb5791fa46b8e795c547942fe4cf", startBlock: 0, }, ETHRegistrar: { abi: ETHRegistrar, - address: "0x5f3f1dbd7b74c6b46e8c44f98792a1daf8d69154", + address: "0x4c4a2f8c81640e47606d3fd77b353e87ba015584", startBlock: 0, }, }, @@ -136,28 +136,28 @@ export default { contracts: { DefaultReverseRegistrar: { abi: StandaloneReverseRegistrar, - address: "0x998abeb3e57409262ae5b751f60747921b33613e", + address: "0x4c5859f0f772848b2d91f1d83e2fe57935348029", startBlock: 0, }, // NOTE: named DefaultReverseResolver in devnet DefaultReverseResolver3: { abi: ResolverABI, - address: "0x4826533b4897376654bb4d4ad88b7fafd0c98528", + address: "0x5f3f1dbd7b74c6b46e8c44f98792a1daf8d69154", startBlock: 0, }, // NOTE: named LegacyPublicResolver in devnet DefaultPublicResolver4: { abi: ResolverABI, - address: "0x4ee6ecad1c2dae9f525404de8555724e3c35d07b", + address: "0x86a2ee8faf9a840f7a2c64ca3d51209f9a02081d", startBlock: 0, }, // NOTE: named PublicResolver in devnet DefaultPublicResolver5: { abi: ResolverABI, - address: "0xbec49fa140acaa83533fb00a2bb19bddd0290f25", + address: "0xa4899d35897033b927acfcf422bc745916139776", startBlock: 0, }, }, diff --git a/packages/ensdb-sdk/src/ensindexer-abstract/ensv2.schema.ts b/packages/ensdb-sdk/src/ensindexer-abstract/ensv2.schema.ts index aba2dc025..bb67d283f 100644 --- a/packages/ensdb-sdk/src/ensindexer-abstract/ensv2.schema.ts +++ b/packages/ensdb-sdk/src/ensindexer-abstract/ensv2.schema.ts @@ -326,7 +326,8 @@ export const registrationType = onchainEnum("RegistrationType", [ "NameWrapper", "BaseRegistrar", "ThreeDNS", - "ENSv2Registry", + "ENSv2RegistryRegistration", + "ENSv2RegistryReservation", ]); export const registration = onchainTable( @@ -352,10 +353,13 @@ export const registration = onchainTable( registrarChainId: t.integer().notNull().$type(), registrarAddress: t.hex().notNull().$type
(), - // references registrant + // may reference a registrant registrantId: t.hex().$type
(), - // may have a referrer + // may reference an unregistrant + unregistrantId: t.hex().$type
(), + + // may have referrer data referrer: t.hex().$type(), // may have fuses (NameWrapper, Wrapped BaseRegistrar) @@ -403,6 +407,13 @@ export const registration_relations = relations(registration, ({ one, many }) => relationName: "registrant", }), + // has one unregistrant + unregistrant: one(account, { + fields: [registration.unregistrantId], + references: [account.id], + relationName: "unregistrant", + }), + // has many renewals renewals: many(renewal), diff --git a/packages/ensnode-sdk/src/graphql-api/example-queries.ts b/packages/ensnode-sdk/src/graphql-api/example-queries.ts index eb625bd63..28801ab21 100644 --- a/packages/ensnode-sdk/src/graphql-api/example-queries.ts +++ b/packages/ensnode-sdk/src/graphql-api/example-queries.ts @@ -31,7 +31,7 @@ const ENS_TEST_ENV_V2_ETH_REGISTRAR = maybeGetDatasourceContract( const DEVNET_DEPLOYER = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; const DEVNET_OWNER = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"; // biome-ignore lint/correctness/noUnusedVariables: keeping it around for the future -const DEVNET_USER = "0x90F79bf6EB2c4f870365E785982E1f101E93b906"; +const DEVNET_USER = "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC"; const VITALIK_ADDRESS = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"; diff --git a/packages/ensnode-sdk/src/rpc/index.ts b/packages/ensnode-sdk/src/rpc/index.ts index 157a5f395..8403bdafa 100644 --- a/packages/ensnode-sdk/src/rpc/index.ts +++ b/packages/ensnode-sdk/src/rpc/index.ts @@ -1,3 +1,2 @@ export * from "./eip-165"; -export * from "./is-dedicated-resolver"; export * from "./is-extended-resolver"; diff --git a/packages/ensnode-sdk/src/rpc/is-dedicated-resolver.ts b/packages/ensnode-sdk/src/rpc/is-dedicated-resolver.ts deleted file mode 100644 index 9cd904b5d..000000000 --- a/packages/ensnode-sdk/src/rpc/is-dedicated-resolver.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { makeSupportsInterfaceReader } from "./eip-165"; - -/** - * DedicatedResolver InterfaceId - * @see https://github.com/ensdomains/contracts-v2/blob/main/contracts/src/resolver/interfaces/IDedicatedResolverSetters.sol - */ -const IDedicatedResolverInterfaceId = "0x92349baa"; - -/** - * Determines whether a Resolver contract supports ENSIP-10. - */ -export const isDedicatedResolver = makeSupportsInterfaceReader(IDedicatedResolverInterfaceId); diff --git a/packages/integration-test-env/README.md b/packages/integration-test-env/README.md index 0677653d8..5eb0320fb 100644 --- a/packages/integration-test-env/README.md +++ b/packages/integration-test-env/README.md @@ -6,12 +6,11 @@ Integration test environment orchestration for ENSNode. Spins up the full ENSNod The current devnet image is pinned to: - ``` -ghcr.io/ensdomains/contracts-v2:main-cb8e11c +ghcr.io/ensdomains/contracts-v2:main-e8696c6 ``` -Update the `DEVNET_IMAGE` constant in the orchestrator source to change the devnet version. +via the `docker-compose.yml` at the monorepo root. ## How It Works @@ -22,16 +21,106 @@ The orchestrator runs a 6-phase pipeline: 3. **ENSIndexer** — starts from source, waits for health 4. **Indexing** — polls until omnichain status reaches "Following" or "Completed" 5. **ENSApi** — starts from source, waits for health -6. **Integration tests** — runs `pnpm test:integration` at monorepo root +6. **Integration tests** — runs `pnpm test:integration` ## Usage +### Automated + ```sh pnpm start ``` Works both in CI and locally — just make sure the required ports are available (8545, 8000, 3223, 42069, 4334). +### Manual (local development) + +When developing, it's useful to run each service individually so you can restart or iterate on a single piece without tearing down the whole stack. + +#### 1. Start the devnet + +```sh +docker compose up devnet +``` + +Runs the ENS contracts-v2 devnet on port 8545. + +#### 2. Start Postgres + +You may have Postgres running any which way you want, for example with brew services: + +```sh +brew services start postgresql@17 +``` + +or with the local docker compose: + +```sh +docker compose up postgres +``` + +#### 3. Start ENSRainbow + +Run via docker compose: + +```sh +docker compose up ensrainbow +``` + +Or run it on the host machine from the repo root: + +```sh +cd apps/ensrainbow && pnpm dev +``` + +with environment variables: + +```env +LOG_LEVEL=error +DB_SCHEMA_VERSION=3 +LABEL_SET_ID=ens-test-env +LABEL_SET_VERSION=0 +``` + +#### 4. Start ENSIndexer + +```sh +cd apps/ensindexer && pnpm dev +``` + +with environment variables: + +```env +DATABASE_SCHEMA=ensindexer_0 +NAMESPACE=ens-test-env +PLUGINS=ensv2,protocol-acceleration +``` + +`DATABASE_SCHEMA` can be any valid Postgres schema name — just make sure ENSApi uses the same value. + +#### 5. Start ENSApi + +```sh +cd apps/ensapi && pnpm dev +``` + +with environment variables: + +```env +DATABASE_URL=postgresql://ensnode:ensnode@localhost:5432/ensnode +ENSINDEXER_SCHEMA_NAME=ensindexer_0 +``` + +`ENSINDEXER_SCHEMA_NAME` must match the `DATABASE_SCHEMA` used by ENSIndexer above. + +#### 6. Run Integration Tests + +Finally, you can run vitest on the integration tests using: + +```sh +pnpm test:integration +``` + ## License Licensed under the MIT License. See [LICENSE](./LICENSE). diff --git a/packages/integration-test-env/package.json b/packages/integration-test-env/package.json index 10fdc216f..97c10db21 100644 --- a/packages/integration-test-env/package.json +++ b/packages/integration-test-env/package.json @@ -5,13 +5,14 @@ "type": "module", "description": "Integration test environment orchestration for ENSNode", "scripts": { - "start": "CI=1 tsx src/orchestrator.ts" + "start": "CI=1 tsx src/orchestrator.ts", + "typecheck": "tsc --noEmit" }, "dependencies": { + "@ensnode/shared-configs": "workspace:*", "@ensnode/datasources": "workspace:*", "@ensnode/ensdb-sdk": "workspace:*", "@ensnode/ensnode-sdk": "workspace:*", - "@testcontainers/postgresql": "^11.12.0", "execa": "^9.6.1", "testcontainers": "^11.12.0", "tsx": "^4.7.1" diff --git a/packages/integration-test-env/src/orchestrator.ts b/packages/integration-test-env/src/orchestrator.ts index 659679261..f462531a1 100644 --- a/packages/integration-test-env/src/orchestrator.ts +++ b/packages/integration-test-env/src/orchestrator.ts @@ -5,15 +5,16 @@ * monorepo-level integration tests, then tears everything down. * * Phases: - * 1. Postgres (testcontainers, dynamic port) + devnet (fixed ports 8545/8000) — parallel + * 1. Postgres + devnet via docker-compose (testcontainers DockerComposeEnvironment) * 2. Download pre-built ENSRainbow LevelDB, extract, start ENSRainbow from source * 3. Start ENSIndexer, wait for omnichain-following / omnichain-completed * 4. Start ENSApi * 5. Run `pnpm test:integration` at the monorepo root * * Design decisions: - * - testcontainers for Postgres (dynamic port, built-in health check) and devnet - * (fixed ports required — ensTestEnvChain hardcodes localhost:8545). + * - Postgres and devnet are started from the root docker-compose.yml via + * testcontainers DockerComposeEnvironment, ensuring the orchestrator always + * uses the same images and configuration defined there. * - execa for child process management — automatic cleanup on parent exit, * forceKillAfterDelay (10s SIGKILL fallback), env inherited from parent. * - Services run from source (pnpm start/serve) rather than Docker so that @@ -30,9 +31,12 @@ import { mkdirSync } from "node:fs"; import { resolve } from "node:path"; -import { PostgreSqlContainer, type StartedPostgreSqlContainer } from "@testcontainers/postgresql"; import { execaSync, type ResultPromise, execa as spawn } from "execa"; -import { GenericContainer, type StartedTestContainer, Wait } from "testcontainers"; +import { + DockerComposeEnvironment, + type StartedDockerComposeEnvironment, + Wait, +} from "testcontainers"; import { ENSNamespaceIds } from "@ensnode/datasources"; import { OmnichainIndexingStatusIds } from "@ensnode/ensnode-sdk"; @@ -42,23 +46,18 @@ const ENSRAINBOW_DIR = resolve(MONOREPO_ROOT, "apps/ensrainbow"); const ENSINDEXER_DIR = resolve(MONOREPO_ROOT, "apps/ensindexer"); const ENSAPI_DIR = resolve(MONOREPO_ROOT, "apps/ensapi"); -// Docker images -const POSTGRES_IMAGE = "postgres:17"; -const DEVNET_IMAGE = "ghcr.io/ensdomains/contracts-v2:main-cb8e11c"; - -// Ports (devnet ports must be fixed — ensTestEnvChain hardcodes localhost:8545) -const DEVNET_RPC_PORT = 8545; -const DEVNET_HEALTH_PORT = 8000; +// Ports const ENSRAINBOW_PORT = 3223; const ENSINDEXER_PORT = 42069; const ENSAPI_PORT = 4334; // Shared config const ENSRAINBOW_URL = `http://localhost:${ENSRAINBOW_PORT}`; +const ENSINDEXER_SCHEMA_NAME = "ensindexer_integration_test"; // Track resources for cleanup const subprocesses: ResultPromise[] = []; -const containers: (StartedTestContainer | StartedPostgreSqlContainer)[] = []; +let composeEnvironment: StartedDockerComposeEnvironment | undefined; // Abort flag — set when a spawned service crashes let aborted = false; @@ -95,12 +94,12 @@ async function cleanup() { } log("All child processes stopped"); - for (const container of containers) { + if (composeEnvironment) { try { - await container.stop(); + await composeEnvironment.down(); } catch (error) { logError( - `Failed to stop container during cleanup: ${ + `Failed to stop compose environment during cleanup: ${ error instanceof Error ? error.message : String(error) }`, ); @@ -231,42 +230,24 @@ function logVersions() { log(` Node.js: ${process.version}`); log(` pnpm: ${execaSync("pnpm", ["--version"]).stdout.trim()}`); log(` Docker: ${execaSync("docker", ["--version"]).stdout.trim()}`); - log(` Postgres image: ${POSTGRES_IMAGE}`); - log(` Devnet image: ${DEVNET_IMAGE}`); } async function main() { log("Starting integration test environment..."); logVersions(); - // Phase 1: Start Postgres + Devnet in parallel + // Phase 1: Start Postgres + Devnet via docker-compose log("Starting Postgres and devnet..."); - const postgresPromise = new PostgreSqlContainer(POSTGRES_IMAGE) - .withDatabase("ensnode") - .withUsername("postgres") - .withPassword("password") - .start() - .then((c) => { - containers.push(c); - return c; - }); - const devnetPromise = new GenericContainer(DEVNET_IMAGE) - .withEnvironment({ ANVIL_IP_ADDR: "0.0.0.0" }) - .withExposedPorts( - { container: DEVNET_RPC_PORT, host: DEVNET_RPC_PORT }, - { container: DEVNET_HEALTH_PORT, host: DEVNET_HEALTH_PORT }, - ) - .withCommand(["./script/runDevnet.ts", "--testNames"]) + composeEnvironment = await new DockerComposeEnvironment(MONOREPO_ROOT, "docker-compose.yml") + .withWaitStrategy("devnet", Wait.forHealthCheck()) + .withWaitStrategy("postgres", Wait.forListeningPorts()) .withStartupTimeout(120_000) - .withWaitStrategy(Wait.forHttp("/health", DEVNET_HEALTH_PORT)) - .start() - .then((c) => { - containers.push(c); - return c; - }); - const [postgres] = await Promise.all([postgresPromise, devnetPromise]); - const DATABASE_URL = postgres.getConnectionUri(); - log(`Postgres is ready (port ${postgres.getPort()})`); + .up(["postgres", "devnet"]); + + const postgresContainer = composeEnvironment.getContainer("postgres"); + const postgresPort = postgresContainer.getMappedPort(5432); + const DATABASE_URL = `postgresql://postgres:password@localhost:${postgresPort}/postgres`; + log(`Postgres is ready (port ${postgresPort})`); log("Devnet is ready"); // Phase 2: Download ENSRainbow database and start from source @@ -317,8 +298,6 @@ async function main() { await waitForHealth(`http://localhost:${ENSRAINBOW_PORT}/health`, 30_000, "ENSRainbow"); // Phase 3: Start ENSIndexer - const ENSINDEXER_SCHEMA_NAME = "ensindexer_0"; - log("Starting ENSIndexer..."); spawnService( "pnpm", diff --git a/packages/integration-test-env/tsconfig.json b/packages/integration-test-env/tsconfig.json new file mode 100644 index 000000000..d6e0b230a --- /dev/null +++ b/packages/integration-test-env/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "@ensnode/shared-configs/tsconfig.lib.json", + "include": ["src/**/*"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3bb29a6c8..f693c35fe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -979,9 +979,9 @@ importers: '@ensnode/ensnode-sdk': specifier: workspace:* version: link:../ensnode-sdk - '@testcontainers/postgresql': - specifier: ^11.12.0 - version: 11.12.0 + '@ensnode/shared-configs': + specifier: workspace:* + version: link:../shared-configs execa: specifier: ^9.6.1 version: 9.6.1 @@ -4279,9 +4279,6 @@ packages: '@tanstack/virtual-core@3.13.12': resolution: {integrity: sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA==} - '@testcontainers/postgresql@11.12.0': - resolution: {integrity: sha512-w4ZK0H+WIYBUBk57H9wCSxPMSMZUNsFpx2MZAX4iru0Aevz9HFWDfAhFLAu+/SwsHtEJUD7XfWUDlqBGC3OF0Q==} - '@testing-library/dom@10.4.1': resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} @@ -13091,15 +13088,6 @@ snapshots: '@tanstack/virtual-core@3.13.12': {} - '@testcontainers/postgresql@11.12.0': - dependencies: - testcontainers: 11.12.0 - transitivePeerDependencies: - - bare-abort-controller - - bare-buffer - - react-native-b4a - - supports-color - '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.29.0