rely-sqlite-main.go raw
1 //go:build ignore
2 // +build ignore
3
4 package main
5
6 import (
7 "context"
8 "log"
9 "os"
10 "os/signal"
11 "syscall"
12 "time"
13
14 "github.com/nbd-wtf/go-nostr"
15 sqlite "github.com/vertex-lab/nostr-sqlite"
16 "github.com/pippellia-btc/rely"
17 )
18
19 func main() {
20 ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
21 defer cancel()
22
23 // Get configuration from environment with defaults
24 dbPath := os.Getenv("DATABASE_PATH")
25 if dbPath == "" {
26 dbPath = "./relay.db"
27 }
28
29 listenAddr := os.Getenv("RELAY_LISTEN")
30 if listenAddr == "" {
31 listenAddr = "0.0.0.0:3334"
32 }
33
34 // Initialize database
35 db, err := sqlite.New(dbPath)
36 if err != nil {
37 log.Fatalf("failed to initialize database: %v", err)
38 }
39 defer db.Close()
40
41 // Create relay with handlers
42 relay := rely.NewRelay(
43 rely.WithQueueCapacity(10_000),
44 rely.WithMaxProcessors(10),
45 )
46
47 // Register event handlers using the correct API
48 relay.On.Event = Save(db)
49 relay.On.Req = Query(db)
50 relay.On.Count = Count(db)
51
52 // Start relay
53 log.Printf("Starting rely-sqlite on %s with database %s", listenAddr, dbPath)
54 err = relay.StartAndServe(ctx, listenAddr)
55 if err != nil {
56 log.Fatalf("relay failed: %v", err)
57 }
58 }
59
60 // Save handles incoming events
61 func Save(db *sqlite.Store) func(_ rely.Client, e *nostr.Event) error {
62 return func(_ rely.Client, e *nostr.Event) error {
63 ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
64 defer cancel()
65
66 switch {
67 case nostr.IsRegularKind(e.Kind):
68 _, err := db.Save(ctx, e)
69 return err
70 case nostr.IsReplaceableKind(e.Kind) || nostr.IsAddressableKind(e.Kind):
71 _, err := db.Replace(ctx, e)
72 return err
73 default:
74 return nil
75 }
76 }
77 }
78
79 // Query retrieves events matching filters
80 func Query(db *sqlite.Store) func(ctx context.Context, _ rely.Client, filters nostr.Filters) ([]nostr.Event, error) {
81 return func(ctx context.Context, _ rely.Client, filters nostr.Filters) ([]nostr.Event, error) {
82 ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
83 defer cancel()
84 return db.Query(ctx, filters...)
85 }
86 }
87
88 // Count counts events matching filters
89 func Count(db *sqlite.Store) func(_ rely.Client, filters nostr.Filters) (count int64, approx bool, err error) {
90 return func(_ rely.Client, filters nostr.Filters) (count int64, approx bool, err error) {
91 ctx, cancel := context.WithTimeout(context.Background(), time.Second)
92 defer cancel()
93 count, err = db.Count(ctx, filters...)
94 if err != nil {
95 return -1, false, err
96 }
97 return count, false, nil
98 }
99 }
100