diff --git a/abis/SchemaRegistry.json b/abis/SchemaRegistry.json new file mode 100644 index 0000000..44a030b --- /dev/null +++ b/abis/SchemaRegistry.json @@ -0,0 +1 @@ +[{"inputs":[],"name":"AlreadyExists","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"uid","type":"bytes32"},{"indexed":false,"internalType":"address","name":"registerer","type":"address"}],"name":"Registered","type":"event"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"uid","type":"bytes32"}],"name":"getSchema","outputs":[{"components":[{"internalType":"bytes32","name":"uid","type":"bytes32"},{"internalType":"contract ISchemaResolver","name":"resolver","type":"address"},{"internalType":"bool","name":"revocable","type":"bool"},{"internalType":"string","name":"schema","type":"string"}],"internalType":"struct SchemaRecord","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"schema","type":"string"},{"internalType":"contract ISchemaResolver","name":"resolver","type":"address"},{"internalType":"bool","name":"revocable","type":"bool"}],"name":"register","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"}] diff --git a/ponder.config.ts b/ponder.config.ts index 2c85814..3af358c 100644 --- a/ponder.config.ts +++ b/ponder.config.ts @@ -2,19 +2,45 @@ import type { PonderConfig } from "@ponder/core"; export const config: PonderConfig = { networks: [ + // { + // name: "sepolia", + // chainId: 11155111, + // rpcUrl: process.env.PONDER_RPC_URL_11155111, + // }, { - name: "sepolia", - chainId: 11155111, - rpcUrl: process.env.PONDER_RPC_URL_11155111, + name: "mainnet", + chainId: 1, + rpcUrl: process.env.PONDER_RPC_URL_1, }, ], contracts: [ + // { + // name: "EAS", + // network: "sepolia", + // abi: "./abis/EAS.json", + // address: "0xc2679fbd37d54388ce493f1db75320d236e1815e", + // startBlock: 2958571, + // }, + // { + // name: "SchemaRegistry", + // network: "sepolia", + // abi: "./abis/SchemaRegistry.json", + // address: "0x0a7e2ff54e76b8e6659aedc9103fb21c038050d0", + // startBlock: 2958571, + // }, { name: "EAS", - network: "sepolia", + network: "mainnet", abi: "./abis/EAS.json", - address: "0xc2679fbd37d54388ce493f1db75320d236e1815e", - startBlock: 2958571, + address: "0xa1207f3bba224e2c9c3c6d5af63d0eb1582ce587", + startBlock: 16756728, + }, + { + name: "SchemaRegistry", + network: "mainnet", + abi: "./abis/SchemaRegistry.json", + address: "0xa7b39296258348c78294f95b872b282326a97bdf", + startBlock: 16756728, }, ], }; diff --git a/schema.graphql b/schema.graphql index b30ba12..2b444a6 100644 --- a/schema.graphql +++ b/schema.graphql @@ -1,4 +1,23 @@ -type ExampleEntity @entity { +type Attestation @entity { id: String! - name: String! + data: Bytes! + schema: Schema + recipient: Bytes! # address + attester: Bytes! # address + time: BigInt! + expirationTime: BigInt! + revocationTime: BigInt! + refUID: Bytes! + revoked: Boolean! + txid: Bytes! +} + +type Schema @entity { + id: String! + schema: String! + creator: String! # address + resolver: String! # address + time: BigInt! + revocable: Boolean! + txid: Bytes! } diff --git a/src/EAS.ts b/src/EAS.ts index 4909574..173752d 100644 --- a/src/EAS.ts +++ b/src/EAS.ts @@ -1,9 +1,53 @@ import { ponder } from "@/generated"; ponder.on("EAS:Attested", async ({ event, context }) => { - console.log(event.params); + console.log("Attested event received!"); + const { Attestation } = context.entities; + + let entity = await Attestation.findUnique({ id: event.params.uid }); + + if (entity == null) { + const attestation = await context.contracts.EAS.getAttestation( + event.params.uid + ); + + console.log("creating attestation", attestation); + + await Attestation.create({ + id: event.params.uid, + data: { + data: attestation.data, + time: attestation.time, + expirationTime: attestation.expirationTime, + revocationTime: attestation.revocationTime, + refUID: attestation.refUID, + txid: event.transaction.hash, + revoked: false, + attester: attestation.attester, + recipient: attestation.recipient, + schema: attestation.schema, + }, + }); + + console.log(`Attestation ${event.params.uid} created!`); + } }); ponder.on("EAS:Revoked", async ({ event, context }) => { - console.log(event.params); + const { Attestation } = context.entities; + + let entity = await Attestation.findUnique({ id: event.params.uid }); + + if (!entity) { + return; + } + + await Attestation.update({ + id: event.params.uid, + data: { + revoked: true, + }, + }); + + console.log(`Attestation ${event.params.uid} revoked!`); }); diff --git a/src/SchemaRegistry.ts b/src/SchemaRegistry.ts new file mode 100644 index 0000000..e0b07bb --- /dev/null +++ b/src/SchemaRegistry.ts @@ -0,0 +1,27 @@ +import { ponder } from "@/generated"; + +ponder.on("SchemaRegistry:Registered", async ({ event, context }) => { + const { Schema } = context.entities; + + let entity = await Schema.findUnique({ id: event.params.uid }); + + if (entity == null) { + const schema = await context.contracts.SchemaRegistry.getSchema( + event.params.uid + ); + + await Schema.create({ + id: event.params.uid, + data: { + creator: event.transaction.from, + schema: schema.schema, + resolver: schema.resolver, + time: event.block.timestamp, + txid: event.transaction.hash, + revocable: schema.revocable, + }, + }); + + console.log(`Attestation ${event.params.uid} created!`); + } +});