Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into fix/make-registration…
Browse files Browse the repository at this point in the history
…-id-unique
  • Loading branch information
tk-o committed Jan 28, 2025
2 parents a63db45 + 2a7d24b commit f1254dc
Show file tree
Hide file tree
Showing 21 changed files with 1,063 additions and 335 deletions.
6 changes: 5 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@
},
"[json]": {
"editor.defaultFormatter": "biomejs.biome"
}
},
"[jsonc]": {
"editor.defaultFormatter": "biomejs.biome"
},
"typescript.tsdk": "node_modules/typescript/lib"
}
2 changes: 2 additions & 0 deletions apps/ensnode/docs/V2.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ in the subgraph implementation, resolver handlers must upsert resolvers because

resolvers should be keyed by `(chainId, address)` and manage a mapping of records for a node, to be more protocol-centric. `coinTypes` and `texts` keys & values should be fully indexed (if possible — intentionally ignored in the subgraph because of some historical reason...)

> Yes, when it comes to all forms of key -> value pairs that comprise resolver records, the ENS Subgraph only indexes the keys and not the values. The motivation for this comes from a concern that some apps might improperly decide to use the ENS Subgraph as a source of truth for resolver record values, rather than ENS protocol standards for how resolver record values should be dynamically looked up. A naive implementation that considers the ENS Subgraph as a source of truth for these can cause a lot of problems.
### registrar

the subgraph implements all of the BaseRegistrar, EthRegistrarController, and EthRegistrarControllerOld logic together
Expand Down
6 changes: 3 additions & 3 deletions apps/ensnode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@
},
"dependencies": {
"@ensdomains/ensjs": "^4.0.2",
"ponder-schema": "workspace:*",
"ensnode-utils": "workspace:*",
"ponder-subgraph-api": "workspace:*",
"hono": "catalog:",
"ponder": "catalog:",
"ponder-schema": "workspace:*",
"ponder-subgraph-api": "workspace:*",
"ts-deepmerge": "^7.0.2",
"viem": "catalog:"
},
"devDependencies": {
"@namehash/shared-configs": "workspace:",
"@biomejs/biome": "catalog:",
"@namehash/shared-configs": "workspace:",
"@types/node": "catalog:",
"typescript": "catalog:",
"vitest": "catalog:"
Expand Down
42 changes: 41 additions & 1 deletion apps/ensnode/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,44 @@ import { graphql as subgraphGraphQL } from "ponder-subgraph-api/middleware";
ponder.use("/", ponderGraphQL());

// use our custom graphql middleware at /subgraph
ponder.use("/subgraph", subgraphGraphQL({ schema }));
ponder.use(
"/subgraph",
subgraphGraphQL({
schema,

// describes the polymorphic (interface) relationships in the schema
polymorphicConfig: {
types: {
DomainEvent: [
schema.transfer,
schema.newOwner,
schema.newResolver,
schema.newTTL,
schema.wrappedTransfer,
schema.nameWrapped,
schema.nameUnwrapped,
schema.fusesSet,
schema.expiryExtended,
],
RegistrationEvent: [schema.nameRegistered, schema.nameRenewed, schema.nameTransferred],
ResolverEvent: [
schema.addrChanged,
schema.multicoinAddrChanged,
schema.nameChanged,
schema.abiChanged,
schema.pubkeyChanged,
schema.textChanged,
schema.contenthashChanged,
schema.interfaceChanged,
schema.authorisationChanged,
schema.versionChanged,
],
},
fields: {
"Domain.events": "DomainEvent",
"Registration.events": "RegistrationEvent",
"Resolver.events": "ResolverEvent",
},
},
}),
);
97 changes: 50 additions & 47 deletions apps/ensnode/src/handlers/NameWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { type Context, type Event, type EventNames } from "ponder:registry";
import { type Context } from "ponder:registry";
import schema from "ponder:schema";
import { checkPccBurned } from "@ensdomains/ensjs/utils";
import { decodeDNSPacketBytes, tokenIdToLabel } from "ensnode-utils/subname-helpers";
import type { Node } from "ensnode-utils/types";
import { type Address, type Hex, hexToBytes, namehash } from "viem";
import { upsertAccount } from "../lib/db-helpers";
import { sharedEventValues, upsertAccount } from "../lib/db-helpers";
import { bigintMax } from "../lib/helpers";
import { makeEventId } from "../lib/ids";
import { EventWithArgs } from "../lib/ponder-helpers";
import type { OwnedName } from "../lib/types";

// if the wrappedDomain has PCC set in fuses, set domain's expiryDate to the greatest of the two
Expand All @@ -33,7 +34,7 @@ async function materializeDomainExpiryDate(context: Context, node: Node) {

async function handleTransfer(
context: Context,
event: Event<EventNames>,
event: EventWithArgs,
eventId: string,
tokenId: bigint,
to: Address,
Expand Down Expand Up @@ -64,7 +65,13 @@ async function handleTransfer(
ownerId: to,
});

// TODO: log WrappedTransfer
// log DomainEvent
await context.db.insert(schema.wrappedTransfer).values({
...sharedEventValues(event),
id: eventId, // NOTE: override the shared id in this case, to account for TransferBatch
domainId: node,
ownerId: to,
});
}

export const makeNameWrapperHandlers = (ownedName: OwnedName) => {
Expand All @@ -76,15 +83,13 @@ export const makeNameWrapperHandlers = (ownedName: OwnedName) => {
event,
}: {
context: Context;
event: {
args: {
node: Node;
owner: Hex;
fuses: number;
expiry: bigint;
name: Hex;
};
};
event: EventWithArgs<{
node: Node;
owner: Hex;
fuses: number;
expiry: bigint;
name: Hex;
}>;
}) {
const { node, owner, fuses, expiry } = event.args;

Expand All @@ -111,20 +116,23 @@ export const makeNameWrapperHandlers = (ownedName: OwnedName) => {
// materialize domain expiryDate
await materializeDomainExpiryDate(context, node);

// TODO: log NameWrapped
// log DomainEvent
await context.db.insert(schema.nameWrapped).values({
...sharedEventValues(event),
domainId: node,
name,
fuses,
ownerId: owner,
expiryDate: expiry,
});
},

async handleNameUnwrapped({
context,
event,
}: {
context: Context;
event: {
args: {
node: Node;
owner: Hex;
};
};
event: EventWithArgs<{ node: Node; owner: Hex }>;
}) {
const { node, owner } = event.args;

Expand All @@ -140,20 +148,20 @@ export const makeNameWrapperHandlers = (ownedName: OwnedName) => {
// delete the WrappedDomain
await context.db.delete(schema.wrappedDomain, { id: node });

// TODO: log NameUnwrapped
// log DomainEvent
await context.db.insert(schema.nameUnwrapped).values({
...sharedEventValues(event),
domainId: node,
ownerId: owner,
});
},

async handleFusesSet({
context,
event,
}: {
context: Context;
event: {
args: {
node: Node;
fuses: number;
};
};
event: EventWithArgs<{ node: Node; fuses: number }>;
}) {
const { node, fuses } = event.args;

Expand All @@ -170,19 +178,19 @@ export const makeNameWrapperHandlers = (ownedName: OwnedName) => {
await materializeDomainExpiryDate(context, node);
}

// TODO: log FusesBurned event
// log DomainEvent
await context.db.insert(schema.fusesSet).values({
...sharedEventValues(event),
domainId: node,
fuses,
});
},
async handleExpiryExtended({
context,
event,
}: {
context: Context;
event: {
args: {
node: Node;
expiry: bigint;
};
};
event: EventWithArgs<{ node: Node; expiry: bigint }>;
}) {
const { node, expiry } = event.args;

Expand All @@ -199,19 +207,19 @@ export const makeNameWrapperHandlers = (ownedName: OwnedName) => {
await materializeDomainExpiryDate(context, node);
}

// TODO: log ExpiryExtended
// log DomainEvent
await context.db.insert(schema.expiryExtended).values({
...sharedEventValues(event),
domainId: node,
expiryDate: expiry,
});
},
async handleTransferSingle({
context,
event,
}: {
context: Context;
event: Event<EventNames> & {
args: {
id: bigint;
to: Hex;
};
};
event: EventWithArgs<{ id: bigint; to: Hex }>;
}) {
await handleTransfer(
context,
Expand All @@ -226,12 +234,7 @@ export const makeNameWrapperHandlers = (ownedName: OwnedName) => {
event,
}: {
context: Context;
event: Event<EventNames> & {
args: {
ids: readonly bigint[];
to: Hex;
};
};
event: EventWithArgs<{ ids: readonly bigint[]; to: Hex }>;
}) {
for (const [i, id] of event.args.ids.entries()) {
await handleTransfer(
Expand Down
Loading

0 comments on commit f1254dc

Please sign in to comment.