Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type CoingeckoSupportedChainId =
| 42220
| 1088;

const CHAIN_DATA_VERSION = "83";
const CHAIN_DATA_VERSION = "86";
const IPFS_DATA_VERSION = "1";
const PRICE_DATA_VERSION = "1";

Expand Down Expand Up @@ -368,6 +368,12 @@ const CHAINS: Chain[] = [
address: "0xCd5AbD09ee34BA604795F7f69413caf20ee0Ab60",
fromBlock: 5100681,
},
// Gitcoin Attestation Network
{
contractName: "GitcoinAttestationNetwork/GitcoinGrantsResolver",
address: "0xBAa70bbAB3C4a7265f879bb3658336DE893b8582",
fromBlock: 6746370,
},
],
},
{
Expand Down Expand Up @@ -711,6 +717,12 @@ const CHAINS: Chain[] = [
address: "0x1133eA7Af70876e64665ecD07C0A0476d09465a1",
fromBlock: 146498081,
},
// Gitcoin Attestation Network
// {
// contractName: "GitcoinAttestationNetwork/GitcoinGrantsResolver",
// address: "0x0",
// fromBlock: 0,
// },
],
},
{
Expand Down
5 changes: 5 additions & 0 deletions src/database/changeset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
NewLegacyProject,
NewApplicationPayout,
NewIpfsData,
NewAttestationData,
} from "./schema.js";

export type DataChange =
Expand Down Expand Up @@ -145,4 +146,8 @@ export type DataChange =
| {
type: "InsertIpfsData";
ipfs: NewIpfsData;
}
| {
type: "InsertAttestation";
attestation: NewAttestationData;
};
34 changes: 34 additions & 0 deletions src/database/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
LegacyProjectTable,
ApplicationPayout,
IpfsDataTable,
AttestationTable,
AttestationTxnTable,
} from "./schema.js";
import { migrate, migrateDataFetcher, migratePriceFetcher } from "./migrate.js";
import { encodeJsonWithBigInts } from "../utils/index.js";
Expand All @@ -39,6 +41,8 @@ interface Tables {
legacyProjects: LegacyProjectTable;
applicationsPayouts: ApplicationPayout;
ipfsData: IpfsDataTable;
attestations: AttestationTable;
attestationTxns: AttestationTxnTable;
}

type KyselyDb = Kysely<Tables>;
Expand Down Expand Up @@ -617,6 +621,36 @@ export class Database {
break;
}

case "InsertAttestation": {
const attestationData = change.attestation.attestationData;
const transactionsData = change.attestation.transactionsData;

// Insert into attestations
await this.#db
.withSchema(this.chainDataSchemaName)
.insertInto("attestations")
.values(attestationData)
.execute();

// Insert into attestation transactions
const attestationTxns: AttestationTxnTable[] = [];
for (let i = 0; i < transactionsData.length; i++) {
// Link transaction to attestation
attestationTxns.push({
chainId: transactionsData[i].chainId,
txnHash: transactionsData[i].txnHash,
attestationUid: attestationData.uid,
attestationChainId: attestationData.chainId,
});
}
await this.#db
.withSchema(this.chainDataSchemaName)
.insertInto("attestationTxns")
.values(attestationTxns)
.execute();
break;
}

default:
throw new Error(`Unknown changeset type`);
}
Expand Down
52 changes: 52 additions & 0 deletions src/database/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,48 @@ export async function migrate<T>(db: Kysely<T>, schemaName: string) {
.columns(["chainId", "roundId", "applicationId"])
.execute();

await schema
.createTable("attestations")
.addColumn("uid", "text")
.addColumn("chainId", CHAIN_ID_TYPE)
.addColumn("fee", BIGINT_TYPE)
.addColumn("recipient", ADDRESS_TYPE)
.addColumn("refUID", "text")
.addColumn("projectsContributed", BIGINT_TYPE)
.addColumn("roundsContributed", BIGINT_TYPE)
.addColumn("chainIdsContributed", BIGINT_TYPE)
.addColumn("totalUSDAmount", BIGINT_TYPE)
.addColumn("timestamp", "timestamptz")
.addColumn("metadataCid", "text")
.addColumn("metadata", "jsonb")
.addUniqueConstraint("unique_uid_chainId", ["uid", "chainId"])
.execute();

await schema
.createTable("attestation_txns")
.addColumn("txnHash", "text")
.addColumn("chainId", CHAIN_ID_TYPE)

// Add the foreign key columns
.addColumn("attestationUid", "text")
.addColumn("attestationChainId", CHAIN_ID_TYPE)

// Add Constraints
.addUniqueConstraint("unique_txnHash_chainId_attestationUid", [
"txnHash",
"chainId",
"attestationUid",
])

.addForeignKeyConstraint(
"attestation_txns_attestations_fkey",
["attestationUid", "attestationChainId"],
"attestations",
["uid", "chainId"],
(cb) => cb.onDelete("cascade")
)
.execute();

await schema
.createTable("legacy_projects")
.addColumn("id", "serial", (col) => col.primaryKey())
Expand Down Expand Up @@ -338,6 +380,11 @@ export async function migrate<T>(db: Kysely<T>, schemaName: string) {
"applications"
)}(id, chain_id)|@fieldNme application';

comment on table ${ref("attestation_txns")} is
E'@foreignKey ("txn_hash", "chain_id") references ${ref(
"donations"
)}(transaction_hash, chain_id)|@fieldName donations';

create function ${ref("applications_canonical_project")}(a ${ref(
"applications"
)} ) returns ${ref("projects")} as $$
Expand All @@ -356,6 +403,11 @@ export async function migrate<T>(db: Kysely<T>, schemaName: string) {
)}(id, round_id, chain_id)|@fieldName application|@foreignFieldName donations
';

comment on constraint "attestation_txns_attestations_fkey" on ${ref(
"attestation_txns"
)} is
E'@foreignFieldName attestationTxns\n@fieldName attestation';

comment on constraint "round_roles_rounds_fkey" on ${ref("round_roles")} is
E'@foreignFieldName roles\n@fieldName round';

Expand Down
29 changes: 29 additions & 0 deletions src/database/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {

import { Address, Hex, ChainId } from "../types.js";
import { z } from "zod";
import { AttestationTxnData } from "../indexer/types.js";

export type MatchingDistribution = z.infer<typeof MatchingDistributionSchema>;

Expand Down Expand Up @@ -267,3 +268,31 @@ export type NewIpfsData = {
cid: string;
data: unknown;
};

// Attestations
export type AttestationTable = {
uid: string;
chainId: ChainId;
fee: bigint;
recipient: Address;
refUID: string;
projectsContributed: bigint;
roundsContributed: bigint;
chainIdsContributed: bigint;
totalUSDAmount: bigint;
timestamp: Date | null;
metadataCid: string;
metadata: unknown;
};

export type AttestationTxnTable = {
chainId: ChainId;
txnHash: string;
attestationUid: string;
attestationChainId: ChainId;
};

export type NewAttestationData = {
attestationData: AttestationTable;
transactionsData: AttestationTxnData[];
};
19 changes: 16 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import abis from "./indexer/abis/index.js";
import type { EventHandlerContext } from "./indexer/indexer.js";
import { handleEvent as handleAlloV1Event } from "./indexer/allo/v1/handleEvent.js";
import { handleEvent as handleAlloV2Event } from "./indexer/allo/v2/handleEvent.js";
import { handleEvent as handleGitcoinAttestationNetworkEvent } from "./indexer/gitcoin-attestation-network/handleEvent.js";
import { Database } from "./database/index.js";
import { decodeJsonWithBigInts, getExternalIP } from "./utils/index.js";
import { Block } from "chainsauce/dist/cache.js";
Expand Down Expand Up @@ -650,9 +651,21 @@ async function catchupAndWatchChain(
});
});
} else {
const handler = args.event.contractName.startsWith("AlloV1")
? handleAlloV1Event
: handleAlloV2Event;
let handler;

if (args.event.contractName.startsWith("GitcoinAttestationNetwork")) {
handler = handleGitcoinAttestationNetworkEvent;
} else if (args.event.contractName.startsWith("AlloV1")) {
handler = handleAlloV1Event;
} else if (args.event.contractName.startsWith("AlloV2")) {
handler = handleAlloV2Event;
} else {
indexerLogger.warn({
msg: "skipping event due to unknown contract",
event: args.event,
});
return;
}

const changesets = await handler(args);

Expand Down
Loading