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