diff --git a/nip77/idsonly.go b/nip77/idsonly.go new file mode 100644 index 0000000..e50ee8f --- /dev/null +++ b/nip77/idsonly.go @@ -0,0 +1,70 @@ +package nip77 + +import ( + "context" + "fmt" + + "github.com/nbd-wtf/go-nostr" + "github.com/nbd-wtf/go-nostr/nip77/negentropy" + "github.com/nbd-wtf/go-nostr/nip77/negentropy/storage/empty" +) + +func FetchIDsOnly( + ctx context.Context, + url string, + filter nostr.Filter, +) (<-chan string, error) { + id := "go-nostr-tmp" // for now we can't have more than one subscription in the same connection + + neg := negentropy.New(empty.Empty{}, 1024*1024) + result := make(chan error) + + var r *nostr.Relay + r, err := nostr.RelayConnect(ctx, url, nostr.WithCustomHandler(func(data []byte) { + envelope := ParseNegMessage(data) + if envelope == nil { + return + } + switch env := envelope.(type) { + case *OpenEnvelope, *CloseEnvelope: + result <- fmt.Errorf("unexpected %s received from relay", env.Label()) + return + case *ErrorEnvelope: + result <- fmt.Errorf("relay returned a %s: %s", env.Label(), env.Reason) + return + case *MessageEnvelope: + nextmsg, err := neg.Reconcile(env.Message) + if err != nil { + result <- fmt.Errorf("failed to reconcile: %w", err) + return + } + + if nextmsg != "" { + msgb, _ := MessageEnvelope{id, nextmsg}.MarshalJSON() + r.Write(msgb) + } + } + })) + if err != nil { + return nil, err + } + + msg := neg.Start() + open, _ := OpenEnvelope{id, filter, msg}.MarshalJSON() + err = <-r.Write(open) + if err != nil { + return nil, fmt.Errorf("failed to write to relay: %w", err) + } + + ch := make(chan string) + go func() { + for id := range neg.HaveNots { + ch <- id + } + clse, _ := CloseEnvelope{id}.MarshalJSON() + r.Write(clse) + close(ch) + }() + + return ch, nil +} diff --git a/nip77/negentropy/storage/vector/accumulator.go b/nip77/negentropy/storage/accumulator.go similarity index 98% rename from nip77/negentropy/storage/vector/accumulator.go rename to nip77/negentropy/storage/accumulator.go index 0385fdb..e8d4453 100644 --- a/nip77/negentropy/storage/vector/accumulator.go +++ b/nip77/negentropy/storage/accumulator.go @@ -1,4 +1,4 @@ -package vector +package storage import ( "crypto/sha256" diff --git a/nip77/negentropy/storage/empty/empty.go b/nip77/negentropy/storage/empty/empty.go new file mode 100644 index 0000000..4d651c7 --- /dev/null +++ b/nip77/negentropy/storage/empty/empty.go @@ -0,0 +1,28 @@ +package empty + +import ( + "iter" + + "github.com/nbd-wtf/go-nostr/nip77/negentropy" + "github.com/nbd-wtf/go-nostr/nip77/negentropy/storage" +) + +var acc storage.Accumulator + +type Empty struct{} + +func (Empty) Size() int { return 0 } + +func (Empty) Range(begin, end int) iter.Seq2[int, negentropy.Item] { + return func(yield func(int, negentropy.Item) bool) {} +} + +func (Empty) FindLowerBound(begin, end int, value negentropy.Bound) int { return begin } + +func (Empty) GetBound(idx int) negentropy.Bound { + return negentropy.InfiniteBound +} + +func (Empty) Fingerprint(begin, end int) string { + return acc.GetFingerprint(end - begin) +} diff --git a/nip77/negentropy/storage/vector/vector.go b/nip77/negentropy/storage/vector/vector.go index d12375d..13a688e 100644 --- a/nip77/negentropy/storage/vector/vector.go +++ b/nip77/negentropy/storage/vector/vector.go @@ -8,13 +8,14 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr/nip77/negentropy" + "github.com/nbd-wtf/go-nostr/nip77/negentropy/storage" ) type Vector struct { items []negentropy.Item sealed bool - acc Accumulator + acc storage.Accumulator } func New() *Vector {