From 78313674da7617af1484a7d04538a6d4bb4c14a6 Mon Sep 17 00:00:00 2001 From: Chqrles Date: Wed, 12 Jun 2024 23:10:53 +0200 Subject: [PATCH] [Backend] USDC balance indexer + endpoint (#84) * support a fake USDC on sepolia * fix balances indexer * remove decimals support * small refactoring * activate entity mode on balances indexor * configure balacnes db update * fix balances indexor entity key * fix entity mode config * small drizzle refactor * add drizzle migrations * fix apibara insert/update on balances * rename db url variable name * remove useless config files * remove more useless config files * replace postgres-js by node-postgres * removed balances indexer entity mode * generate drizzle migration on build --- backend/.gitignore | 2 +- backend/drizzle.config.ts | 11 +- backend/drizzle/meta/_journal.json | 1 + backend/package.json | 1 + backend/src/app.ts | 3 +- backend/src/db/drizzle.ts | 4 +- .../migrations/0000_dry_silver_centurion.sql | 13 - .../db/migrations/0001_flawless_nehzno.sql | 8 - .../src/db/migrations/0002_medical_darwin.sql | 8 - .../migrations/0003_giant_thaddeus_ross.sql | 6 - .../src/db/migrations/0004_thin_gorgon.sql | 6 - .../db/migrations/0005_first_madripoor.sql | 5 - .../migrations/0006_light_rocket_raccoon.sql | 1 - .../0006_outgoing_roxanne_simpson.sql | 4 - .../src/db/migrations/0007_breezy_zarek.sql | 2 - .../src/db/migrations/0008_fearless_angel.sql | 4 - .../src/db/migrations/0009_gray_whizzer.sql | 3 - .../src/db/migrations/meta/0000_snapshot.json | 91 ------ .../src/db/migrations/meta/0001_snapshot.json | 137 -------- .../src/db/migrations/meta/0002_snapshot.json | 185 ----------- .../src/db/migrations/meta/0003_snapshot.json | 221 ------------- .../src/db/migrations/meta/0004_snapshot.json | 256 --------------- .../src/db/migrations/meta/0005_snapshot.json | 284 ---------------- .../src/db/migrations/meta/0006_snapshot.json | 303 ------------------ .../src/db/migrations/meta/0007_snapshot.json | 279 ---------------- .../src/db/migrations/meta/0008_snapshot.json | 291 ----------------- .../src/db/migrations/meta/0009_snapshot.json | 291 ----------------- backend/src/db/migrations/meta/_journal.json | 76 ----- backend/src/db/plugin.ts | 2 + backend/src/routes/getBalance.ts | 14 +- infra/indexers/.gitignore | 1 + infra/indexers/docker-compose.yml | 45 --- infra/indexers/envs.example.yaml | 19 -- infra/indexers/init.sql | 22 -- infra/indexers/k8indexer.yml | 26 -- infra/indexers/src/constants.ts | 3 + infra/indexers/src/deps.ts | 5 +- infra/indexers/src/usdc-balances.indexer.ts | 93 +++--- infra/indexers/src/usdc-transfers.indexer.ts | 77 ++--- infra/indexers/src/usdc.ts | 26 -- infra/indexers/src/utils.ts | 16 + 41 files changed, 136 insertions(+), 2709 deletions(-) create mode 100644 backend/drizzle/meta/_journal.json delete mode 100644 backend/src/db/migrations/0000_dry_silver_centurion.sql delete mode 100644 backend/src/db/migrations/0001_flawless_nehzno.sql delete mode 100644 backend/src/db/migrations/0002_medical_darwin.sql delete mode 100644 backend/src/db/migrations/0003_giant_thaddeus_ross.sql delete mode 100644 backend/src/db/migrations/0004_thin_gorgon.sql delete mode 100644 backend/src/db/migrations/0005_first_madripoor.sql delete mode 100644 backend/src/db/migrations/0006_light_rocket_raccoon.sql delete mode 100644 backend/src/db/migrations/0006_outgoing_roxanne_simpson.sql delete mode 100644 backend/src/db/migrations/0007_breezy_zarek.sql delete mode 100644 backend/src/db/migrations/0008_fearless_angel.sql delete mode 100644 backend/src/db/migrations/0009_gray_whizzer.sql delete mode 100644 backend/src/db/migrations/meta/0000_snapshot.json delete mode 100644 backend/src/db/migrations/meta/0001_snapshot.json delete mode 100644 backend/src/db/migrations/meta/0002_snapshot.json delete mode 100644 backend/src/db/migrations/meta/0003_snapshot.json delete mode 100644 backend/src/db/migrations/meta/0004_snapshot.json delete mode 100644 backend/src/db/migrations/meta/0005_snapshot.json delete mode 100644 backend/src/db/migrations/meta/0006_snapshot.json delete mode 100644 backend/src/db/migrations/meta/0007_snapshot.json delete mode 100644 backend/src/db/migrations/meta/0008_snapshot.json delete mode 100644 backend/src/db/migrations/meta/0009_snapshot.json delete mode 100644 backend/src/db/migrations/meta/_journal.json create mode 100644 infra/indexers/.gitignore delete mode 100644 infra/indexers/docker-compose.yml delete mode 100644 infra/indexers/envs.example.yaml delete mode 100644 infra/indexers/init.sql delete mode 100644 infra/indexers/k8indexer.yml create mode 100644 infra/indexers/src/constants.ts delete mode 100644 infra/indexers/src/usdc.ts create mode 100644 infra/indexers/src/utils.ts diff --git a/backend/.gitignore b/backend/.gitignore index 468f82a1..9b1ee42e 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -10,7 +10,7 @@ yarn-error.log* lerna-debug.log* .pnpm-debug.log* -# Caches +# Caches .cache diff --git a/backend/drizzle.config.ts b/backend/drizzle.config.ts index d15319aa..9512e436 100644 --- a/backend/drizzle.config.ts +++ b/backend/drizzle.config.ts @@ -1,9 +1,12 @@ /* eslint-disable import/no-unused-modules */ -import type { Config } from 'drizzle-kit' +import { defineConfig } from 'drizzle-kit' -export default { +export default defineConfig({ schema: './src/db/schema.ts', - out: './src/db/migrations', + out: './drizzle', driver: 'pg', -} satisfies Config + dbCredentials: { + connectionString: process.env.DATABASE_URL ?? '', + }, +}) diff --git a/backend/drizzle/meta/_journal.json b/backend/drizzle/meta/_journal.json new file mode 100644 index 00000000..5dcbf6ab --- /dev/null +++ b/backend/drizzle/meta/_journal.json @@ -0,0 +1 @@ +{"version":"5","dialect":"pg","entries":[]} \ No newline at end of file diff --git a/backend/package.json b/backend/package.json index 1f971116..82253636 100644 --- a/backend/package.json +++ b/backend/package.json @@ -6,6 +6,7 @@ "typecheck": "tsc --noEmit", "drizzle:generate": "drizzle-kit generate:pg", "test": "vitest", + "prepare": "pnpm drizzle:generate", "coverage": "vitest run --coverage", "lint": "eslint . --max-warnings=0", "fix": "eslint . --fix" diff --git a/backend/src/app.ts b/backend/src/app.ts index 2e476254..8462a1f6 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -2,7 +2,8 @@ import Fastify from 'fastify' import { Account } from 'starknet' import { fastifyDrizzle } from '@/db/plugin' -import { declareRoutes } from '@/routes' + +import { declareRoutes } from './routes' export type AppConfiguration = { database: { diff --git a/backend/src/db/drizzle.ts b/backend/src/db/drizzle.ts index 260f4732..2529de32 100644 --- a/backend/src/db/drizzle.ts +++ b/backend/src/db/drizzle.ts @@ -14,7 +14,5 @@ export function drizzle(client: postgres.Sql, config: DrizzleConfig = {}) { export async function migrate(client: postgres.Sql, config: DrizzleConfig = {}) { // Notice that the path must be relative to the application root. - return await ogMigrate(drizzle(client, config), { - migrationsFolder: './src/db/migrations', - }) + return await ogMigrate(drizzle(client, config), { migrationsFolder: './drizzle' }) } diff --git a/backend/src/db/migrations/0000_dry_silver_centurion.sql b/backend/src/db/migrations/0000_dry_silver_centurion.sql deleted file mode 100644 index ae9dc018..00000000 --- a/backend/src/db/migrations/0000_dry_silver_centurion.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE TABLE IF NOT EXISTS "transfer_usdc" ( - "transfer_id" text PRIMARY KEY NOT NULL, - "network" text, - "block_hash" text, - "block_number" bigint, - "block_timestamp" timestamp, - "transaction_hash" text, - "from_address" text, - "to_address" text, - "amount" text, - "created_at" timestamp, - "_cursor" bigint -); diff --git a/backend/src/db/migrations/0001_flawless_nehzno.sql b/backend/src/db/migrations/0001_flawless_nehzno.sql deleted file mode 100644 index ee637c0f..00000000 --- a/backend/src/db/migrations/0001_flawless_nehzno.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE IF NOT EXISTS "balance_usdc" ( - "network" text, - "block_number" bigint, - "block_timestamp" timestamp, - "address" text, - "balance" text, - "_cursor" bigint -); diff --git a/backend/src/db/migrations/0002_medical_darwin.sql b/backend/src/db/migrations/0002_medical_darwin.sql deleted file mode 100644 index 1524571b..00000000 --- a/backend/src/db/migrations/0002_medical_darwin.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE IF NOT EXISTS "registration" ( - "phone_number" text PRIMARY KEY NOT NULL, - "address" text, - "first_name" text, - "last_name" text, - "created_at" timestamp DEFAULT now(), - "is_confirmed" boolean DEFAULT false -); diff --git a/backend/src/db/migrations/0003_giant_thaddeus_ross.sql b/backend/src/db/migrations/0003_giant_thaddeus_ross.sql deleted file mode 100644 index 670dde34..00000000 --- a/backend/src/db/migrations/0003_giant_thaddeus_ross.sql +++ /dev/null @@ -1,6 +0,0 @@ -CREATE TABLE IF NOT EXISTS "otp" ( - "phone_number" text, - "otp" text, - "used" boolean DEFAULT false, - "created_at" timestamp DEFAULT now() -); diff --git a/backend/src/db/migrations/0004_thin_gorgon.sql b/backend/src/db/migrations/0004_thin_gorgon.sql deleted file mode 100644 index b2dafd3b..00000000 --- a/backend/src/db/migrations/0004_thin_gorgon.sql +++ /dev/null @@ -1,6 +0,0 @@ -CREATE TABLE IF NOT EXISTS "claims" ( - "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, - "amount" text, - "nonce" serial NOT NULL, - "signature" text[] -); diff --git a/backend/src/db/migrations/0005_first_madripoor.sql b/backend/src/db/migrations/0005_first_madripoor.sql deleted file mode 100644 index c1500773..00000000 --- a/backend/src/db/migrations/0005_first_madripoor.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE TABLE IF NOT EXISTS "mock_limit" ( - "address" text PRIMARY KEY NOT NULL, - "limit" text, - "block_timestamp" timestamp -); diff --git a/backend/src/db/migrations/0006_light_rocket_raccoon.sql b/backend/src/db/migrations/0006_light_rocket_raccoon.sql deleted file mode 100644 index 92555695..00000000 --- a/backend/src/db/migrations/0006_light_rocket_raccoon.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "registration" ADD COLUMN "contract_address" text DEFAULT ''; \ No newline at end of file diff --git a/backend/src/db/migrations/0006_outgoing_roxanne_simpson.sql b/backend/src/db/migrations/0006_outgoing_roxanne_simpson.sql deleted file mode 100644 index 3ba2b852..00000000 --- a/backend/src/db/migrations/0006_outgoing_roxanne_simpson.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE "claims" ALTER COLUMN "nonce" SET DATA TYPE integer;--> statement-breakpoint -ALTER TABLE "claims" ALTER COLUMN "nonce" DROP NOT NULL;--> statement-breakpoint -ALTER TABLE "claims" ADD COLUMN "address" text;--> statement-breakpoint -ALTER TABLE "claims" ADD CONSTRAINT "claims_address_nonce_unique" UNIQUE("address","nonce"); \ No newline at end of file diff --git a/backend/src/db/migrations/0007_breezy_zarek.sql b/backend/src/db/migrations/0007_breezy_zarek.sql deleted file mode 100644 index 91d8b159..00000000 --- a/backend/src/db/migrations/0007_breezy_zarek.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE "registration" DROP COLUMN IF EXISTS "address";--> statement-breakpoint -ALTER TABLE "registration" DROP COLUMN IF EXISTS "last_name"; \ No newline at end of file diff --git a/backend/src/db/migrations/0008_fearless_angel.sql b/backend/src/db/migrations/0008_fearless_angel.sql deleted file mode 100644 index 3ba2b852..00000000 --- a/backend/src/db/migrations/0008_fearless_angel.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE "claims" ALTER COLUMN "nonce" SET DATA TYPE integer;--> statement-breakpoint -ALTER TABLE "claims" ALTER COLUMN "nonce" DROP NOT NULL;--> statement-breakpoint -ALTER TABLE "claims" ADD COLUMN "address" text;--> statement-breakpoint -ALTER TABLE "claims" ADD CONSTRAINT "claims_address_nonce_unique" UNIQUE("address","nonce"); \ No newline at end of file diff --git a/backend/src/db/migrations/0009_gray_whizzer.sql b/backend/src/db/migrations/0009_gray_whizzer.sql deleted file mode 100644 index 44af86eb..00000000 --- a/backend/src/db/migrations/0009_gray_whizzer.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE "registration" RENAME COLUMN "first_name" TO "nickname";--> statement-breakpoint -ALTER TABLE "otp" ADD PRIMARY KEY ("phone_number");--> statement-breakpoint -ALTER TABLE "otp" ALTER COLUMN "phone_number" SET NOT NULL; \ No newline at end of file diff --git a/backend/src/db/migrations/meta/0000_snapshot.json b/backend/src/db/migrations/meta/0000_snapshot.json deleted file mode 100644 index 2d8b1e96..00000000 --- a/backend/src/db/migrations/meta/0000_snapshot.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "id": "17cd79e7-54c5-4426-b179-33c068cebaf8", - "prevId": "00000000-0000-0000-0000-000000000000", - "version": "5", - "dialect": "pg", - "tables": { - "transfer_usdc": { - "name": "transfer_usdc", - "schema": "", - "columns": { - "transfer_id": { - "name": "transfer_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_hash": { - "name": "block_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "transaction_hash": { - "name": "transaction_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "from_address": { - "name": "from_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "to_address": { - "name": "to_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - } - }, - "enums": {}, - "schemas": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/backend/src/db/migrations/meta/0001_snapshot.json b/backend/src/db/migrations/meta/0001_snapshot.json deleted file mode 100644 index b6ff33d2..00000000 --- a/backend/src/db/migrations/meta/0001_snapshot.json +++ /dev/null @@ -1,137 +0,0 @@ -{ - "id": "2e782cb5-83f3-45c4-94d7-72bd2cdabf88", - "prevId": "17cd79e7-54c5-4426-b179-33c068cebaf8", - "version": "5", - "dialect": "pg", - "tables": { - "balance_usdc": { - "name": "balance_usdc", - "schema": "", - "columns": { - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "balance": { - "name": "balance", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "transfer_usdc": { - "name": "transfer_usdc", - "schema": "", - "columns": { - "transfer_id": { - "name": "transfer_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_hash": { - "name": "block_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "transaction_hash": { - "name": "transaction_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "from_address": { - "name": "from_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "to_address": { - "name": "to_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - } - }, - "enums": {}, - "schemas": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/backend/src/db/migrations/meta/0002_snapshot.json b/backend/src/db/migrations/meta/0002_snapshot.json deleted file mode 100644 index 4f513f1b..00000000 --- a/backend/src/db/migrations/meta/0002_snapshot.json +++ /dev/null @@ -1,185 +0,0 @@ -{ - "id": "9ef1e1c1-43aa-4d77-a535-e301ab1d09f3", - "prevId": "2e782cb5-83f3-45c4-94d7-72bd2cdabf88", - "version": "5", - "dialect": "pg", - "tables": { - "registration": { - "name": "registration", - "schema": "", - "columns": { - "phone_number": { - "name": "phone_number", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "first_name": { - "name": "first_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "last_name": { - "name": "last_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "is_confirmed": { - "name": "is_confirmed", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "balance_usdc": { - "name": "balance_usdc", - "schema": "", - "columns": { - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "balance": { - "name": "balance", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "transfer_usdc": { - "name": "transfer_usdc", - "schema": "", - "columns": { - "transfer_id": { - "name": "transfer_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_hash": { - "name": "block_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "transaction_hash": { - "name": "transaction_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "from_address": { - "name": "from_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "to_address": { - "name": "to_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - } - }, - "enums": {}, - "schemas": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/backend/src/db/migrations/meta/0003_snapshot.json b/backend/src/db/migrations/meta/0003_snapshot.json deleted file mode 100644 index 2ef1d0d1..00000000 --- a/backend/src/db/migrations/meta/0003_snapshot.json +++ /dev/null @@ -1,221 +0,0 @@ -{ - "id": "ddbf7704-31b7-4326-aa2c-d23b4d774bc8", - "prevId": "9ef1e1c1-43aa-4d77-a535-e301ab1d09f3", - "version": "5", - "dialect": "pg", - "tables": { - "otp": { - "name": "otp", - "schema": "", - "columns": { - "phone_number": { - "name": "phone_number", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "otp": { - "name": "otp", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "used": { - "name": "used", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "registration": { - "name": "registration", - "schema": "", - "columns": { - "phone_number": { - "name": "phone_number", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "first_name": { - "name": "first_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "last_name": { - "name": "last_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "is_confirmed": { - "name": "is_confirmed", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "balance_usdc": { - "name": "balance_usdc", - "schema": "", - "columns": { - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "balance": { - "name": "balance", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "transfer_usdc": { - "name": "transfer_usdc", - "schema": "", - "columns": { - "transfer_id": { - "name": "transfer_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_hash": { - "name": "block_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "transaction_hash": { - "name": "transaction_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "from_address": { - "name": "from_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "to_address": { - "name": "to_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - } - }, - "enums": {}, - "schemas": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/backend/src/db/migrations/meta/0004_snapshot.json b/backend/src/db/migrations/meta/0004_snapshot.json deleted file mode 100644 index 3c962edb..00000000 --- a/backend/src/db/migrations/meta/0004_snapshot.json +++ /dev/null @@ -1,256 +0,0 @@ -{ - "id": "dce629a6-17e5-438e-8bc5-5f044726fd3b", - "prevId": "ddbf7704-31b7-4326-aa2c-d23b4d774bc8", - "version": "5", - "dialect": "pg", - "tables": { - "claims": { - "name": "claims", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "nonce": { - "name": "nonce", - "type": "serial", - "primaryKey": false, - "notNull": true - }, - "signature": { - "name": "signature", - "type": "text[]", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "otp": { - "name": "otp", - "schema": "", - "columns": { - "phone_number": { - "name": "phone_number", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "otp": { - "name": "otp", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "used": { - "name": "used", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "registration": { - "name": "registration", - "schema": "", - "columns": { - "phone_number": { - "name": "phone_number", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "first_name": { - "name": "first_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "last_name": { - "name": "last_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "is_confirmed": { - "name": "is_confirmed", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "balance_usdc": { - "name": "balance_usdc", - "schema": "", - "columns": { - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "balance": { - "name": "balance", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "transfer_usdc": { - "name": "transfer_usdc", - "schema": "", - "columns": { - "transfer_id": { - "name": "transfer_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_hash": { - "name": "block_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "transaction_hash": { - "name": "transaction_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "from_address": { - "name": "from_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "to_address": { - "name": "to_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - } - }, - "enums": {}, - "schemas": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/backend/src/db/migrations/meta/0005_snapshot.json b/backend/src/db/migrations/meta/0005_snapshot.json deleted file mode 100644 index f765103c..00000000 --- a/backend/src/db/migrations/meta/0005_snapshot.json +++ /dev/null @@ -1,284 +0,0 @@ -{ - "id": "68742940-5675-4d5a-8303-15ca8e817329", - "prevId": "dce629a6-17e5-438e-8bc5-5f044726fd3b", - "version": "5", - "dialect": "pg", - "tables": { - "claims": { - "name": "claims", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "nonce": { - "name": "nonce", - "type": "serial", - "primaryKey": false, - "notNull": true - }, - "signature": { - "name": "signature", - "type": "text[]", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "mock_limit": { - "name": "mock_limit", - "schema": "", - "columns": { - "address": { - "name": "address", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "limit": { - "name": "limit", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "otp": { - "name": "otp", - "schema": "", - "columns": { - "phone_number": { - "name": "phone_number", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "otp": { - "name": "otp", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "used": { - "name": "used", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "registration": { - "name": "registration", - "schema": "", - "columns": { - "phone_number": { - "name": "phone_number", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "first_name": { - "name": "first_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "last_name": { - "name": "last_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "is_confirmed": { - "name": "is_confirmed", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "balance_usdc": { - "name": "balance_usdc", - "schema": "", - "columns": { - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "balance": { - "name": "balance", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "transfer_usdc": { - "name": "transfer_usdc", - "schema": "", - "columns": { - "transfer_id": { - "name": "transfer_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_hash": { - "name": "block_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "transaction_hash": { - "name": "transaction_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "from_address": { - "name": "from_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "to_address": { - "name": "to_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - } - }, - "enums": {}, - "schemas": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/backend/src/db/migrations/meta/0006_snapshot.json b/backend/src/db/migrations/meta/0006_snapshot.json deleted file mode 100644 index 64bac97f..00000000 --- a/backend/src/db/migrations/meta/0006_snapshot.json +++ /dev/null @@ -1,303 +0,0 @@ -{ - "id": "119a3777-c913-4a8c-9cc7-b3dfdcc37f03", - "prevId": "68742940-5675-4d5a-8303-15ca8e817329", - "version": "5", - "dialect": "pg", - "tables": { - "claims": { - "name": "claims", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "nonce": { - "name": "nonce", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "signature": { - "name": "signature", - "type": "text[]", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "claims_address_nonce_unique": { - "name": "claims_address_nonce_unique", - "nullsNotDistinct": false, - "columns": ["address", "nonce"] - } - } - }, - "mock_limit": { - "name": "mock_limit", - "schema": "", - "columns": { - "address": { - "name": "address", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "limit": { - "name": "limit", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "otp": { - "name": "otp", - "schema": "", - "columns": { - "phone_number": { - "name": "phone_number", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "otp": { - "name": "otp", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "used": { - "name": "used", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "registration": { - "name": "registration", - "schema": "", - "columns": { - "phone_number": { - "name": "phone_number", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "first_name": { - "name": "first_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "last_name": { - "name": "last_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "contract_address": { - "name": "contract_address", - "type": "text", - "primaryKey": false, - "notNull": false, - "default": "''" - }, - "is_confirmed": { - "name": "is_confirmed", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "balance_usdc": { - "name": "balance_usdc", - "schema": "", - "columns": { - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "balance": { - "name": "balance", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "transfer_usdc": { - "name": "transfer_usdc", - "schema": "", - "columns": { - "transfer_id": { - "name": "transfer_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_hash": { - "name": "block_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "transaction_hash": { - "name": "transaction_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "from_address": { - "name": "from_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "to_address": { - "name": "to_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - } - }, - "enums": {}, - "schemas": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/backend/src/db/migrations/meta/0007_snapshot.json b/backend/src/db/migrations/meta/0007_snapshot.json deleted file mode 100644 index 1e69a501..00000000 --- a/backend/src/db/migrations/meta/0007_snapshot.json +++ /dev/null @@ -1,279 +0,0 @@ -{ - "id": "951d8ca3-fdb5-4d6e-8ebf-5591b0de1267", - "prevId": "119a3777-c913-4a8c-9cc7-b3dfdcc37f03", - "version": "5", - "dialect": "pg", - "tables": { - "claims": { - "name": "claims", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "nonce": { - "name": "nonce", - "type": "serial", - "primaryKey": false, - "notNull": true - }, - "signature": { - "name": "signature", - "type": "text[]", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "mock_limit": { - "name": "mock_limit", - "schema": "", - "columns": { - "address": { - "name": "address", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "limit": { - "name": "limit", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "otp": { - "name": "otp", - "schema": "", - "columns": { - "phone_number": { - "name": "phone_number", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "otp": { - "name": "otp", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "used": { - "name": "used", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "registration": { - "name": "registration", - "schema": "", - "columns": { - "phone_number": { - "name": "phone_number", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "first_name": { - "name": "first_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "contract_address": { - "name": "contract_address", - "type": "text", - "primaryKey": false, - "notNull": false, - "default": "''" - }, - "is_confirmed": { - "name": "is_confirmed", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "balance_usdc": { - "name": "balance_usdc", - "schema": "", - "columns": { - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "balance": { - "name": "balance", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "transfer_usdc": { - "name": "transfer_usdc", - "schema": "", - "columns": { - "transfer_id": { - "name": "transfer_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_hash": { - "name": "block_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "transaction_hash": { - "name": "transaction_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "from_address": { - "name": "from_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "to_address": { - "name": "to_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - } - }, - "enums": {}, - "schemas": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/backend/src/db/migrations/meta/0008_snapshot.json b/backend/src/db/migrations/meta/0008_snapshot.json deleted file mode 100644 index 2cc306f5..00000000 --- a/backend/src/db/migrations/meta/0008_snapshot.json +++ /dev/null @@ -1,291 +0,0 @@ -{ - "id": "c1e328e0-1009-46fa-80ae-f4f838bb6237", - "prevId": "951d8ca3-fdb5-4d6e-8ebf-5591b0de1267", - "version": "5", - "dialect": "pg", - "tables": { - "claims": { - "name": "claims", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "nonce": { - "name": "nonce", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "signature": { - "name": "signature", - "type": "text[]", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "claims_address_nonce_unique": { - "name": "claims_address_nonce_unique", - "nullsNotDistinct": false, - "columns": ["address", "nonce"] - } - } - }, - "mock_limit": { - "name": "mock_limit", - "schema": "", - "columns": { - "address": { - "name": "address", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "limit": { - "name": "limit", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "otp": { - "name": "otp", - "schema": "", - "columns": { - "phone_number": { - "name": "phone_number", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "otp": { - "name": "otp", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "used": { - "name": "used", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "registration": { - "name": "registration", - "schema": "", - "columns": { - "phone_number": { - "name": "phone_number", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "first_name": { - "name": "first_name", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "contract_address": { - "name": "contract_address", - "type": "text", - "primaryKey": false, - "notNull": false, - "default": "''" - }, - "is_confirmed": { - "name": "is_confirmed", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "balance_usdc": { - "name": "balance_usdc", - "schema": "", - "columns": { - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "balance": { - "name": "balance", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "transfer_usdc": { - "name": "transfer_usdc", - "schema": "", - "columns": { - "transfer_id": { - "name": "transfer_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_hash": { - "name": "block_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "transaction_hash": { - "name": "transaction_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "from_address": { - "name": "from_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "to_address": { - "name": "to_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - } - }, - "enums": {}, - "schemas": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/backend/src/db/migrations/meta/0009_snapshot.json b/backend/src/db/migrations/meta/0009_snapshot.json deleted file mode 100644 index bf6c46dc..00000000 --- a/backend/src/db/migrations/meta/0009_snapshot.json +++ /dev/null @@ -1,291 +0,0 @@ -{ - "id": "c3a1ffc5-8c81-47c8-979f-a9624ad69c3b", - "prevId": "c1e328e0-1009-46fa-80ae-f4f838bb6237", - "version": "5", - "dialect": "pg", - "tables": { - "claims": { - "name": "claims", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "uuid", - "primaryKey": true, - "notNull": true, - "default": "gen_random_uuid()" - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "nonce": { - "name": "nonce", - "type": "integer", - "primaryKey": false, - "notNull": false - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "signature": { - "name": "signature", - "type": "text[]", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "claims_address_nonce_unique": { - "name": "claims_address_nonce_unique", - "nullsNotDistinct": false, - "columns": ["address", "nonce"] - } - } - }, - "mock_limit": { - "name": "mock_limit", - "schema": "", - "columns": { - "address": { - "name": "address", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "limit": { - "name": "limit", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "otp": { - "name": "otp", - "schema": "", - "columns": { - "phone_number": { - "name": "phone_number", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "otp": { - "name": "otp", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "used": { - "name": "used", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "registration": { - "name": "registration", - "schema": "", - "columns": { - "phone_number": { - "name": "phone_number", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "nickname": { - "name": "nickname", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false, - "default": "now()" - }, - "contract_address": { - "name": "contract_address", - "type": "text", - "primaryKey": false, - "notNull": false, - "default": "''" - }, - "is_confirmed": { - "name": "is_confirmed", - "type": "boolean", - "primaryKey": false, - "notNull": false, - "default": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "balance_usdc": { - "name": "balance_usdc", - "schema": "", - "columns": { - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "address": { - "name": "address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "balance": { - "name": "balance", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "transfer_usdc": { - "name": "transfer_usdc", - "schema": "", - "columns": { - "transfer_id": { - "name": "transfer_id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "network": { - "name": "network", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_hash": { - "name": "block_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "block_number": { - "name": "block_number", - "type": "bigint", - "primaryKey": false, - "notNull": false - }, - "block_timestamp": { - "name": "block_timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "transaction_hash": { - "name": "transaction_hash", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "from_address": { - "name": "from_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "to_address": { - "name": "to_address", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "amount": { - "name": "amount", - "type": "text", - "primaryKey": false, - "notNull": false - }, - "created_at": { - "name": "created_at", - "type": "timestamp", - "primaryKey": false, - "notNull": false - }, - "_cursor": { - "name": "_cursor", - "type": "bigint", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - } - }, - "enums": {}, - "schemas": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/backend/src/db/migrations/meta/_journal.json b/backend/src/db/migrations/meta/_journal.json deleted file mode 100644 index f7fa252e..00000000 --- a/backend/src/db/migrations/meta/_journal.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "version": "5", - "dialect": "pg", - "entries": [ - { - "idx": 0, - "version": "5", - "when": 1712234094947, - "tag": "0000_dry_silver_centurion", - "breakpoints": true - }, - { - "idx": 1, - "version": "5", - "when": 1712236056306, - "tag": "0001_flawless_nehzno", - "breakpoints": true - }, - { - "idx": 2, - "version": "5", - "when": 1713181694478, - "tag": "0002_medical_darwin", - "breakpoints": true - }, - { - "idx": 3, - "version": "5", - "when": 1713519385365, - "tag": "0003_giant_thaddeus_ross", - "breakpoints": true - }, - { - "idx": 4, - "version": "5", - "when": 1713519395837, - "tag": "0004_thin_gorgon", - "breakpoints": true - }, - { - "idx": 5, - "version": "5", - "when": 1713774641394, - "tag": "0005_first_madripoor", - "breakpoints": true - }, - { - "idx": 6, - "version": "5", - "when": 1714064842098, - "tag": "0006_light_rocket_raccoon", - "breakpoints": true - }, - { - "idx": 7, - "version": "5", - "when": 1714482438641, - "tag": "0007_breezy_zarek", - "breakpoints": true - }, - { - "idx": 8, - "version": "5", - "when": 1714484046651, - "tag": "0008_fearless_angel", - "breakpoints": true - }, - { - "idx": 9, - "version": "5", - "when": 1714738112834, - "tag": "0009_gray_whizzer", - "breakpoints": true - } - ] -} diff --git a/backend/src/db/plugin.ts b/backend/src/db/plugin.ts index 6d5cdbb5..5e325052 100644 --- a/backend/src/db/plugin.ts +++ b/backend/src/db/plugin.ts @@ -31,6 +31,8 @@ const plugin: FastifyPluginCallback = (fastify, opts: Fas const client = postgres(opts.connectionString, { max: 1, onnotice }) await migrate(client) + console.log('done') + fastify.log.info('Database migration finished') }) diff --git a/backend/src/routes/getBalance.ts b/backend/src/routes/getBalance.ts index 9ec154d6..07686ac1 100644 --- a/backend/src/routes/getBalance.ts +++ b/backend/src/routes/getBalance.ts @@ -1,4 +1,4 @@ -import { eq } from 'drizzle-orm/pg-core/expressions' +import { eq, max } from 'drizzle-orm' import type { FastifyInstance } from 'fastify' import { usdcBalance } from '@/db/schema' @@ -23,11 +23,17 @@ export function getBalanceRoute(fastify: FastifyInstance) { try { // Use Drizzle ORM to find the balance by address - const balanceRecord = await fastify.db.query.usdcBalance - .findFirst({ where: eq(usdcBalance.address, address) }) + const balanceRecord = await fastify.db + .select({ + cursor: max(usdcBalance.cursor), + balance: usdcBalance.balance, + }) + .from(usdcBalance) + .where(eq(usdcBalance.address, address)) + .groupBy(usdcBalance.balance) .execute() - const balance = balanceRecord?.balance ?? '0' + const balance = balanceRecord[0]?.balance ?? '0' return reply.send({ balance }) } catch (error) { diff --git a/infra/indexers/.gitignore b/infra/indexers/.gitignore new file mode 100644 index 00000000..722d5e71 --- /dev/null +++ b/infra/indexers/.gitignore @@ -0,0 +1 @@ +.vscode diff --git a/infra/indexers/docker-compose.yml b/infra/indexers/docker-compose.yml deleted file mode 100644 index c217a245..00000000 --- a/infra/indexers/docker-compose.yml +++ /dev/null @@ -1,45 +0,0 @@ -version: "3.8" - -services: - postgres: - image: postgres:latest - environment: - POSTGRES_DB: indexer - POSTGRES_USER: admin - POSTGRES_PASSWORD: password - ports: - - "5432:5432" - volumes: - - ./init.sql:/docker-entrypoint-initdb.d/init.sql - networks: - - backend - - usdc-transfers-indexer: - environment: - - AUTH_TOKEN=${AUTH_TOKEN} - image: quay.io/apibara/sink-postgres:latest - command: "run ./indexer/usdc-transfers.indexer.ts --connection-string postgresql://admin:password@postgres:5432/indexer -A ${AUTH_TOKEN}" - volumes: - - ./src:/indexer - depends_on: - - postgres - networks: - - backend - restart: on-failure - - usdc-balances-indexer: - environment: - - AUTH_TOKEN=${AUTH_TOKEN} - image: quay.io/apibara/sink-postgres:latest - command: "run ./indexer/usdc-balances.indexer.ts --connection-string postgresql://admin:password@postgres:5432/indexer -A ${AUTH_TOKEN}" - volumes: - - ./src:/indexer - depends_on: - - postgres - networks: - - backend - restart: on-failure - -networks: - backend: - driver: bridge diff --git a/infra/indexers/envs.example.yaml b/infra/indexers/envs.example.yaml deleted file mode 100644 index e95c4fdd..00000000 --- a/infra/indexers/envs.example.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - namespace: default - name: apibara-api-key -stringData: - production: dna_XXX # replace with your production key - ---- -apiVersion: v1 -kind: Secret -metadata: - namespace: default - name: database-connection-string -stringData: - production: your_postgres_connection_string # replace with postgres connection string - -# To apply : -# kubectl apply -f envs.yaml diff --git a/infra/indexers/init.sql b/infra/indexers/init.sql deleted file mode 100644 index 3fc49457..00000000 --- a/infra/indexers/init.sql +++ /dev/null @@ -1,22 +0,0 @@ -create table transfer_usdc( - network text, - block_hash text, - block_number bigint, - block_timestamp timestamp, - transaction_hash text, - transfer_id text unique primary key, - from_address text, - to_address text, - amount text, - created_at timestamp default current_timestamp, - _cursor bigint -); - -create table balance_usdc( - network text, - block_number bigint, - block_timestamp timestamp, - address text, - balance text, - _cursor bigint -); \ No newline at end of file diff --git a/infra/indexers/k8indexer.yml b/infra/indexers/k8indexer.yml deleted file mode 100644 index b7f8acd3..00000000 --- a/infra/indexers/k8indexer.yml +++ /dev/null @@ -1,26 +0,0 @@ -apiVersion: apibara.com/v1alpha2 -kind: Indexer -metadata: - namespace: default - name: k8indexer -spec: - source: - gitHub: - repo: vault - owner: keep-starknet-strange - revision: main - subpath: Infra/Indexers - sink: - script: usdc.indexer.js - type: postgres - env: - - name: AUTH_TOKEN - valueFrom: - secretKeyRef: - name: apibara-api-key - key: production - - name: POSTGRES_CONNECTION_STRING - valueFrom: - secretKeyRef: - name: database-connection-string - key: production diff --git a/infra/indexers/src/constants.ts b/infra/indexers/src/constants.ts new file mode 100644 index 00000000..39830202 --- /dev/null +++ b/infra/indexers/src/constants.ts @@ -0,0 +1,3 @@ +export const STORAGE_ADDRESS_BOUND = 2n ** 251n + +export const USDC_ADDRESS = '0x07ab0b8855a61f480b4423c46c32fa7c553f0aac3531bbddaa282d86244f7a23' diff --git a/infra/indexers/src/deps.ts b/infra/indexers/src/deps.ts index 2a414f7b..a14b8480 100644 --- a/infra/indexers/src/deps.ts +++ b/infra/indexers/src/deps.ts @@ -1,8 +1,7 @@ -export { ec, hash, uint256 } from "https://esm.sh/starknet@5.14"; -export { formatUnits } from "https://esm.sh/viem@1.4"; +export { ec, hash, uint256 } from 'https://esm.sh/starknet@5.14' export type { Block, FieldElement, Filter, -} from "https://esm.sh/@apibara/indexer@0.3/starknet"; +} from 'https://esm.sh/@apibara/indexer@0.3/starknet' diff --git a/infra/indexers/src/usdc-balances.indexer.ts b/infra/indexers/src/usdc-balances.indexer.ts index 071e5d1e..e94e1b86 100644 --- a/infra/indexers/src/usdc-balances.indexer.ts +++ b/infra/indexers/src/usdc-balances.indexer.ts @@ -1,12 +1,12 @@ +import { USDC_ADDRESS } from './constants.ts'; import { Block, FieldElement, Filter, - formatUnits, hash, uint256, -} from "./deps.ts"; -import { balanceStorageLocation, USDC_ADDRESS, USDC_DECIMALS } from "./usdc.ts"; +} from './deps.ts' +import { getStorageLocation } from './utils.ts' const filter: Filter = { header: { @@ -15,77 +15,84 @@ const filter: Filter = { events: [ { fromAddress: USDC_ADDRESS, - keys: [hash.getSelectorFromName("Transfer") as FieldElement], + keys: [hash.getSelectorFromName('Transfer') as FieldElement], includeReceipt: false, }, ], stateUpdate: { storageDiffs: [{ contractAddress: USDC_ADDRESS }], }, -}; +} -let streamUrl = - (Deno.env.get("NETWORK") || "testnet") === "MAINNET" - ? "https://mainnet.starknet.a5a.ch" - : "https://sepolia.starknet.a5a.ch"; -let startingBlock = Number(Deno.env.get("STARTING_BLOCK")) || 0; +// TODO: multiple chains support +const streamUrl = 'https://sepolia.starknet.a5a.ch' +const startingBlock = Number(Deno.env.get('STARTING_BLOCK')) ?? 0 export const config = { streamUrl, startingBlock, - network: "starknet", - finality: "DATA_STATUS_ACCEPTED", + network: 'starknet', + finality: 'DATA_STATUS_ACCEPTED', filter, - sinkType: "postgres", + sinkType: 'postgres', sinkOptions: { - tableName: "balance_usdc", + tableName: 'balance_usdc', }, -}; +} export default function decodeUSDCBalances({ header, events, stateUpdate, }: Block) { - const { blockNumber, timestamp } = header!; + const { blockNumber, timestamp } = header! // Step 1: collect addresses that have been part of a transfer. - const addresses = (events ?? []).reduce((addresses, { event }) => { - const [fromAddress, toAddress] = event.data; - addresses.add(fromAddress); - addresses.add(toAddress); - return addresses; - }, new Set()); + const addresses = (events ?? []).reduce>((acc, { event }) => { + if (!event.data) return acc + + const [fromAddress, toAddress] = event.data + + acc.add(fromAddress) + acc.add(toAddress) + + return acc + }, new Set()) // Step 2: collect balances for each address. - const storageDiffs = stateUpdate?.stateDiff?.storageDiffs ?? []; - if (storageDiffs.length !== 1) { - throw new Error("Inconsistent state update."); - } + const storageMap = new Map() + const storageDiffs = stateUpdate?.stateDiff?.storageDiffs ?? [] + + for (const storageDiff of storageDiffs) { + for (const storageEntry of storageDiff.storageEntries ?? []) { + if (!storageEntry.key || !storageEntry.value) { + continue + } - const storageEntries = storageDiffs[0].storageEntries; + const key = BigInt(storageEntry.key) + const value = BigInt(storageEntry.value) + + storageMap.set(key, value) + } + } return Array.from(addresses).map((address) => { - const location = balanceStorageLocation(address); - // Notice that balances may use 2 felts. - const entryLow = storageEntries.find( - (entry) => BigInt(entry.key) === location, - ); - const entryHigh = storageEntries.find( - (entry) => BigInt(entry.key) === location + 1n, - ); + const addressBalanceLocation = getStorageLocation(address, 'balances') + + const addressBalanceLow = storageMap.get(addressBalanceLocation) + const addressBalanceHigh = storageMap.get(addressBalanceLocation + 1n) const balanceBn = uint256.uint256ToBN({ - low: entryLow?.value ?? 0n, - high: entryHigh?.value ?? 0n, - }); + low: addressBalanceLow ?? 0n, + high: addressBalanceHigh ?? 0n, + }) return { - network: "starknet-mainnet", - block_number: +blockNumber, + network: 'starknet-sepolia', + block_number: +(blockNumber ?? 0), block_timestamp: timestamp, address, - balance: formatUnits(balanceBn, USDC_DECIMALS), - }; - }); + balance: balanceBn.toString(), + } + }) } diff --git a/infra/indexers/src/usdc-transfers.indexer.ts b/infra/indexers/src/usdc-transfers.indexer.ts index 3896f92b..33273139 100644 --- a/infra/indexers/src/usdc-transfers.indexer.ts +++ b/infra/indexers/src/usdc-transfers.indexer.ts @@ -1,5 +1,5 @@ -import { Block, formatUnits, hash, uint256 } from "./deps.ts"; -import { USDC_ADDRESS, USDC_DECIMALS } from "./usdc.ts"; +import { USDC_ADDRESS } from './constants.ts'; +import { Block, hash, uint256 } from './deps.ts' const filter = { header: { @@ -8,57 +8,58 @@ const filter = { events: [ { fromAddress: USDC_ADDRESS, - keys: [hash.getSelectorFromName("Transfer")], + keys: [hash.getSelectorFromName('Transfer')], includeReceipt: false, }, ], -}; +} -let streamUrl = - (Deno.env.get("NETWORK") || "testnet") === "MAINNET" - ? "https://mainnet.starknet.a5a.ch" - : "https://sepolia.starknet.a5a.ch"; -let startingBlock = Number(Deno.env.get("STARTING_BLOCK")) || 0; +// TODO: multiple chains support +const streamUrl = 'https://sepolia.starknet.a5a.ch' +const startingBlock = Number(Deno.env.get('STARTING_BLOCK')) ?? 0 export const config = { streamUrl, startingBlock, - network: "starknet", - finality: "DATA_STATUS_ACCEPTED", + network: 'starknet', + finality: 'DATA_STATUS_ACCEPTED', filter, - sinkType: "postgres", + sinkType: 'postgres', sinkOptions: { - tableName: "transfer_usdc", + tableName: 'transfer_usdc', }, -}; +} export default function decodeUSDCTransfers({ header, events }: Block) { - const { blockNumber, blockHash, timestamp } = header!; + const { blockNumber, blockHash, timestamp } = header! + + return (events ?? []) + .map(({ event, transaction }) => { + if (!event.data) return null - return (events ?? []).map(({ event, transaction }) => { - const transactionHash = transaction.meta.hash; - const transferId = `${transactionHash}_${event.index ?? 0}`; + const transactionHash = transaction.meta.hash + const transferId = `${transactionHash}_${event.index ?? 0}` - const [fromAddress, toAddress, amountAddedLow, amountAddedHigh] = - event.data; + const [fromAddress, toAddress, amountAddedLow, amountAddedHigh] = + event.data - const amountBn = uint256.uint256ToBN({ - low: amountAddedLow, - high: amountAddedHigh, - }); - const amount = formatUnits(amountBn, USDC_DECIMALS); + const amountBn = uint256.uint256ToBN({ + low: amountAddedLow, + high: amountAddedHigh, + }) - return { - network: "starknet-mainnet", - block_hash: blockHash, - block_number: +blockNumber, - block_timestamp: timestamp, - transaction_hash: transactionHash, - transfer_id: transferId, - from_address: fromAddress, - to_address: toAddress, - amount, - created_at: new Date().toISOString(), - }; - }); + return { + network: 'starknet-sepolia', + block_hash: blockHash, + block_number: +(blockNumber ?? 0), + block_timestamp: timestamp, + transaction_hash: transactionHash, + transfer_id: transferId, + from_address: fromAddress, + to_address: toAddress, + amount: amountBn.toString(), + created_at: new Date().toISOString(), + } + }) + .filter(Boolean) } diff --git a/infra/indexers/src/usdc.ts b/infra/indexers/src/usdc.ts deleted file mode 100644 index 0449bcfe..00000000 --- a/infra/indexers/src/usdc.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ec, hash } from "./deps.ts"; - -export const USDC_ADDRESS = - "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8"; - -export const USDC_DECIMALS = 6; - -/** - * Computes the storage location of the balance of an address. - * - * @param address The address. - * @returns The storage location. - */ -export function balanceStorageLocation(address: string) { - const addressBound = 2n ** 251n; - - let hashed = hash.getSelectorFromName("ERC20_balances"); - hashed = ec.starkCurve.pedersen(hashed, address); - - let location = BigInt(hashed); - if (location >= addressBound) { - location -= addressBound; - } - - return location; -} diff --git a/infra/indexers/src/utils.ts b/infra/indexers/src/utils.ts new file mode 100644 index 00000000..80a16252 --- /dev/null +++ b/infra/indexers/src/utils.ts @@ -0,0 +1,16 @@ +import { STORAGE_ADDRESS_BOUND } from './constants.ts' +import { ec, hash } from './deps.ts' + +/** + * Computes the storage location of the balance of an address. + * + * @param address The address. + * @param address The name of the slot. + * @returns The storage location. + */ +export function getStorageLocation(address: string, name: string): bigint { + const hashedName = hash.getSelectorFromName(name) + const location = BigInt(ec.starkCurve.pedersen(hashedName, address)) + + return location >= STORAGE_ADDRESS_BOUND ? location - STORAGE_ADDRESS_BOUND : location +}