Skip to content

Commit

Permalink
examples: add production like cli indexers example
Browse files Browse the repository at this point in the history
  • Loading branch information
jaipaljadeja committed Dec 4, 2024
1 parent 53604d5 commit 9c64da3
Show file tree
Hide file tree
Showing 13 changed files with 905 additions and 125 deletions.
7 changes: 5 additions & 2 deletions examples/cli/apibara.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ import { defineConfig } from "apibara/config";

export default defineConfig({
runtimeConfig: {
databasePath: ":memory:",
pgLiteDBPath: "memory://persistence",
},
presets: {
dev: {
runtimeConfig: {
databasePath: "/tmp/my-db.sqlite",
pgLiteDBPath: "./.persistence",
},
},
},
// rollupConfig: {
// plugins: [tsConfigPaths()],
// },
});
14 changes: 14 additions & 0 deletions examples/cli/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: "3"
services:
timescaledb:
image: timescale/timescaledb-ha:pg14-latest
restart: always
environment:
POSTGRES_PASSWORD: postgres
ports:
- "5432:5432"
volumes:
- postgres:/var/lib/postgresql/data

volumes:
postgres:
14 changes: 14 additions & 0 deletions examples/cli/drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { Config } from "drizzle-kit";

const connectionString =
process.env.POSTGRES_CONNECTION_STRING ??
"postgres://postgres:postgres@localhost:5432/postgres";

export default {
schema: "./lib/schema.ts",
out: "./drizzle",
dialect: "postgresql",
dbCredentials: {
url: connectionString,
},
} satisfies Config;
25 changes: 25 additions & 0 deletions examples/cli/drizzle/0000_great_hobgoblin.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
CREATE TABLE IF NOT EXISTS "checkpoints" (
"id" text PRIMARY KEY NOT NULL,
"order_key" integer NOT NULL,
"unique_key" text NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "ethereum_usdc_transfers" (
"number" bigint,
"hash" text,
"_cursor" "int8range" NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "filters" (
"id" text NOT NULL,
"filter" text NOT NULL,
"from_block" integer NOT NULL,
"to_block" integer,
CONSTRAINT "filters_id_from_block_pk" PRIMARY KEY("id","from_block")
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "starknet_usdc_transfers" (
"number" bigint,
"hash" text,
"_cursor" "int8range" NOT NULL
);
154 changes: 154 additions & 0 deletions examples/cli/drizzle/meta/0000_snapshot.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
{
"id": "f33ac3ed-f308-44cf-a4b1-64871d409835",
"prevId": "00000000-0000-0000-0000-000000000000",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.checkpoints": {
"name": "checkpoints",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"order_key": {
"name": "order_key",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"unique_key": {
"name": "unique_key",
"type": "text",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.ethereum_usdc_transfers": {
"name": "ethereum_usdc_transfers",
"schema": "",
"columns": {
"number": {
"name": "number",
"type": "bigint",
"primaryKey": false,
"notNull": false
},
"hash": {
"name": "hash",
"type": "text",
"primaryKey": false,
"notNull": false
},
"_cursor": {
"name": "_cursor",
"type": "int8range",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.filters": {
"name": "filters",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"filter": {
"name": "filter",
"type": "text",
"primaryKey": false,
"notNull": true
},
"from_block": {
"name": "from_block",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"to_block": {
"name": "to_block",
"type": "integer",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {
"filters_id_from_block_pk": {
"name": "filters_id_from_block_pk",
"columns": ["id", "from_block"]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.starknet_usdc_transfers": {
"name": "starknet_usdc_transfers",
"schema": "",
"columns": {
"number": {
"name": "number",
"type": "bigint",
"primaryKey": false,
"notNull": false
},
"hash": {
"name": "hash",
"type": "text",
"primaryKey": false,
"notNull": false
},
"_cursor": {
"name": "_cursor",
"type": "int8range",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}
13 changes: 13 additions & 0 deletions examples/cli/drizzle/meta/_journal.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": "7",
"dialect": "postgresql",
"entries": [
{
"idx": 0,
"version": "7",
"when": 1733315820544,
"tag": "0000_great_hobgoblin",
"breakpoints": true
}
]
}
91 changes: 75 additions & 16 deletions examples/cli/indexers/1-evm.indexer.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,78 @@
import { EvmStream } from "@apibara/evm";
import { defineIndexer } from "@apibara/indexer";
import { defineIndexer, useSink } from "@apibara/indexer";
import { drizzlePersistence } from "@apibara/indexer/plugins/drizzle-persistence";
import { useLogger } from "@apibara/indexer/plugins/logger";
import { drizzle as drizzleSink } from "@apibara/indexer/sinks/drizzle";
import type { ApibaraRuntimeConfig } from "apibara/types";
import type {
ExtractTablesWithRelations,
TablesRelationalConfig,
} from "drizzle-orm";
import type { PgDatabase, PgQueryResultHKT } from "drizzle-orm/pg-core";
import { encodeEventTopics, parseAbi } from "viem";
import { db } from "../lib/db";
import { ethereumUsdcTransfers } from "../lib/schema";

export default defineIndexer(EvmStream)({
streamUrl: "https://ethereum.preview.apibara.org",
finality: "accepted",
startingCursor: {
orderKey: 10_000_000n,
},
filter: {
header: "always",
transactions: [{}],
},
async transform({ endCursor }) {
const logger = useLogger();
logger.info("Transforming block ", endCursor?.orderKey);
},
});
const abi = parseAbi([
"event Transfer(address indexed from, address indexed to, uint256 value)",
]);

// USDC Transfers on Ethereum
export default function (runtimeConfig: ApibaraRuntimeConfig) {
return createIndexer({
database: db,
});
}

export function createIndexer<
TQueryResult extends PgQueryResultHKT,
TFullSchema extends Record<string, unknown> = Record<string, never>,
TSchema extends
TablesRelationalConfig = ExtractTablesWithRelations<TFullSchema>,
>({
database,
}: {
database: PgDatabase<TQueryResult, TFullSchema, TSchema>;
}) {
return defineIndexer(EvmStream)({
streamUrl: "https://ethereum.preview.apibara.org",
finality: "accepted",
startingCursor: {
orderKey: 10_000_000n,
},
filter: {
logs: [
{
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
topics: encodeEventTopics({
abi,
eventName: "Transfer",
args: { from: null, to: null },
}) as `0x${string}`[],
strict: true,
},
],
},
plugins: [
drizzlePersistence({ database, indexerName: "evm-usdc-transfers" }),
],
sink: drizzleSink({
database,
tables: [ethereumUsdcTransfers],
}),
async transform({ endCursor, context, block }) {
const logger = useLogger();
const { db } = useSink({ context });
const { logs } = block;

logger.info("Transforming block ", endCursor?.orderKey);

for (const log of logs) {
await db.insert(ethereumUsdcTransfers).values({
number: Number(endCursor?.orderKey),
hash: log.transactionHash,
});
}
},
});
}
Loading

0 comments on commit 9c64da3

Please sign in to comment.