Files
njump/nostr.go
fiatjaf 48ed02dbd0 wip
2023-05-09 13:41:24 -03:00

101 lines
2.3 KiB
Go

package main
import (
"context"
"fmt"
"time"
"github.com/die-net/lrucache"
"github.com/mailru/easyjson"
"github.com/nbd-wtf/go-nostr"
"github.com/nbd-wtf/go-nostr/nip19"
)
var (
pool = nostr.NewSimplePool(context.Background())
cache = lrucache.New(50, 60*60)
serial int
always = []string{
"wss://relay.nostr.band",
}
everything = []string{
"wss://relay.nostr.bg",
"wss://relay.damus.io",
"wss://nostr.wine",
"wss://nos.lol",
"wss://nostr.mom",
"wss://atlas.nostr.land",
"wss://relay.snort.social",
"wss://eden.nostr.land",
"wss://nostr-pub.wellorder.net",
}
profiles = []string{
"wss://purplepag.es",
"wss://rbr.bio",
}
)
func getRelay() string {
serial = (serial + 1) % len(everything)
return everything[serial]
}
func getEvent(ctx context.Context, code string) (*nostr.Event, error) {
if v, ok := cache.Get(code); ok {
evt := &nostr.Event{}
easyjson.Unmarshal(v, evt)
return evt, nil
}
prefix, data, err := nip19.Decode(code)
if err != nil {
return nil, fmt.Errorf("failed to decode %w", err)
}
var filter nostr.Filter
relays := make([]string, 0, 7)
relays = append(relays, always...)
switch v := data.(type) {
case nostr.ProfilePointer:
filter.Authors = []string{v.PublicKey}
filter.Kinds = []int{0}
relays = append(relays, profiles...)
relays = append(relays, v.Relays...)
case nostr.EventPointer:
filter.IDs = []string{v.ID}
relays = append(relays, getRelay())
relays = append(relays, getRelay())
relays = append(relays, v.Relays...)
case nostr.EntityPointer:
filter.Authors = []string{v.PublicKey}
filter.Tags = nostr.TagMap{
"d": []string{v.Identifier},
}
relays = append(relays, getRelay())
relays = append(relays, getRelay())
relays = append(relays, v.Relays...)
case string:
if prefix == "note" {
filter.IDs = []string{v}
relays = append(relays, getRelay())
relays = append(relays, getRelay())
relays = append(relays, getRelay())
} else if prefix == "npub" {
filter.Authors = []string{v}
filter.Kinds = []int{0}
relays = append(relays, profiles...)
}
}
ctx, cancel := context.WithTimeout(ctx, time.Second*4)
defer cancel()
for event := range pool.SubManyEose(ctx, relays, nostr.Filters{filter}) {
cache.Set(code, []byte(event.String()))
return event, nil
}
return nil, fmt.Errorf("couldn't find this %s", prefix)
}