// Package kind provides event kind types and a kind database. package kind import ( "smesh.lol/pkg/nostr/ints" "smesh.lol/pkg/lol/chk" ) type Integer interface { ~int | ~int8 | ~int16 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint64 } type K struct { K uint16 } func New[V Integer](k V) *K { return &K{uint16(k)} } func (k *K) ToInt() int { if k == nil { return 0 } return int(k.K) } func (k *K) ToU16() uint16 { if k == nil { return 0 } return k.K } func (k *K) ToI32() int32 { if k == nil { return 0 } return int32(k.K) } func (k *K) ToU64() uint64 { if k == nil { return 0 } return uint64(k.K) } func (k *K) Name() []byte { return []byte(GetString(k.K)) } func (k *K) Equal(k2 uint16) bool { if k == nil { return false } return k.K == k2 } var Privileged = []*K{ EncryptedDirectMessage, GiftWrap, GiftWrapWithKind4, JWTBinding, ApplicationSpecificData, Seal, DirectMessage, FileMessage, MLSKeyPackage, KeyPackageRelaysList, ChannelCreation, ChannelMetadata, ChannelMessage, ChannelHideMessage, ChannelMuteUser, } func IsChannelKind(k uint16) bool { return k >= ChannelCreation.K && k <= ChannelMuteUser.K } func IsDiscoverableChannelKind(k uint16) bool { return k == ChannelCreation.K || k == ChannelMetadata.K } func IsPrivileged(k uint16) bool { for i := range Privileged { if k == Privileged[i].K { return true } } return false } func (k *K) Marshal(dst []byte) []byte { return ints.New(k.ToU64()).Marshal(dst) } func (k *K) Unmarshal(b []byte) (r []byte, err error) { n := ints.New(0) if r, err = n.Unmarshal(b); chk.T(err) { return } k.K = n.Uint16() return } // GetString returns a human-readable name for a kind number. // No mutex needed — single cooperative thread. func GetString(t uint16) string { return Map[t] } func IsEphemeral(k uint16) bool { return k >= EphemeralStart.K && k < EphemeralEnd.K } func IsReplaceable(k uint16) bool { return k == ProfileMetadata.K || k == FollowList.K || (k >= ReplaceableStart.K && k < ReplaceableEnd.K) } func IsParameterizedReplaceable(k uint16) bool { return k >= ParameterizedReplaceableStart.K && k < ParameterizedReplaceableEnd.K } var Directory = []*K{ ProfileMetadata, FollowList, EventDeletion, Reporting, RelayListMetadata, MuteList, DMRelaysList, } func IsDirectoryEvent(k uint16) bool { for i := range Directory { if k == Directory[i].K { return true } } return false } var ( ProfileMetadata = &K{0} SetMetadata = &K{0} TextNote = &K{1} RecommendRelay = &K{2} FollowList = &K{3} Follows = &K{3} EncryptedDirectMessage = &K{4} EventDeletion = &K{5} Deletion = &K{5} Repost = &K{6} Reaction = &K{7} BadgeAward = &K{8} ChatMessage = &K{9} GroupChatThreadedReply = &K{10} Thread = &K{11} GroupThreadReply = &K{12} Seal = &K{13} DirectMessage = &K{14} FileMessage = &K{15} GenericRepost = &K{16} ReactionToWebsite = &K{17} Picture = &K{20} VideoEventHorizontal = &K{34235} VideoEventVertical = &K{34236} MLSKeyPackage = &K{443} MLSWelcome = &K{444} MLSGroupEvent = &K{445} ChannelCreation = &K{40} ChannelMetadata = &K{41} ChannelMessage = &K{42} ChannelHideMessage = &K{43} ChannelMuteUser = &K{44} Bid = &K{1021} BidConfirmation = &K{1022} OpenTimestamps = &K{1040} GiftWrap = &K{1059} GiftWrapWithKind4 = &K{1060} FileMetadata = &K{1063} LiveChatMessage = &K{1311} BitcoinBlock = &K{1517} LiveStream = &K{1808} ProblemTracker = &K{1971} MemoryHole = &K{1984} Reporting = &K{1984} Label = &K{1985} CommunityPostApproval = &K{4550} JobRequestStart = &K{5000} JobRequestEnd = &K{5999} JobResultStart = &K{6000} JobResultEnd = &K{6999} JobFeedback = &K{7000} ZapGoal = &K{9041} ZapRequest = &K{9734} Zap = &K{9735} Highlights = &K{9802} ReplaceableStart = &K{10000} MuteList = &K{10000} BlockList = &K{10000} PinList = &K{10001} RelayListMetadata = &K{10002} BookmarkList = &K{10003} CommunitiesList = &K{10004} PublicChatsList = &K{10005} BlockedRelaysList = &K{10006} SearchRelaysList = &K{10007} RelayGroupConfig = &K{10008} InterestsList = &K{10015} UserEmojiList = &K{10030} DMRelaysList = &K{10050} KeyPackageRelaysList = &K{10051} FileStorageServerList = &K{10096} JWTBinding = &K{13004} NWCWalletServiceInfo = &K{13194} WalletServiceInfo = &K{13194} ReplaceableEnd = &K{19999} EphemeralStart = &K{20000} LightningPubRPC = &K{21000} ClientAuthentication = &K{22242} NWCWalletRequest = &K{23194} WalletRequest = &K{23194} NWCWalletResponse = &K{23195} WalletResponse = &K{23195} NWCNotification = &K{23196} WalletNotificationNip4 = &K{23196} WalletNotification = &K{23197} NostrConnect = &K{24133} HTTPAuth = &K{27235} EphemeralEnd = &K{29999} ParameterizedReplaceableStart = &K{30000} CategorizedPeopleList = &K{30000} FollowSets = &K{30000} CategorizedBookmarksList = &K{30001} GenericLists = &K{30001} RelaySets = &K{30002} BookmarkSets = &K{30003} CurationSets = &K{30004} ProfileBadges = &K{30008} BadgeDefinition = &K{30009} InterestSets = &K{30015} StallDefinition = &K{30017} ProductDefinition = &K{30018} MarketplaceUIUX = &K{30019} ProductSoldAsAuction = &K{30020} Article = &K{30023} LongFormContent = &K{30023} DraftLongFormContent = &K{30024} EmojiSets = &K{30030} ApplicationSpecificData = &K{30078} LiveEvent = &K{30311} UserStatuses = &K{30315} ClassifiedListing = &K{30402} DraftClassifiedListing = &K{30403} DateBasedCalendarEvent = &K{31922} TimeBasedCalendarEvent = &K{31923} Calendar = &K{31924} CalendarEventRSVP = &K{31925} HandlerRecommendation = &K{31989} HandlerInformation = &K{31990} WaveLakeTrack = &K{32123} CommunityDefinition = &K{34550} ACLEvent = &K{39998} PolicyConfig = &K{12345} ParameterizedReplaceableEnd = &K{40000} ) // Map is populated from the embedded kinds.json during init(). var Map = map[uint16]string{}