mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-03-17 13:22:56 +01:00
84 lines
2.6 KiB
Go
84 lines
2.6 KiB
Go
package sdk
|
|
|
|
import (
|
|
"context"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
var outboxShortTermCache = [256]ostcEntry{}
|
|
|
|
type ostcEntry struct {
|
|
pubkey string
|
|
relays []string
|
|
when time.Time
|
|
}
|
|
|
|
// FetchOutboxRelays uses a bunch of heuristics and locally stored data about many relays, including hints, tags,
|
|
// NIP-05, past attempts at fetching data from a user from a given relay, including successes and failures, and
|
|
// the "write" relays of kind:10002, in order to determine the best possible list of relays where a user might be
|
|
// currently publishing their events to.
|
|
func (sys *System) FetchOutboxRelays(ctx context.Context, pubkey string, n int) []string {
|
|
ostcIndex, _ := strconv.ParseUint(pubkey[12:14], 16, 8)
|
|
now := time.Now()
|
|
if entry := outboxShortTermCache[ostcIndex]; entry.pubkey == pubkey && entry.when.Add(time.Minute*2).After(now) {
|
|
return entry.relays
|
|
}
|
|
|
|
// if we have it cached that means we have at least tried to fetch recently and it won't be tried again
|
|
fetchGenericList(sys, ctx, pubkey, 10002, kind_10002, parseRelayFromKind10002, sys.RelayListCache)
|
|
|
|
relays := sys.Hints.TopN(pubkey, 6)
|
|
if len(relays) == 0 {
|
|
return []string{"wss://relay.damus.io", "wss://nos.lol"}
|
|
}
|
|
|
|
// we save a copy of this slice to this cache (must be a copy otherwise
|
|
// we will have a reference to a thing that the caller to this function may change at will)
|
|
relaysCopy := make([]string, len(relays))
|
|
copy(relaysCopy, relays)
|
|
outboxShortTermCache[ostcIndex] = ostcEntry{pubkey, relaysCopy, now}
|
|
|
|
if len(relays) > n {
|
|
relays = relays[0:n]
|
|
}
|
|
|
|
return relays
|
|
}
|
|
|
|
// FetchWriteRelays just reads relays from a kind:10002, that's the only canonical place where a user reveals
|
|
// the relays they intend to receive notifications from.
|
|
func (sys *System) FetchInboxRelays(ctx context.Context, pubkey string, n int) []string {
|
|
rl := sys.FetchRelayList(ctx, pubkey)
|
|
if len(rl.Items) == 0 || len(rl.Items) > 10 {
|
|
return []string{"wss://relay.damus.io", "wss://nos.lol"}
|
|
}
|
|
|
|
relays := make([]string, 0, n)
|
|
for _, r := range rl.Items {
|
|
if r.Inbox {
|
|
relays = append(relays, r.URL)
|
|
}
|
|
}
|
|
|
|
return relays
|
|
}
|
|
|
|
// FetchWriteRelays just reads relays from a kind:10002, it's different than FetchOutboxRelays, which relies on
|
|
// other data and heuristics besides kind:10002.
|
|
//
|
|
// Use FetchWriteRelays when deciding where to publish on behalf of a user, but FetchOutboxRelays when deciding
|
|
// from where to read notes authored by other users.
|
|
func (sys *System) FetchWriteRelays(ctx context.Context, pubkey string, n int) []string {
|
|
rl := sys.FetchRelayList(ctx, pubkey)
|
|
|
|
relays := make([]string, 0, n)
|
|
for _, r := range rl.Items {
|
|
if r.Outbox {
|
|
relays = append(relays, r.URL)
|
|
}
|
|
}
|
|
|
|
return relays
|
|
}
|