diff --git a/pkg/nostr/nip5/nip05.go b/pkg/nostr/nip5/nip05.go index 727abcba..19fca387 100644 --- a/pkg/nostr/nip5/nip05.go +++ b/pkg/nostr/nip5/nip05.go @@ -9,6 +9,13 @@ import ( "strings" "github.com/Hubmakerlabs/replicatr/pkg/nostr/pointers" + log2 "mleku.online/git/log" +) + +var ( + log = log2.GetLogger() + fails = log.D.Chk + hexDecode, encodeToHex = hex.DecodeString, hex.EncodeToString ) type ( @@ -21,9 +28,8 @@ type WellKnownResponse struct { Relays key2RelaysMap `json:"relays"` // NIP-35 } -func QueryIdentifier(ctx context.Context, fullname string) (*pointers.Profile, error) { +func QueryIdentifier(ctx context.Context, fullname string) (pp *pointers.Profile, e error) { spl := strings.Split(fullname, "@") - var name, domain string switch len(spl) { case 1: @@ -35,46 +41,39 @@ func QueryIdentifier(ctx context.Context, fullname string) (*pointers.Profile, e default: return nil, fmt.Errorf("not a valid nip-05 identifier") } - if strings.Index(domain, ".") == -1 { return nil, fmt.Errorf("hostname doesn't have a dot") } - - req, err := http.NewRequestWithContext(ctx, "GET", + var req *http.Request + req, e = http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://%s/.well-known/nostr.json?name=%s", domain, name), nil) - if err != nil { - return nil, fmt.Errorf("failed to create a request: %w", err) + if log.E.Chk(e) { + return nil, fmt.Errorf("failed to create a request: %w", e) } - client := &http.Client{ CheckRedirect: func(req *http.Request, via []*http.Request) (e error) { return http.ErrUseLastResponse }, } - res, err := client.Do(req) - if err != nil { - return nil, fmt.Errorf("request failed: %w", err) + var res *http.Response + if res, e = client.Do(req); log.E.Chk(e) { + return nil, fmt.Errorf("request failed: %w", e) } defer res.Body.Close() - var result WellKnownResponse - if err := json.NewDecoder(res.Body).Decode(&result); err != nil { - return nil, fmt.Errorf("failed to decode json response: %w", err) + if e = json.NewDecoder(res.Body).Decode(&result); log.E.Chk(e) { + return nil, fmt.Errorf("failed to decode json response: %w", e) } - pubkey, ok := result.Names[name] if !ok { return &pointers.Profile{}, nil } - if len(pubkey) == 64 { if _, err := hex.DecodeString(pubkey); err != nil { return &pointers.Profile{}, nil } } - relays, _ := result.Relays[pubkey] - return &pointers.Profile{ PublicKey: pubkey, Relays: relays, @@ -85,6 +84,5 @@ func NormalizeIdentifier(fullname string) string { if strings.HasPrefix(fullname, "_@") { return fullname[2:] } - return fullname } diff --git a/pkg/nostr/sdk/cache/memory/cache.go b/pkg/nostr/sdk/cache/memory/cache.go index 41610da0..c3a24443 100644 --- a/pkg/nostr/sdk/cache/memory/cache.go +++ b/pkg/nostr/sdk/cache/memory/cache.go @@ -6,6 +6,13 @@ import ( "time" ristretto "github.com/fiatjaf/generic-ristretto" + log2 "mleku.online/git/log" +) + +var ( + log = log2.GetLogger() + fails = log.D.Chk + hexDecode, encodeToHex = hex.DecodeString, hex.EncodeToString ) type RistrettoCache[V any] struct { @@ -40,8 +47,9 @@ func shortUint64(idOrPubkey string) uint64 { if length < 8 { return 0 } - b, err := hex.DecodeString(idOrPubkey[length-8:]) - if err != nil { + var b []byte + var e error + if b, e = hex.DecodeString(idOrPubkey[length-8:]); log.E.Chk(e) { return 0 } return uint64(binary.BigEndian.Uint32(b)) diff --git a/pkg/nostr/sdk/input.go b/pkg/nostr/sdk/input.go index da0e1fa8..35b99479 100644 --- a/pkg/nostr/sdk/input.go +++ b/pkg/nostr/sdk/input.go @@ -3,6 +3,7 @@ package sdk import ( "context" "encoding/hex" + "github.com/Hubmakerlabs/replicatr/pkg/nostr/nip1" "github.com/Hubmakerlabs/replicatr/pkg/nostr/pointers" @@ -13,28 +14,36 @@ import ( // InputToProfile turns any npub/nprofile/hex/nip5 input into a ProfilePointer // (or nil). func InputToProfile(ctx context.Context, input string) (pp *pointers.Profile) { + var e error // handle if it is a hex string if len(input) == 64 { - if _, err := hex.DecodeString(input); err == nil { + if _, e = hex.DecodeString(input); !log.E.Chk(e) { return &pointers.Profile{PublicKey: input} } } // handle nip19 codes, if that's the case - prefix, data, e := nip19.Decode(input) - log.D.Chk(e) + var prefix string + var data any + if prefix, data, e = nip19.Decode(input); log.D.Chk(e) { + } + var ok bool switch prefix { case "npub": - input = data.(string) + input, ok = data.(string) + if !ok { + return + } return &pointers.Profile{PublicKey: input} case "nprofile": - pp := data.(pointers.Profile) - return &pp + pp = data.(*pointers.Profile) + return } // handle nip5 ids, if that's the case - pp, e = nip5.QueryIdentifier(ctx, input) - log.D.Chk(e) + if pp, e = nip5.QueryIdentifier(ctx, input); log.D.Chk(e) { + return + } if pp != nil { - return pp + return } return nil } @@ -42,21 +51,32 @@ func InputToProfile(ctx context.Context, input string) (pp *pointers.Profile) { // InputToEventPointer turns any note/nevent/hex input into a EventPointer (or // nil). func InputToEventPointer(input string) (ep *pointers.Event) { + var e error // handle if it is a hex string if len(input) == 64 { - if _, err := hex.DecodeString(input); err == nil { + if _, e = hex.DecodeString(input); !log.E.Chk(e) { return &pointers.Event{ID: nip1.EventID(input)} } } // handle nip19 codes, if that's the case - prefix, data, e := nip19.Decode(input) - log.D.Chk(e) + var prefix string + var data any + if prefix, data, e = nip19.Decode(input); log.D.Chk(e) { + return + } + var ok bool switch prefix { case "note": - input = data.(string) + if input, ok = data.(string); !ok { + log.E.F("note pointer was not expected string") + return + } return &pointers.Event{ID: nip1.EventID(input)} case "nevent": - *ep = data.(pointers.Event) + if ep, ok = data.(*pointers.Event); !ok { + log.E.F("note pointer was not event pointer") + return + } return ep } // handle nip5 ids, if that's the case (???) diff --git a/pkg/nostr/sdk/metadata.go b/pkg/nostr/sdk/metadata.go index 0ad66a0b..2e5d9653 100644 --- a/pkg/nostr/sdk/metadata.go +++ b/pkg/nostr/sdk/metadata.go @@ -56,7 +56,7 @@ func (p ProfileMetadata) ShortName() string { } func FetchProfileMetadata(ctx context.Context, pool *nostr.SimplePool, - pubkey string, relays ...string) *ProfileMetadata { + pubkey string, relays ...string) (pm *ProfileMetadata) { ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -67,9 +67,10 @@ func FetchProfileMetadata(ctx context.Context, pool *nostr.SimplePool, Limit: 1, }, }) + var e error for ie := range ch { - if m, err := ParseMetadata(ie.Event); err == nil { - return m + if pm, e = ParseMetadata(ie.Event); !log.E.Chk(e) { + return } } return &ProfileMetadata{PubKey: pubkey} diff --git a/pkg/nostr/sdk/outbox.go b/pkg/nostr/sdk/outbox.go index 255f3067..a757b501 100644 --- a/pkg/nostr/sdk/outbox.go +++ b/pkg/nostr/sdk/outbox.go @@ -3,9 +3,10 @@ package sdk import ( "context" "fmt" - "github.com/Hubmakerlabs/replicatr/pkg/nostr/nip1" "sync" + "github.com/Hubmakerlabs/replicatr/pkg/nostr/nip1" + "github.com/Hubmakerlabs/replicatr/pkg/nostr" ) @@ -27,8 +28,8 @@ func (s *System) ExpandQueriesByAuthorAndRelays( relayURLs := s.FetchOutboxRelays(ctx, pubkey) c := 0 for _, r := range relayURLs { - relay, err := s.Pool.EnsureRelay(r) - if err != nil { + var relay *nostr.Relay + if relay, e = s.Pool.EnsureRelay(r); log.E.Chk(e) { continue } relaysForPubkey[pubkey] = append(relaysForPubkey[pubkey], relay) diff --git a/pkg/nostr/sdk/system.go b/pkg/nostr/sdk/system.go index 0bb5d81b..58884ed8 100644 --- a/pkg/nostr/sdk/system.go +++ b/pkg/nostr/sdk/system.go @@ -84,11 +84,11 @@ func (s *System) fetchProfileMetadata(ctx context.Context, Authors: []string{pubkey}}) log.D.Chk(e) if len(res) != 0 { - if m, err := ParseMetadata(res[0]); err == nil { - m.PubKey = pubkey - m.Event = res[0] - s.MetadataCache.SetWithTTL(pubkey, m, time.Hour*6) - return m, true + if pm, e = ParseMetadata(res[0]); !log.E.Chk(e) { + pm.PubKey = pubkey + pm.Event = res[0] + s.MetadataCache.SetWithTTL(pubkey, pm, time.Hour*6) + return pm, true } } } diff --git a/pkg/nostr/tags/tags.go b/pkg/nostr/tags/tags.go index b21f76a8..1bc1001c 100644 --- a/pkg/nostr/tags/tags.go +++ b/pkg/nostr/tags/tags.go @@ -2,18 +2,28 @@ package tags import ( "bytes" + "encoding/hex" "encoding/json" "errors" "fmt" - t "github.com/Hubmakerlabs/replicatr/pkg/nostr/tag" + + "github.com/Hubmakerlabs/replicatr/pkg/nostr/tag" + log2 "mleku.online/git/log" +) + +var ( + log = log2.GetLogger() + fails = log.D.Chk + hexDecode, encodeToHex = hex.DecodeString, hex.EncodeToString ) -// T is a list of T - which are lists of string elements with ordering and -// no uniqueness constraint (not a set). -type T []t.T +// T is a list of T - which are lists of string elements with ordering and no +// uniqueness constraint (not a set). +type T []tag.T -// GetFirst gets the first t in tags that matches the prefix, see [T.StartsWith] -func (t T) GetFirst(tagPrefix []string) *t.T { +// GetFirst gets the first tag in tags that matches the prefix, see +// [T.StartsWith] +func (t T) GetFirst(tagPrefix []string) *tag.T { for _, v := range t { if v.StartsWith(tagPrefix) { return &v @@ -22,8 +32,8 @@ func (t T) GetFirst(tagPrefix []string) *t.T { return nil } -// GetLast gets the last t in tags that matches the prefix, see [T.StartsWith] -func (t T) GetLast(tagPrefix []string) *t.T { +// GetLast gets the last tag in tags that matches the prefix, see [T.StartsWith] +func (t T) GetLast(tagPrefix []string) *tag.T { for i := len(t) - 1; i >= 0; i-- { v := t[i] if v.StartsWith(tagPrefix) { @@ -55,9 +65,10 @@ func (t T) FilterOut(tagPrefix []string) T { return filtered } -// AppendUnique appends a t if it doesn't exist yet, otherwise does nothing. -// the uniqueness comparison is done based only on the first 2 elements of the t. -func (t T) AppendUnique(tag t.T) T { +// AppendUnique appends a tag if it doesn't exist yet, otherwise does nothing. +// the uniqueness comparison is done based only on the first 2 elements of the +// tag. +func (t T) AppendUnique(tag tag.T) T { n := len(tag) if n > 2 { n = 2 @@ -70,7 +81,7 @@ func (t T) AppendUnique(tag t.T) T { // Scan parses a string or raw bytes that should be a string and embeds the // values into the tags variable from which this method is invoked. -func (t T) Scan(src any) (err error) { +func (t T) Scan(src any) (e error) { var jtags []byte switch v := src.(type) { case []byte: @@ -78,14 +89,15 @@ func (t T) Scan(src any) (err error) { case string: jtags = []byte(v) default: - return errors.New("couldn't scan t, it's not a json string") + return errors.New("couldn'tag scan tag, it's not a json string") } - err = json.Unmarshal(jtags, &t) + e = json.Unmarshal(jtags, &t) + log.E.Chk(e) return } // ContainsAny returns true if any of the strings given in `values` matches any -// of the t elements. +// of the tag elements. func (t T) ContainsAny(tagName string, values []string) bool { for _, v := range t { if len(v) < 2 { diff --git a/pkg/relay/eventstore/helpers.go b/pkg/relay/eventstore/helpers.go index 8492b642..54b36223 100644 --- a/pkg/relay/eventstore/helpers.go +++ b/pkg/relay/eventstore/helpers.go @@ -2,6 +2,7 @@ package eventstore import ( "encoding/hex" + "github.com/Hubmakerlabs/replicatr/pkg/nostr/nip1" log2 "mleku.online/git/log" )