Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
7e73fd9
feat: custom indexer trades
pradel Mar 20, 2025
cae1e87
start schemas
pradel Mar 20, 2025
6b308c2
Update docker-compose.yml
pradel Mar 20, 2025
70b4ffe
start some logic
pradel Mar 20, 2025
99ba030
Update create-pool.ts
pradel Mar 20, 2025
af9fc82
more logic
pradel Mar 20, 2025
b098d2c
get logic working
pradel Mar 20, 2025
eec0e83
more
pradel Mar 20, 2025
6072d9f
chainhook logic
pradel Mar 20, 2025
017703c
Update webhook.post.ts
pradel Mar 20, 2025
69c33a2
properly handle pool creation
pradel Mar 21, 2025
9e8db87
start swap logic
pradel Mar 21, 2025
7bfb59e
fix logic
pradel Mar 21, 2025
b5eac6c
Update chainhook.ts
pradel Mar 21, 2025
5e85b4f
tmp
pradel Mar 25, 2025
e9f6d22
add docker config
pradel Mar 25, 2025
371af7a
Update Dockerfile
pradel Mar 25, 2025
f31dd17
fix
pradel Mar 25, 2025
0c7fac7
Update .env.production.local
pradel Mar 25, 2025
7156457
Create health.get.ts
pradel Mar 25, 2025
8078946
fix API_URL
pradel Mar 25, 2025
d60eb71
try fix
pradel Mar 25, 2025
3b73a19
fix
pradel Mar 25, 2025
579452f
prisma fix
pradel Mar 25, 2025
7bf641a
use upsert
pradel Mar 25, 2025
80b2e21
Update token.ts
pradel Mar 25, 2025
68e7b80
feat: save blocks
pradel Mar 25, 2025
6b0a48e
Update create-pool.ts
pradel Mar 25, 2025
88c021a
upsert
pradel Mar 25, 2025
a177055
fix casting
pradel Mar 25, 2025
6114334
migration
pradel Mar 25, 2025
f81a54e
deps
pradel Mar 25, 2025
9ade7e7
retry
pradel Mar 25, 2025
e462e75
Update create-pool.ts
pradel Mar 25, 2025
4d893ec
Update swap.ts
pradel Mar 25, 2025
a4e4667
sender
pradel Mar 25, 2025
ec7dbb6
Update docker-compose.yml
pradel Mar 25, 2025
276063b
cleanup
pradel Mar 30, 2025
da19ba6
add more
pradel Apr 2, 2025
44328de
simple transactions
pradel Apr 2, 2025
83870dc
cleanup
pradel Apr 2, 2025
b1867f3
more
pradel Apr 2, 2025
901110a
more
pradel Apr 2, 2025
dd70ddb
more
pradel Apr 2, 2025
2b05ab1
add sender
pradel Apr 2, 2025
1804837
more
pradel Apr 2, 2025
31d2d0d
cleanup
pradel Apr 2, 2025
ce3bba3
cleanup
pradel Apr 2, 2025
feac368
cleanup
pradel Apr 2, 2025
caa4c47
cleanup
pradel Apr 2, 2025
e24d41e
arkadiko
pradel Apr 2, 2025
32eabfb
stackingdao
pradel Apr 2, 2025
c37518c
cleanup
pradel Apr 2, 2025
4a49c60
cleanup
pradel Apr 2, 2025
90046a1
bitflow
pradel Apr 2, 2025
9c5299f
velar
pradel Apr 2, 2025
926cf58
zest
pradel Apr 2, 2025
72d66fd
Update stackingdao.ts
pradel Apr 2, 2025
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
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
**/.next
**/.turbo
**/dist
**/node_modules
2 changes: 2 additions & 0 deletions apps/server-indexer/.env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
NODE_ENV="development"
DATABASE_URL="postgres://stackspulse_user:stackspulse_password@host.docker.internal:5432/stackspulse_db?sslmode=disable"
10 changes: 10 additions & 0 deletions apps/server-indexer/.env.production.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
#/ public-key encryption for .env files /
#/ [how it works](https://dotenvx.com/encryption) /
#/----------------------------------------------------------/
DOTENV_PUBLIC_KEY_PRODUCTION_LOCAL="020b21e579eb9b260c6f4df063b2debf2769d1ca3433ae8ba534dd46bd1cbb7470"

CHAINHOOK_API_TOKEN="encrypted:BLnIh7ANBx7mOuxQ+cqmP/TCa1oulsmvmg9e0MxEOFiW65Gjhqdo+j/A8mxHtcpUpy7667PofS9fo4jZ/bmwznONXmT5bagShhaLCMhLRpsL6LCrZeE2uUxHlh0oSmfuReVTo97Jjrt9V6TOb3qEvec8bGkMb/U="
HIRO_API_KEY="encrypted:BFFWs2gEypPBt37J2Ao4CzixUptsZzmZKZtQlNlzsQz/UzzTBayEFIs4mFlDKNiiBEQvYHydMnphz+4wwPxucX8XeWXZy0ECKvF75Cuqfs2hyULH3N2FGSyyVHjTAO0bSEjWDe4zz4BTQvBImNuSNLMJoF+cwRxq+O0XMfawzbzz"
DATABASE_URL="encrypted:BL3Z52ueVM4H+2fOtMyD2Ld2OLnbNjIrK8nqT6Bkwb+vwUij0VrX8vh3PAc1SJ93LEqGRM7U9sJINWbCHQRzYfg3g7/Nq8WRpdhep9UedkSHFvbjPtgFAIsVMMEaWL05/A/vS6nsB9GdKnqPv2lnk6rL33LrG0t6Q00FYAlhxS5Yp4pMDrSVIkVN9ZwMxO4anhxuhW2cCTdcf7uMhiXOWmrJz/s7a3Q2lt4LAzt0V02ZQ7vGkNfBa2Jw8tmDQQ=="
API_URL="encrypted:BDp4gf+4665J6DIusV7qQOR1f21bv3r9spZlvq7NzZFC22e0PlcjLgV8Z6qiCXE5i/qaa8cgnlGbZc3/m84LPSluxIdiJHcO6/x3u4SN4KzMAkAEPnhZ2CRKxZ1IJ/Hps4mfIK3D3gSJIWH/OjsZCq/dVKaTxkJJJrdfYaqjgzgGdpIInah1pARSVN+1CRsMfA=="
12 changes: 12 additions & 0 deletions apps/server-indexer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
node_modules
dist
.data
.nitro
.cache
.output
.env

# local env files
.env*.local
.env.keys
!.env.production.local
72 changes: 72 additions & 0 deletions apps/server-indexer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
ARG NODE_VERSION=22
FROM node:${NODE_VERSION}-alpine AS base

WORKDIR /app

# Set production environment
ENV NODE_ENV="production"
ENV APP_NAME="server-indexer"

# Install pnpm
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
COPY --link ./package.json ./
RUN npm install -g corepack@latest # fix for https://github.com/nodejs/corepack/issues/612
RUN corepack enable pnpm
RUN pnpm install turbo@^2 --global
RUN pnpm install @dotenvx/dotenvx@^1 --global

# --- Turbo stage ---

FROM base AS builder
WORKDIR /app
COPY . .
RUN turbo prune @stackspulse/$APP_NAME --docker

# --- Build stage ---

FROM base AS installer
WORKDIR /app

RUN apk update && \
apk add --no-cache libc6-compat python3 g++ make

# First install the dependencies (as they change less often)
COPY .gitignore .gitignore
COPY --from=builder /app/out/json/ .
COPY --from=builder /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
COPY --from=builder /app/out/pnpm-workspace.yaml ./pnpm-workspace.yaml
RUN pnpm install --frozen-lockfile --prod=false

COPY --from=builder /app/out/full/ .
COPY turbo.json turbo.json

WORKDIR /app/apps/$APP_NAME

# Build application
RUN turbo run db:generate --filter=@stackspulse/$APP_NAME
RUN turbo run build --filter=@stackspulse/$APP_NAME...

# --- Runner stage ---

FROM base AS runner
WORKDIR /app

# Don't run production as root
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nitro

# Copy built application
COPY --from=installer --chown=nitro:nodejs /app/apps/$APP_NAME/.output ./.output
COPY --from=installer --chown=nitro:nodejs /app/apps/$APP_NAME/package.json ./package.json
COPY --from=installer --chown=nitro:nodejs /app/apps/$APP_NAME/scripts ./scripts
COPY --from=installer --chown=nitro:nodejs /app/apps/$APP_NAME/prisma ./prisma
COPY --from=builder --chown=nitro:nodejs /app/apps/$APP_NAME/.env.production.local ./.env.production.local
RUN node scripts/prod-deps.cjs
RUN pnpm install

USER nitro

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD dotenvx run -- node .output/server/index.mjs
48 changes: 48 additions & 0 deletions apps/server-indexer/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
ARG NODE_VERSION=22
FROM node:${NODE_VERSION}-alpine AS base

WORKDIR /app

ENV APP_NAME="server-indexer"

ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
COPY --link ./package.json ./
RUN npm install -g corepack@latest # fix for https://github.com/nodejs/corepack/issues/612
RUN corepack enable pnpm
RUN pnpm install turbo@^2 --global
RUN pnpm install @dotenvx/dotenvx@^1 --global
RUN apk update; \
apk add --no-cache openssl;

# --- Turbo stage ---

FROM base AS builder
# Set working directory
WORKDIR /app
COPY . .
RUN turbo prune @stackspulse/$APP_NAME --docker

# --- Build stage ---

# Add lockfile and package.json's of isolated subworkspace
FROM base AS installer
WORKDIR /app

# First install dependencies (as they change less often)
COPY .gitignore .gitignore
COPY --from=builder /app/out/json/ .
COPY --from=builder /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
COPY --from=builder /app/out/pnpm-workspace.yaml ./pnpm-workspace.yaml
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile

# Build the project and its dependencies
COPY --from=builder /app/out/full/ .
COPY ./apps/$APP_NAME/.env.development.local ./apps/$APP_NAME/.env.development.local
COPY turbo.json turbo.json

WORKDIR /app/apps/$APP_NAME

RUN pnpm prisma generate

CMD pnpm prisma migrate deploy && turbo run dev
3 changes: 3 additions & 0 deletions apps/server-indexer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Nitro starter

Look at the [nitro quick start](https://nitro.unjs.io/guide#quick-start) to learn more how to get started.
9 changes: 9 additions & 0 deletions apps/server-indexer/nitro.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default defineNitroConfig({
compatibilityDate: "2025-03-20",
srcDir: "src",
esbuild: {
options: {
target: "esnext",
},
},
});
32 changes: 32 additions & 0 deletions apps/server-indexer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "@stackspulse/server-indexer",
"version": "0.20.2",
"private": true,
"type": "module",
"packageManager": "pnpm@9.15.5",
"scripts": {
"build": "nitro build",
"db:generate": "prisma generate",
"db:migrate:prod": "prisma migrate deploy",
"dev": "dotenvx run --env-file=.env.development --env-file=.env.development.local -- nitro dev --port 3001",
"prepare": "nitro prepare",
"prisma:migrate:dev": "dotenvx run --env-file=.env.development -- prisma migrate dev",
"prisma:migrate:reset": "dotenvx run --env-file=.env.development -- prisma migrate reset",
"prisma:studio:dev": "dotenvx run --env-file=.env.development -- prisma studio",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@dotenvx/dotenvx": "1.39.0",
"@hirosystems/chainhook-client": "2.3.0",
"@prisma/client": "6.5.0",
"@stacks/blockchain-api-client": "8.7.0",
"@stacks/transactions": "7.0.5",
"@t3-oss/env-core": "0.12.0",
"consola": "3.4.2",
"prisma": "6.5.0",
"zod": "3.24.2"
},
"devDependencies": {
"nitropack": "2.11.7"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- CreateTable
CREATE TABLE "Transaction" (
"id" TEXT NOT NULL,
"block_height" BIGINT NOT NULL,
"timestamp" BIGINT NOT NULL,

CONSTRAINT "Transaction_pkey" PRIMARY KEY ("id")
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- CreateTable
CREATE TABLE "Token" (
"id" TEXT NOT NULL,
"decimals" INTEGER NOT NULL,
"tx_count" BIGINT NOT NULL,
"pool_count" INTEGER NOT NULL,

CONSTRAINT "Token_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Pool" (
"id" TEXT NOT NULL,
"token0_id" TEXT NOT NULL,
"token1_id" TEXT NOT NULL,
"tx_count" BIGINT NOT NULL,

CONSTRAINT "Pool_pkey" PRIMARY KEY ("id")
);

-- AddForeignKey
ALTER TABLE "Pool" ADD CONSTRAINT "Pool_token0_id_fkey" FOREIGN KEY ("token0_id") REFERENCES "Token"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Pool" ADD CONSTRAINT "Pool_token1_id_fkey" FOREIGN KEY ("token1_id") REFERENCES "Token"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
Warnings:

- Added the required column `name` to the `Token` table without a default value. This is not possible if the table is not empty.
- Added the required column `symbol` to the `Token` table without a default value. This is not possible if the table is not empty.

*/
-- AlterTable
ALTER TABLE "Token" ADD COLUMN "name" TEXT NOT NULL,
ADD COLUMN "symbol" TEXT NOT NULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-- CreateTable
CREATE TABLE "Swap" (
"id" TEXT NOT NULL,
"pool_id" TEXT NOT NULL,
"token0_id" TEXT NOT NULL,
"token1_id" TEXT NOT NULL,
"amount0" BIGINT NOT NULL,
"amount1" BIGINT NOT NULL,
"tx_index" INTEGER NOT NULL,

CONSTRAINT "Swap_pkey" PRIMARY KEY ("id")
);

-- AddForeignKey
ALTER TABLE "Swap" ADD CONSTRAINT "Swap_pool_id_fkey" FOREIGN KEY ("pool_id") REFERENCES "Pool"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Swap" ADD CONSTRAINT "Swap_token0_id_fkey" FOREIGN KEY ("token0_id") REFERENCES "Token"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Swap" ADD CONSTRAINT "Swap_token1_id_fkey" FOREIGN KEY ("token1_id") REFERENCES "Token"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- CreateTable
CREATE TABLE "Block" (
"height" BIGINT NOT NULL,
"timestamp" INTEGER NOT NULL,

CONSTRAINT "Block_pkey" PRIMARY KEY ("height")
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Warnings:

- You are about to drop the column `timestamp` on the `Transaction` table. All the data in the column will be lost.

*/
-- AlterTable
ALTER TABLE "Transaction" DROP COLUMN "timestamp";

-- AddForeignKey
ALTER TABLE "Transaction" ADD CONSTRAINT "Transaction_block_height_fkey" FOREIGN KEY ("block_height") REFERENCES "Block"("height") ON DELETE RESTRICT ON UPDATE CASCADE;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
Warnings:

- Added the required column `sender` to the `Swap` table without a default value. This is not possible if the table is not empty.

*/
-- AlterTable
ALTER TABLE "Swap" ADD COLUMN "sender" TEXT NOT NULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
Warnings:

- You are about to drop the `Swap` table. If the table is not empty, all the data it contains will be lost.

*/
-- DropForeignKey
ALTER TABLE "Swap" DROP CONSTRAINT "Swap_pool_id_fkey";

-- DropForeignKey
ALTER TABLE "Swap" DROP CONSTRAINT "Swap_token0_id_fkey";

-- DropForeignKey
ALTER TABLE "Swap" DROP CONSTRAINT "Swap_token1_id_fkey";

-- DropTable
DROP TABLE "Swap";

-- CreateTable
CREATE TABLE "Trade" (
"id" TEXT NOT NULL,
"pool_id" TEXT NOT NULL,
"token0_id" TEXT NOT NULL,
"token1_id" TEXT NOT NULL,
"sender" TEXT NOT NULL,
"amount_in" BIGINT NOT NULL,
"amount_out" BIGINT NOT NULL,
"tx_index" INTEGER NOT NULL,

CONSTRAINT "Trade_pkey" PRIMARY KEY ("id")
);

-- AddForeignKey
ALTER TABLE "Trade" ADD CONSTRAINT "Trade_pool_id_fkey" FOREIGN KEY ("pool_id") REFERENCES "Pool"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Trade" ADD CONSTRAINT "Trade_token0_id_fkey" FOREIGN KEY ("token0_id") REFERENCES "Token"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Trade" ADD CONSTRAINT "Trade_token1_id_fkey" FOREIGN KEY ("token1_id") REFERENCES "Token"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
Warnings:

- The primary key for the `Block` table will be changed. If it partially fails, the table could be left without primary key constraint.
- You are about to alter the column `height` on the `Block` table. The data in that column could be lost. The data in that column will be cast from `BigInt` to `Integer`.
- You are about to alter the column `block_height` on the `Transaction` table. The data in that column could be lost. The data in that column will be cast from `BigInt` to `Integer`.
- Added the required column `contract_call_contract_id` to the `Transaction` table without a default value. This is not possible if the table is not empty.
- Added the required column `contract_call_function_name` to the `Transaction` table without a default value. This is not possible if the table is not empty.
- Added the required column `dapp_id` to the `Transaction` table without a default value. This is not possible if the table is not empty.
- Added the required column `index` to the `Transaction` table without a default value. This is not possible if the table is not empty.

*/
-- DropForeignKey
ALTER TABLE "Transaction" DROP CONSTRAINT "Transaction_block_height_fkey";

-- AlterTable
ALTER TABLE "Block" DROP CONSTRAINT "Block_pkey",
ALTER COLUMN "height" SET DATA TYPE INTEGER,
ADD CONSTRAINT "Block_pkey" PRIMARY KEY ("height");

-- AlterTable
ALTER TABLE "Transaction" ADD COLUMN "contract_call_contract_id" TEXT NOT NULL,
ADD COLUMN "contract_call_function_name" TEXT NOT NULL,
ADD COLUMN "dapp_id" TEXT NOT NULL,
ADD COLUMN "index" SMALLINT NOT NULL,
ALTER COLUMN "block_height" SET DATA TYPE INTEGER;

-- CreateTable
CREATE TABLE "Dapp" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL,
"updated_at" TIMESTAMP(3) NOT NULL,

CONSTRAINT "Dapp_pkey" PRIMARY KEY ("id")
);

-- AddForeignKey
ALTER TABLE "Transaction" ADD CONSTRAINT "Transaction_block_height_fkey" FOREIGN KEY ("block_height") REFERENCES "Block"("height") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Transaction" ADD CONSTRAINT "Transaction_dapp_id_fkey" FOREIGN KEY ("dapp_id") REFERENCES "Dapp"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
Warnings:

- Added the required column `sender` to the `Transaction` table without a default value. This is not possible if the table is not empty.

*/
-- AlterTable
ALTER TABLE "Transaction" ADD COLUMN "sender" TEXT NOT NULL;
3 changes: 3 additions & 0 deletions apps/server-indexer/prisma/migrations/migration_lock.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "postgresql"
Loading