Files
zeekay a9497e711c api-go: Go port scaffold (foundation + auth + chains + projects + wallets)
Lays down the Go skeleton parallel to api/ (FastAPI). Foundation:
  - config: env-driven Settings
  - db: pgx pool + idempotent schema migrations + typed row structs
  - iam: HS256 JWT Verifier + bearer-auth middleware
  - api: chi router with /healthz + /readyz + versioned /v1 mount

Routes ported:
  - /auth: login + signup + refresh (bcrypt + JWT)
  - /chains: registry + status
  - /projects: full CRUD scoped by org
  - /wallets: list + create scoped by project+org

Stubs (route wired, handler returns 501):
  - /api-keys, /webhooks, /rpc, /tokens, /nfts

cmd/bootnode/main.go is the production entrypoint with graceful
shutdown (SIGINT/SIGTERM) and slog JSON logging. Dockerfile builds a
distroless image with CGO disabled.

Remaining surface to port (in order of priority): rpc upstream
dispatcher, api-keys CRUD + auth, tokens + nfts read-only, webhooks
delivery worker, fleet + node + cluster routes, bundler + gas, billing.
The Python service in api/ keeps running until parity ships.
2026-05-13 02:00:07 -07:00

50 lines
1.2 KiB
Go

// Package db — Postgres pool + migration entry.
package db
import (
"context"
"fmt"
"github.com/jackc/pgx/v5/pgxpool"
)
// Pool wraps pgxpool.Pool so callers depend on this package's type and
// the underlying driver can be swapped without breaking call sites.
type Pool = pgxpool.Pool
// Open creates a connection pool from the canonical DATABASE_URL.
func Open(ctx context.Context, dsn string, poolSize, maxOverflow int) (*Pool, error) {
cfg, err := pgxpool.ParseConfig(dsn)
if err != nil {
return nil, fmt.Errorf("parse dsn: %w", err)
}
cfg.MaxConns = int32(poolSize + maxOverflow)
cfg.MinConns = int32(poolSize / 4)
p, err := pgxpool.NewWithConfig(ctx, cfg)
if err != nil {
return nil, fmt.Errorf("connect: %w", err)
}
if err := p.Ping(ctx); err != nil {
p.Close()
return nil, fmt.Errorf("ping: %w", err)
}
return p, nil
}
// Init runs the schema migrations. Idempotent.
func Init(ctx context.Context, p *Pool) error {
for _, stmt := range schemaStatements {
if _, err := p.Exec(ctx, stmt); err != nil {
return fmt.Errorf("migration %q: %w", stmt[:min(len(stmt), 60)], err)
}
}
return nil
}
func min(a, b int) int {
if a < b {
return a
}
return b
}