mirror of
https://github.com/hanzoai/bootnode.git
synced 2026-10-25 02:31:30 +00:00
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.
50 lines
1.2 KiB
Go
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
|
|
}
|