sdk taking shape.

This commit is contained in:
fiatjaf
2023-10-30 19:23:58 -03:00
parent 234d825e43
commit c506cc0f8b
8 changed files with 133 additions and 18 deletions
+10
View File
@@ -0,0 +1,10 @@
package cache
import "time"
type Cache32[V any] interface {
Get(k string) (v V, ok bool)
Delete(k string)
Set(k string, v V) bool
SetWithTTL(k string, v V, d time.Duration) bool
}
+48
View File
@@ -0,0 +1,48 @@
package cache_memory
import (
"encoding/binary"
"encoding/hex"
"time"
"github.com/dgraph-io/ristretto"
)
type RistrettoCache[V any] struct {
Cache *ristretto.Cache[string, V]
}
func New32[V any](max int64) *RistrettoCache[V] {
cache, _ := ristretto.NewCache(&ristretto.Config[string, V]{
NumCounters: max * 10,
MaxCost: max,
BufferItems: 64,
KeyToHash: func(key string) (uint64, uint64) { return h32(key), 0 },
})
return &RistrettoCache[V]{Cache: cache}
}
func (s RistrettoCache[V]) Get(k string) (v V, ok bool) { return s.Cache.Get(k) }
func (s RistrettoCache[V]) Delete(k string) { s.Cache.Del(k) }
func (s RistrettoCache[V]) Set(k string, v V) bool { return s.Cache.Set(k, v, 1) }
func (s RistrettoCache[V]) SetWithTTL(k string, v V, d time.Duration) bool {
return s.Cache.SetWithTTL(k, v, 1, d)
}
func h32(key string) uint64 {
// we get an event id or pubkey as hex,
// so just extract the last 8 bytes from it and turn them into a uint64
return shortUint64(key)
}
func shortUint64(idOrPubkey string) uint64 {
length := len(idOrPubkey)
if length < 8 {
return 0
}
b, err := hex.DecodeString(idOrPubkey[length-8:])
if err != nil {
return 0
}
return uint64(binary.BigEndian.Uint32(b))
}
+7
View File
@@ -0,0 +1,7 @@
package sdk
type Follow struct {
Pubkey string
Relay string
Petname string
}
+41
View File
@@ -0,0 +1,41 @@
package sdk
import (
"context"
"time"
"github.com/nbd-wtf/go-nostr"
"github.com/nbd-wtf/go-nostr/sdk/cache"
)
type System struct {
relaysCache cache.Cache32[[]Relay]
followsCache cache.Cache32[[]Follow]
metadataCache cache.Cache32[*ProfileMetadata]
pool *nostr.SimplePool
metadataRelays []string
relayListRelays []string
}
func (sys System) FetchRelaysForPubkey(ctx context.Context, pubkey string) []Relay {
if v, ok := sys.relaysCache.Get(pubkey); ok {
return v
}
ctx, cancel := context.WithTimeout(ctx, time.Second*5)
defer cancel()
res := FetchRelaysForPubkey(ctx, sys.pool, pubkey, sys.relayListRelays...)
sys.relaysCache.SetWithTTL(pubkey, res, time.Hour*6)
return res
}
func (sys System) FetchOutboxRelaysForPubkey(ctx context.Context, pubkey string) []string {
relays := sys.FetchRelaysForPubkey(ctx, pubkey)
result := make([]string, 0, len(relays))
for _, relay := range relays {
if relay.Outbox {
result = append(result, relay.URL)
}
}
return result
}
+50
View File
@@ -0,0 +1,50 @@
package sdk
import (
"context"
"encoding/json"
"fmt"
"github.com/nbd-wtf/go-nostr"
"github.com/nbd-wtf/go-nostr/nip19"
)
type ProfileMetadata struct {
pubkey string
Name string `json:"name,omitempty"`
DisplayName string `json:"display_name,omitempty"`
About string `json:"about,omitempty"`
Website string `json:"website,omitempty"`
Picture string `json:"picture,omitempty"`
Banner string `json:"banner,omitempty"`
NIP05 string `json:"nip05,omitempty"`
LUD16 string `json:"lud16,omitempty"`
}
func (p ProfileMetadata) Npub() string {
v, _ := nip19.EncodePublicKey(p.pubkey)
return v
}
func (p ProfileMetadata) Nprofile(ctx context.Context, sys *System, nrelays int) string {
v, _ := nip19.EncodeProfile(p.pubkey, sys.FetchOutboxRelaysForPubkey(ctx, p.pubkey))
return v
}
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)
}
var meta ProfileMetadata
if err := json.Unmarshal([]byte(event.Content), &meta); err != nil {
cont := event.Content
if len(cont) > 100 {
cont = cont[0:99]
}
return nil, fmt.Errorf("failed to parse metadata (%s) from event %s: %w", cont, event.ID, err)
}
return &meta, nil
}
+4 -9
View File
@@ -13,18 +13,13 @@ type Relay struct {
Outbox bool
}
func FetchRelaysForPubkey(ctx context.Context, pool *nostr.SimplePool, pubkey string, extraRelays ...string) []Relay {
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()
relays := append(extraRelays,
"wss://nostr-pub.wellorder.net",
"wss://relay.damus.io",
"wss://nos.lol",
"wss://nostr.mom",
"wss://relay.nostr.bg",
)
ch := pool.SubManyEose(ctx, relays, nostr.Filters{
{
Kinds: []int{