No description
  • Go 92.8%
  • PLpgSQL 5.2%
  • Makefile 1.2%
  • Dockerfile 0.8%
Find a file
katakrdp b09e695f0e feat: add crypto-gateway solana payment processor
Implement a production-grade Go backend for accepting Solana payments in SOL,
USDC, and USDT with PostgreSQL persistence.

Key features:
- Deterministically derived ed25519 wallets per invoice to prevent fund collisions
- Idempotent write APIs with Idempotency-Key header support
- Rate limiting per API key
- Durable webhook delivery with exponential backoff and concurrent-safe queue draining
- Embedded database migrations applied on boot
- Minimal Solana JSON-RPC client for balance and transaction queries
- AES-256-GCM encryption for wallet secrets at rest

Project structure includes command-line tools (server, migrations, test wallet
generation), core domain logic, data access layer, HTTP API with chi router,
and background workers for scanning, webhook dispatch, and cleanup.

Includes comprehensive documentation, Docker setup, and configuration examples.
2026-05-20 14:41:56 +00:00
cmd feat: add crypto-gateway solana payment processor 2026-05-20 14:41:56 +00:00
internal feat: add crypto-gateway solana payment processor 2026-05-20 14:41:56 +00:00
.env.example feat: add crypto-gateway solana payment processor 2026-05-20 14:41:56 +00:00
.gitignore feat: add crypto-gateway solana payment processor 2026-05-20 14:41:56 +00:00
docker-compose.yml feat: add crypto-gateway solana payment processor 2026-05-20 14:41:56 +00:00
Dockerfile feat: add crypto-gateway solana payment processor 2026-05-20 14:41:56 +00:00
go.mod feat: add crypto-gateway solana payment processor 2026-05-20 14:41:56 +00:00
go.sum feat: add crypto-gateway solana payment processor 2026-05-20 14:41:56 +00:00
Makefile feat: add crypto-gateway solana payment processor 2026-05-20 14:41:56 +00:00
PRODUCTION.md feat: add crypto-gateway solana payment processor 2026-05-20 14:41:56 +00:00
README.md feat: add crypto-gateway solana payment processor 2026-05-20 14:41:56 +00:00
USAGE.md feat: add crypto-gateway solana payment processor 2026-05-20 14:41:56 +00:00

crypto-gateway

A production-style Go backend for accepting payments on Solana in SOL, USDC, and USDT, backed by PostgreSQL.

The service is built around a few non-negotiables:

  • Every invoice gets its own deterministically derived ed25519 wallet, so a given payer can never collide with another payer's funds.
  • All write APIs are idempotent (Idempotency-Key header) and rate-limited per API key.
  • Webhook delivery is durable: it survives restarts, retries with exponential backoff, and uses FOR UPDATE SKIP LOCKED so multiple replicas can drain the queue safely.
  • Database migrations are embedded in the binary; the server applies them on boot.

Project layout

cmd/
  server/        crypto-gateway HTTP + workers
  migrate/       apply database migrations and exit
  testwallet/    generate ed25519 keypairs for local testing
internal/
  config/        env-driven configuration with validation
  logger/        structured slog logger
  db/            pgx pool + embedded migrations
  domain/        core types (Invoice, Wallet, Payment, ...)
  repository/    Postgres data access layer
  chain/solana/  minimal JSON-RPC client (balances, sigs, txns)
  wallet/        ed25519 derivation + AES-256-GCM at-rest encryption
  service/       invoice, payment and webhook services
  httpapi/       chi router + handlers + middleware
  idempotency/   replay-safe POST middleware backed by Postgres
  ratelimit/     in-memory token bucket per API key/IP
  worker/        scanner, webhook dispatcher, janitor

Quick start

# 1. Boot Postgres
docker compose up -d postgres

# 2. Generate a master derivation secret + a fee-payer wallet
make wallet                            # one-off random keypair
go run ./cmd/testwallet -gen-secret    # 32-byte hex master secret

# 3. Configure the server
cp .env.example .env
# edit .env: set DATABASE_URL, WALLET_DERIVATION_SECRET, SOLANA_FEE_PAYER_SECRET

# 4. Run migrations and start the server
make migrate
make run

The server boots on :8080 by default. Health checks: GET /healthz, GET /readyz.

Creating an invoice

curl -sS -X POST http://localhost:8080/v1/invoices \
  -H "X-API-Key: dev-secret-please-change" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "reference": "order-42",
    "asset":     "USDC",
    "amount":    "12.50",
    "ttl":       "30m",
    "metadata":  {"customer_id": "u_001"}
  }'

Response (truncated):

{
  "id": "f5b3...e9",
  "reference": "order-42",
  "chain": "solana",
  "asset": "USDC",
  "amount": "12.5",
  "amount_received": "0",
  "address": "9xQe...derived address...",
  "status": "pending",
  "expires_at": "..."
}

The merchant should display address as the destination for the payer. The scanner watches that address and updates the invoice status to confirming, underpaid, or paid. On every status change a webhook is fired to the merchant's configured URL with header X-Gateway-Signature: sha256=<hmac of body using webhook_secret>.

Test wallets

Generate one or more wallets:

go run ./cmd/testwallet -count 3
go run ./cmd/testwallet -gen-secret
go run ./cmd/testwallet -derived -secret <hex32> -from 0 -count 5

Fund a devnet wallet:

solana airdrop 2 <address> --url https://api.devnet.solana.com

For SPL tokens, use spl-token transfer with the appropriate devnet mint or mint your own dev USDC.

Configuration

All configuration is environment-driven. See .env.example for the full list. Key items:

Variable Purpose
DATABASE_URL Postgres connection string
SOLANA_RPC_URL RPC endpoint (devnet / mainnet)
SOLANA_USDC_MINT / SOLANA_USDT_MINT Network-specific SPL token mints
WALLET_DERIVATION_SECRET Master HMAC secret used to derive invoice wallets
API_KEYS Comma list of <merchant>:<key> entries
RATE_LIMIT_RPS / RATE_LIMIT_BURST Per-key token bucket settings

Running the test suite

make test               # unit tests
make test-int           # integration tests (needs DATABASE_URL_TEST)

Operational notes

  • The HTTP server enforces a 1 MiB max request body, a 2048-request in-flight cap, request IDs, panic recovery, security headers, structured access logs, and per-key rate limiting before any handler runs.
  • Postgres connection pool sizes are configurable; defaults assume a single replica. Tune DB_MAX_CONNS and DB_MIN_CONNS for horizontal scale.
  • Workers are safe to run as multiple replicas: webhook delivery uses FOR UPDATE SKIP LOCKED, and the scanner is idempotent at the payment level (ON CONFLICT DO NOTHING on (chain, tx_signature, asset)).
  • Wallet secrets are encrypted at rest with AES-256-GCM, key derived from the master secret. The plaintext private key never leaves the gateway. A treasury sweep workflow is wired in (see cmd/server/main.go); enable it with SWEEPER_INTERVAL and a configured SOLANA_TREASURY_ADDRESS.

License

MIT