package nostr import ( "bytes" "cmp" "encoding/hex" "net/url" "slices" ) // IsValidRelayURL checks if a URL is a valid relay URL (ws:// or wss://). func IsValidRelayURL(u string) bool { parsed, err := url.Parse(u) if err != nil { return false } if parsed.Scheme != "wss" && parsed.Scheme != "ws" { return false } return true } // IsValid32ByteHex checks if a string is a valid 32-byte hex string. func IsValid32ByteHex(thing string) bool { if !isLowerHex(thing) { return false } if len(thing) != 64 { return false } _, err := hex.DecodeString(thing) return err == nil } // CompareEvent is meant to to be used with slices.Sort func CompareEvent(a, b Event) int { if a.CreatedAt == b.CreatedAt { return bytes.Compare(a.ID[:], b.ID[:]) } return cmp.Compare(a.CreatedAt, b.CreatedAt) } // CompareEventReverse is meant to to be used with slices.Sort func CompareEventReverse(b, a Event) int { if a.CreatedAt == b.CreatedAt { return bytes.Compare(a.ID[:], b.ID[:]) } return cmp.Compare(a.CreatedAt, b.CreatedAt) } // AppendUnique adds items to an array only if they don't already exist in the array. // Returns the modified array. func AppendUnique[I comparable](arr []I, item ...I) []I { for _, item := range item { if slices.Contains(arr, item) { return arr } arr = append(arr, item) } return arr }