diff --git a/go.mod b/go.mod index a5ede41..5a66817 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/lib/pq v1.10.3 github.com/mattn/go-sqlite3 v1.14.6 github.com/mmcdole/gofeed v1.1.3 - github.com/nbd-wtf/go-nostr v0.18.3 + github.com/nbd-wtf/go-nostr v0.18.10 github.com/rif/cache2go v1.0.0 github.com/rs/cors v1.7.0 github.com/stevelacy/daz v0.1.4 @@ -28,7 +28,6 @@ require ( require ( github.com/DataDog/zstd v1.4.5 // indirect github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect - github.com/SaveTheRbtz/generic-sync-map-go v0.0.0-20230201052002-6c5833b989be // indirect github.com/aead/siphash v1.0.1 // indirect github.com/andybalholm/cascadia v1.3.1 // indirect github.com/btcsuite/btcd v0.23.1 // indirect @@ -83,6 +82,7 @@ require ( github.com/modern-go/reflect2 v1.0.1 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/puzpuzpuz/xsync v1.5.2 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect diff --git a/go.sum b/go.sum index 9c51458..3893703 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,6 @@ github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4K github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U= github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI= -github.com/SaveTheRbtz/generic-sync-map-go v0.0.0-20230201052002-6c5833b989be h1:ZUMGZpetBeapAS/oOlffnBL6aSG6WwXSWfNXeadAzXE= -github.com/SaveTheRbtz/generic-sync-map-go v0.0.0-20230201052002-6c5833b989be/go.mod h1:ihkm1viTbO/LOsgdGoFPBSvzqvx7ibvkMzYp3CgtHik= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY= github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg= @@ -345,8 +343,8 @@ github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOA github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/nbd-wtf/go-nostr v0.18.3 h1:ofMYxlFAptyoErlOGOCUk7zGHQNJ8/ZkIXXOsveFZ+c= -github.com/nbd-wtf/go-nostr v0.18.3/go.mod h1:GPJOOK8US38kz+bfb9nWe873Xu0e6bXlThejOs1LTkc= +github.com/nbd-wtf/go-nostr v0.18.10 h1:9kD9U1QkAvqW4CH4CdKagY2wwyZoH80tO/voMZiSisg= +github.com/nbd-wtf/go-nostr v0.18.10/go.mod h1:F9y6+M8askJCjilLgMC3rD0moA6UtG1MCnyClNYXeys= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nwaples/rardecode v1.1.2 h1:Cj0yZY6T1Zx1R7AhTbyGSALm44/Mmq+BAPc4B/p/d3M= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -373,6 +371,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= +github.com/puzpuzpuz/xsync v1.5.2 h1:yRAP4wqSOZG+/4pxJ08fPTwrfL0IzE/LKQ/cw509qGY= +github.com/puzpuzpuz/xsync v1.5.2/go.mod h1:K98BYhX3k1dQ2M63t1YNVDanbwUPmBCAhNmVrrxfiGg= github.com/rif/cache2go v1.0.0 h1:DhvZcxXvsuD9ExQ6ZO6f/sOE66OaAQIwB8Mfumap4w4= github.com/rif/cache2go v1.0.0/go.mod h1:reDqW0mGufW34CGJ1tvjMobI1BY3dCTxA0ZWdbvm06s= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= diff --git a/handlers.go b/handlers.go index ba46da3..fb51905 100644 --- a/handlers.go +++ b/handlers.go @@ -85,7 +85,7 @@ func (s *Server) HandleWebsocket(w http.ResponseWriter, r *http.Request) { // NIP-42 auth challenge if _, ok := s.relay.(Auther); ok { - ws.WriteJSON([]interface{}{"AUTH", ws.challenge}) + ws.WriteJSON(nostr.AuthEnvelope{Challenge: &ws.challenge}) } for { @@ -112,7 +112,7 @@ func (s *Server) HandleWebsocket(w http.ResponseWriter, r *http.Request) { var notice string defer func() { if notice != "" { - ws.WriteJSON([]interface{}{"NOTICE", notice}) + ws.WriteJSON(nostr.NoticeEnvelope(notice)) } }() @@ -148,10 +148,12 @@ func (s *Server) HandleWebsocket(w http.ResponseWriter, r *http.Request) { // check signature (requires the ID to be set) if ok, err := evt.CheckSignature(); err != nil { - ws.WriteJSON([]interface{}{"OK", evt.ID, false, "error: failed to verify signature"}) + reason := "error: failed to verify signature" + ws.WriteJSON(nostr.OKEnvelope{EventID: evt.ID, OK: false, Reason: &reason}) return } else if !ok { - ws.WriteJSON([]interface{}{"OK", evt.ID, false, "invalid: signature is invalid"}) + reason := "invalid: signature is invalid" + ws.WriteJSON(nostr.OKEnvelope{EventID: evt.ID, OK: false, Reason: &reason}) return } @@ -164,7 +166,8 @@ func (s *Server) HandleWebsocket(w http.ResponseWriter, r *http.Request) { } if err := store.DeleteEvent(ctx, tag[1], evt.PubKey); err != nil { - ws.WriteJSON([]interface{}{"OK", evt.ID, false, fmt.Sprintf("error: %s", err.Error())}) + reason := fmt.Sprintf("error: %s", err.Error()) + ws.WriteJSON(nostr.OKEnvelope{EventID: evt.ID, OK: false, Reason: &reason}) return } @@ -177,8 +180,11 @@ func (s *Server) HandleWebsocket(w http.ResponseWriter, r *http.Request) { } ok, message := AddEvent(ctx, s.relay, &evt) - ws.WriteJSON([]interface{}{"OK", evt.ID, ok, message}) - + var reason *string + if message != "" { + reason = &message + } + ws.WriteJSON(nostr.OKEnvelope{EventID: evt.ID, OK: ok, Reason: reason}) case "COUNT": counter, ok := store.(EventCounter) if !ok { @@ -294,8 +300,7 @@ func (s *Server) HandleWebsocket(w http.ResponseWriter, r *http.Request) { } i := 0 for event := range events { - ws.WriteJSON([]interface{}{"EVENT", id, event}) - + ws.WriteJSON(nostr.EventEnvelope{SubscriptionID: &id, Event: *event}) i++ if i > filter.Limit { break @@ -307,7 +312,7 @@ func (s *Server) HandleWebsocket(w http.ResponseWriter, r *http.Request) { } } - ws.WriteJSON([]interface{}{"EOSE", id}) + ws.WriteJSON(nostr.EOSEEnvelope(id)) setListener(id, ws, filters) case "CLOSE": var id string @@ -327,9 +332,10 @@ func (s *Server) HandleWebsocket(w http.ResponseWriter, r *http.Request) { } if pubkey, ok := nip42.ValidateAuthEvent(&evt, ws.challenge, auther.ServiceURL()); ok { ws.authed = pubkey - ws.WriteJSON([]interface{}{"OK", evt.ID, true, "authentication success"}) + ws.WriteJSON(nostr.OKEnvelope{EventID: evt.ID, OK: true}) } else { - ws.WriteJSON([]interface{}{"OK", evt.ID, false, "error: failed to authenticate"}) + reason := "error: failed to authenticate" + ws.WriteJSON(nostr.OKEnvelope{EventID: evt.ID, OK: false, Reason: &reason}) } } default: diff --git a/listener.go b/listener.go index b581d3e..5ef362a 100644 --- a/listener.go +++ b/listener.go @@ -10,11 +10,13 @@ type Listener struct { filters nostr.Filters } -var listeners = make(map[*WebSocket]map[string]*Listener) -var listenersMutex = sync.Mutex{} +var ( + listeners = make(map[*WebSocket]map[string]*Listener) + listenersMutex = sync.Mutex{} +) func GetListeningFilters() nostr.Filters { - var respfilters = make(nostr.Filters, 0, len(listeners)*2) + respfilters := make(nostr.Filters, 0, len(listeners)*2) listenersMutex.Lock() defer listenersMutex.Unlock() @@ -86,7 +88,7 @@ func notifyListeners(event *nostr.Event) { if !listener.filters.Match(event) { continue } - ws.WriteJSON([]interface{}{"EVENT", id, event}) + ws.WriteJSON(nostr.EventEnvelope{SubscriptionID: &id, Event: *event}) } } }