initial public relay build repo
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
)
|
||||
|
||||
func envOr(key, fallback string) string {
|
||||
if v := os.Getenv(key); v != "" {
|
||||
return v
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
// envIntOr parses a non-negative integer env var, falling back on empty/invalid.
|
||||
func envIntOr(key string, fallback int) int {
|
||||
if v := os.Getenv(key); v != "" {
|
||||
if n, err := strconv.Atoi(v); err == nil && n >= 0 {
|
||||
return n
|
||||
}
|
||||
log.Printf("invalid %s=%q; using %d", key, v, fallback)
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
// loadOrGenerateKey resolves the relay's signing identity, which signs the group
|
||||
// metadata/admins/members events. A STABLE identity is required so those signed
|
||||
// lists remain valid across restarts and re-deploys.
|
||||
//
|
||||
// - RELAY_SECRET_KEY set → use it (production path).
|
||||
// - RELAY_ENV=production, unset → fatal. A fresh key each boot silently
|
||||
// corrupts signed group rosters, so we refuse to start.
|
||||
// - otherwise (dev) → persist a generated key under the data dir
|
||||
// and reuse it, so even dev keeps a stable identity across restarts.
|
||||
func loadOrGenerateKey(dataDir string) nostr.SecretKey {
|
||||
if hex := os.Getenv("RELAY_SECRET_KEY"); hex != "" {
|
||||
sk, err := nostr.SecretKeyFromHex(hex)
|
||||
if err != nil {
|
||||
log.Fatalf("invalid RELAY_SECRET_KEY: %v", err)
|
||||
}
|
||||
return sk
|
||||
}
|
||||
|
||||
if isProduction() {
|
||||
log.Fatal("RELAY_SECRET_KEY is required when RELAY_ENV=production " +
|
||||
"(a fresh key each boot would corrupt signed group rosters). " +
|
||||
"Generate one with: openssl rand -hex 32")
|
||||
}
|
||||
|
||||
// Dev convenience: persist a generated key so restarts keep one identity.
|
||||
keyPath := filepath.Join(dataDir, "relay.key")
|
||||
if data, err := os.ReadFile(keyPath); err == nil {
|
||||
if sk, err := nostr.SecretKeyFromHex(string(data)); err == nil {
|
||||
log.Printf("using persisted dev relay identity from %s", keyPath)
|
||||
return sk
|
||||
}
|
||||
log.Printf("ignoring unreadable %s; generating a new dev key", keyPath)
|
||||
}
|
||||
sk := nostr.Generate()
|
||||
if err := os.WriteFile(keyPath, []byte(sk.Hex()), 0o600); err != nil {
|
||||
log.Printf("could not persist dev relay key (%v); identity is ephemeral this run", err)
|
||||
} else {
|
||||
log.Printf("generated and persisted a dev relay identity at %s (set RELAY_SECRET_KEY for production)", keyPath)
|
||||
}
|
||||
return sk
|
||||
}
|
||||
|
||||
func isProduction() bool {
|
||||
return os.Getenv("RELAY_ENV") == "production"
|
||||
}
|
||||
Reference in New Issue
Block a user