sdk: fetch and cache profiles.

This commit is contained in:
fiatjaf
2023-10-31 11:00:46 -03:00
parent aaaf608c2b
commit 374dbbe1a0
5 changed files with 47 additions and 15 deletions

View File

@@ -24,7 +24,7 @@ type Event struct {
} }
const ( const (
KindSetMetadata int = 0 KindProfileMetadata int = 0
KindTextNote int = 1 KindTextNote int = 1
KindRecommendServer int = 2 KindRecommendServer int = 2
KindContactList int = 3 KindContactList int = 3

View File

@@ -11,13 +11,14 @@ import (
type System struct { type System struct {
relaysCache cache.Cache32[[]Relay] relaysCache cache.Cache32[[]Relay]
followsCache cache.Cache32[[]Follow] followsCache cache.Cache32[[]Follow]
metadataCache cache.Cache32[*ProfileMetadata] metadataCache cache.Cache32[ProfileMetadata]
pool *nostr.SimplePool pool *nostr.SimplePool
metadataRelays []string
relayListRelays []string 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 { if v, ok := sys.relaysCache.Get(pubkey); ok {
return v return v
} }
@@ -29,8 +30,8 @@ func (sys System) FetchRelaysForPubkey(ctx context.Context, pubkey string) []Rel
return res return res
} }
func (sys System) FetchOutboxRelaysForPubkey(ctx context.Context, pubkey string) []string { func (sys System) FetchOutboxRelays(ctx context.Context, pubkey string) []string {
relays := sys.FetchRelaysForPubkey(ctx, pubkey) relays := sys.FetchRelays(ctx, pubkey)
result := make([]string, 0, len(relays)) result := make([]string, 0, len(relays))
for _, relay := range relays { for _, relay := range relays {
if relay.Outbox { if relay.Outbox {
@@ -39,3 +40,15 @@ func (sys System) FetchOutboxRelaysForPubkey(ctx context.Context, pubkey string)
} }
return result 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
}

View File

@@ -28,10 +28,32 @@ func (p ProfileMetadata) Npub() string {
} }
func (p ProfileMetadata) Nprofile(ctx context.Context, sys *System, nrelays int) 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 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) { func ParseMetadata(event *nostr.Event) (*ProfileMetadata, error) {
if event.Kind != 0 { if event.Kind != 0 {
return nil, fmt.Errorf("event %s is kind %d, not 0", event.ID, event.Kind) return nil, fmt.Errorf("event %s is kind %d, not 0", event.ID, event.Kind)

View File

@@ -13,9 +13,6 @@ type Relay struct {
Outbox bool 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 { func FetchRelaysForPubkey(ctx context.Context, pool *nostr.SimplePool, pubkey string, relays ...string) []Relay {
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
defer cancel() defer cancel()

View File

@@ -66,7 +66,7 @@ func TestNestedSubscriptions(t *testing.T) {
select { select {
case event := <-sub.Events: case event := <-sub.Events:
// now fetch author of this // 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 { if err != nil {
t.Errorf("subscription 2 failed: %v", err) t.Errorf("subscription 2 failed: %v", err)
return return