mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-03-17 21:32:56 +01:00
sdk taking shape.
This commit is contained in:
parent
234d825e43
commit
c506cc0f8b
4
go.mod
4
go.mod
@ -13,7 +13,6 @@ require (
|
||||
github.com/tidwall/gjson v1.14.4
|
||||
github.com/tyler-smith/go-bip32 v1.0.0
|
||||
github.com/tyler-smith/go-bip39 v1.1.0
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||
golang.org/x/exp v0.0.0-20221106115401-f9659909a136
|
||||
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc
|
||||
)
|
||||
@ -32,5 +31,8 @@ require (
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/dgraph-io/ristretto => github.com/aryehlev/ristretto v0.0.0-20230325112030-fd222a1ebb5e
|
||||
|
8
go.sum
8
go.sum
@ -3,6 +3,8 @@ github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUq
|
||||
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
|
||||
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/aryehlev/ristretto v0.0.0-20230325112030-fd222a1ebb5e h1:6XE6UUXzL1OTmsHg/mOqTPyER/KiIhTp7lK4YCxiO3k=
|
||||
github.com/aryehlev/ristretto v0.0.0-20230325112030-fd222a1ebb5e/go.mod h1:CVcbbyUW8c4weQp46o4er/sA83zTXDPV8xc8D85Dgag=
|
||||
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||
github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M=
|
||||
github.com/btcsuite/btcd v0.23.0/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY=
|
||||
@ -39,10 +41,7 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
|
||||
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
|
||||
github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8=
|
||||
github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA=
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
|
||||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
@ -92,7 +91,6 @@ github.com/puzpuzpuz/xsync/v2 v2.5.0 h1:2k4qrO/orvmEXZ3hmtHqIy9XaQtPTwzMZk1+iErp
|
||||
github.com/puzpuzpuz/xsync/v2 v2.5.0/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
|
||||
@ -129,7 +127,6 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -148,7 +145,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
|
10
sdk/cache/interface.go
vendored
Normal file
10
sdk/cache/interface.go
vendored
Normal 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
sdk/cache/memory/cache.go
vendored
Normal file
48
sdk/cache/memory/cache.go
vendored
Normal 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
sdk/follows.go
Normal file
7
sdk/follows.go
Normal file
@ -0,0 +1,7 @@
|
||||
package sdk
|
||||
|
||||
type Follow struct {
|
||||
Pubkey string
|
||||
Relay string
|
||||
Petname string
|
||||
}
|
41
sdk/init.go
Normal file
41
sdk/init.go
Normal 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
|
||||
}
|
@ -1,11 +1,17 @@
|
||||
package nostr
|
||||
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"`
|
||||
@ -16,7 +22,17 @@ type ProfileMetadata struct {
|
||||
LUD16 string `json:"lud16,omitempty"`
|
||||
}
|
||||
|
||||
func ParseMetadata(event Event) (*ProfileMetadata, error) {
|
||||
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)
|
||||
}
|
@ -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{
|
||||
|
Loading…
x
Reference in New Issue
Block a user