From 374dbbe1a07d12a5649bef9931b36dfe45a777e3 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Tue, 31 Oct 2023 11:00:46 -0300 Subject: [PATCH] sdk: fetch and cache profiles. --- event.go | 2 +- sdk/init.go | 31 ++++++++++++++++++++++--------- sdk/metadata.go | 24 +++++++++++++++++++++++- sdk/relays.go | 3 --- subscription_test.go | 2 +- 5 files changed, 47 insertions(+), 15 deletions(-) diff --git a/event.go b/event.go index 52c2cf1..78c8f3d 100644 --- a/event.go +++ b/event.go @@ -24,7 +24,7 @@ type Event struct { } const ( - KindSetMetadata int = 0 + KindProfileMetadata int = 0 KindTextNote int = 1 KindRecommendServer int = 2 KindContactList int = 3 diff --git a/sdk/init.go b/sdk/init.go index e5c6823..b181d5f 100644 --- a/sdk/init.go +++ b/sdk/init.go @@ -9,15 +9,16 @@ import ( ) type System struct { - relaysCache cache.Cache32[[]Relay] - followsCache cache.Cache32[[]Follow] - metadataCache cache.Cache32[*ProfileMetadata] - pool *nostr.SimplePool - metadataRelays []string - relayListRelays []string + relaysCache cache.Cache32[[]Relay] + followsCache cache.Cache32[[]Follow] + metadataCache cache.Cache32[ProfileMetadata] + pool *nostr.SimplePool + relayListRelays []string + followListRelays []string + metadataRelays []string } -func (sys System) FetchRelaysForPubkey(ctx context.Context, pubkey string) []Relay { +func (sys System) FetchRelays(ctx context.Context, pubkey string) []Relay { if v, ok := sys.relaysCache.Get(pubkey); ok { return v } @@ -29,8 +30,8 @@ func (sys System) FetchRelaysForPubkey(ctx context.Context, pubkey string) []Rel return res } -func (sys System) FetchOutboxRelaysForPubkey(ctx context.Context, pubkey string) []string { - relays := sys.FetchRelaysForPubkey(ctx, pubkey) +func (sys System) FetchOutboxRelays(ctx context.Context, pubkey string) []string { + relays := sys.FetchRelays(ctx, pubkey) result := make([]string, 0, len(relays)) for _, relay := range relays { if relay.Outbox { @@ -39,3 +40,15 @@ func (sys System) FetchOutboxRelaysForPubkey(ctx context.Context, pubkey string) } return result } + +func (sys System) FetchProfileMetadata(ctx context.Context, pubkey string) ProfileMetadata { + if v, ok := sys.metadataCache.Get(pubkey); ok { + return v + } + + ctx, cancel := context.WithTimeout(ctx, time.Second*5) + defer cancel() + res := FetchProfileMetadata(ctx, sys.pool, pubkey, sys.metadataRelays...) + sys.metadataCache.SetWithTTL(pubkey, res, time.Hour*6) + return res +} diff --git a/sdk/metadata.go b/sdk/metadata.go index 2c39461..bbd0d56 100644 --- a/sdk/metadata.go +++ b/sdk/metadata.go @@ -28,10 +28,32 @@ func (p ProfileMetadata) Npub() string { } func (p ProfileMetadata) Nprofile(ctx context.Context, sys *System, nrelays int) string { - v, _ := nip19.EncodeProfile(p.pubkey, sys.FetchOutboxRelaysForPubkey(ctx, p.pubkey)) + v, _ := nip19.EncodeProfile(p.pubkey, sys.FetchOutboxRelays(ctx, p.pubkey)) return v } +func FetchProfileMetadata(ctx context.Context, pool *nostr.SimplePool, pubkey string, relays ...string) ProfileMetadata { + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + ch := pool.SubManyEose(ctx, relays, nostr.Filters{ + { + Kinds: []int{nostr.KindProfileMetadata}, + Authors: []string{pubkey}, + Limit: 1, + }, + }) + + for ie := range ch { + if m, err := ParseMetadata(ie.Event); err == nil { + m.pubkey = pubkey + return *m + } + } + + return ProfileMetadata{pubkey: pubkey} +} + func ParseMetadata(event *nostr.Event) (*ProfileMetadata, error) { if event.Kind != 0 { return nil, fmt.Errorf("event %s is kind %d, not 0", event.ID, event.Kind) diff --git a/sdk/relays.go b/sdk/relays.go index 7ce9185..6da54a6 100644 --- a/sdk/relays.go +++ b/sdk/relays.go @@ -13,9 +13,6 @@ type Relay struct { Outbox bool } -func FetchOutboxRelaysForPubkey(ctx context.Context, pool *nostr.SimplePool, pubkey string, n int) { -} - func FetchRelaysForPubkey(ctx context.Context, pool *nostr.SimplePool, pubkey string, relays ...string) []Relay { ctx, cancel := context.WithCancel(ctx) defer cancel() diff --git a/subscription_test.go b/subscription_test.go index ca8760e..fa0e80c 100644 --- a/subscription_test.go +++ b/subscription_test.go @@ -66,7 +66,7 @@ func TestNestedSubscriptions(t *testing.T) { select { case event := <-sub.Events: // now fetch author of this - sub, err := rl.Subscribe(context.Background(), Filters{{Kinds: []int{KindSetMetadata}, Authors: []string{event.PubKey}, Limit: 1}}) + sub, err := rl.Subscribe(context.Background(), Filters{{Kinds: []int{KindProfileMetadata}, Authors: []string{event.PubKey}, Limit: 1}}) if err != nil { t.Errorf("subscription 2 failed: %v", err) return