Skip to content

Latest commit

History

History
144 lines (121 loc) · 4.61 KB

File metadata and controls

144 lines (121 loc) · 4.61 KB

stackpay-backend 🪨

Indexer + REST/WebSocket API for StackPay — turns Soroban payment events into queryable requests, balances, and webhooks.

CITypeScriptNodeLicense: MIT

The off-chain brain of StackPay. The contract (stackpay-contracts) is the source of truth; this service keeps a materialized view so the dApp and integrators can query requests, statuses, and history without replaying ledgers.


Table of contents


What it does

  1. Indexesrequest_created, request_paid, request_cancelled events from Soroban RPC.
  2. Materializes request state into PostgreSQL.
  3. Serves a REST API for the dApp and partners.
  4. Streams live updates over WebSocket.
  5. Notifies via webhooks on payment.

Architecture

 Stellar RPC / Horizon
| poll ledger
v
+------------+ events +--------------+
| Indexer | -------> | PostgreSQL |
| (worker) | +------+-------+
+------------+ |
+-----v------+
| REST API |<-- dApp / partners
| (Express) |
+-----+------+
| publish
+-----v------+
| WebSocket |
| (Socket.IO)|
+------------+

Tech stack

  • Node.js 20 + TypeScript, Express, Socket.IO
  • PostgreSQL 16 (Prisma), Redis 7 (BullMQ)
  • @stellar/stellar-sdk for RPC/ledger access

Getting started

git clone https://github.com/Stack-Rocks/stackpay-backend.git
cd stackpay-backend
cp .env.example .env
npm install
npx prisma migrate dev
npm run dev

API at http://localhost:4000.

Configuration

See .env.example:

VariableDescription
PORTHTTP port (default 4000).
DATABASE_URLPostgreSQL connection string.
REDIS_URLRedis connection string.
STELLAR_RPC_URLSoroban RPC endpoint.
STELLAR_NETWORKtestnet | mainnet.
CONTRACT_PAYMENTDeployed PaymentRequest contract address.
START_LEDGERLedger to begin indexing from.

API reference

Base: http://localhost:4000/api/v1

Requests

MethodPathDescription
GET/requestsList requests (filter payee, payer, status, asset).
GET/requests/:idGet a request + on-chain status.
GET/requests/:id/historyEvent history.
GET/accounts/:address/requestsRequests involving an address.
GET/accounts/:address/receivedTotal received by an address.

Webhooks

MethodPathDescription
POST/webhooksRegister a URL to notify on request_paid.

Example:

curl http://localhost:4000/api/v1/requests/7
{ "id": 7, "payee": "GABC...", "asset": "C...", "amount": "5000000",
"memo": "Invoice #12", "status": "Paid" }

WebSocket events

Connect to ws://localhost:4000. Subscribe to a request room:

socket.emit("subscribe",{requestId: 7});socket.on("request:paid",(p)=>console.log(p));

Events: request:created, request:paid, request:cancelled.

Indexer internals

  • Polls getEvents in contiguous ledger windows; resumable via a stored last_ledger cursor.
  • Maps events to DB upserts keyed by contract + request_id.
  • Idempotent — safe to run a single worker replica.

Docker

docker compose up --build

Testing

npm run test# vitest (PG via testcontainers)
npm run test:e2e # against local soroban sandbox

Deployment

Stateless API behind any Node host; one long-running indexer worker; managed Postgres + Redis.

Contributing

Part of the Stellar Wave Program on Drips. Look for Stellar Wave / Good first issue. Run npm run lint && npm run test before a PR.

License

MIT.