diff --git a/event.go b/event.go index 6c9e60f..1de87a7 100644 --- a/event.go +++ b/event.go @@ -24,38 +24,51 @@ type Event struct { } const ( - KindProfileMetadata int = 0 - KindTextNote int = 1 - KindRecommendServer int = 2 - KindContactList int = 3 - KindEncryptedDirectMessage int = 4 - KindDeletion int = 5 - KindRepost int = 6 - KindReaction int = 7 - KindChannelCreation int = 40 - KindChannelMetadata int = 41 - KindChannelMessage int = 42 - KindChannelHideMessage int = 43 - KindChannelMuteUser int = 44 - KindFileMetadata int = 1063 - KindZapRequest int = 9734 - KindZap int = 9735 - KindMuteList int = 10000 - KindPinList int = 10001 - KindRelayListMetadata int = 10002 - KindNWCWalletInfo int = 13194 - KindClientAuthentication int = 22242 - KindNWCWalletRequest int = 23194 - KindNWCWalletResponse int = 23195 - KindNostrConnect int = 24133 - KindCategorizedPeopleList int = 30000 - KindCategorizedBookmarksList int = 30001 - KindProfileBadges int = 30008 - KindBadgeDefinition int = 30009 - KindStallDefinition int = 30017 - KindProductDefinition int = 30018 - KindArticle int = 30023 - KindApplicationSpecificData int = 30078 + KindProfileMetadata int = 0 + KindTextNote int = 1 + KindRecommendServer int = 2 + KindContactList int = 3 + KindEncryptedDirectMessage int = 4 + KindDeletion int = 5 + KindRepost int = 6 + KindReaction int = 7 + KindSimpleGroupChatMessage int = 9 + KindSimpleGroupThread int = 11 + KindSimpleGroupReply int = 12 + KindChannelCreation int = 40 + KindChannelMetadata int = 41 + KindChannelMessage int = 42 + KindChannelHideMessage int = 43 + KindChannelMuteUser int = 44 + KindFileMetadata int = 1063 + KindSimpleGroupAddUser int = 9000 + KindSimpleGroupRemoveUser int = 9001 + KindSimpleGroupEditMetadata int = 9002 + KindSimpleGroupAddPermission int = 9003 + KindSimpleGroupRemovePermission int = 9004 + KindSimpleGroupDeleteEvent int = 9005 + KindSimpleGroupEditGroupStatus int = 9006 + KindZapRequest int = 9734 + KindZap int = 9735 + KindMuteList int = 10000 + KindPinList int = 10001 + KindRelayListMetadata int = 10002 + KindNWCWalletInfo int = 13194 + KindClientAuthentication int = 22242 + KindNWCWalletRequest int = 23194 + KindNWCWalletResponse int = 23195 + KindNostrConnect int = 24133 + KindCategorizedPeopleList int = 30000 + KindCategorizedBookmarksList int = 30001 + KindProfileBadges int = 30008 + KindBadgeDefinition int = 30009 + KindStallDefinition int = 30017 + KindProductDefinition int = 30018 + KindArticle int = 30023 + KindApplicationSpecificData int = 30078 + KindSimpleGroupMetadata int = 39000 + KindSimpleGroupAdmins int = 39001 + KindSimpleGroupMembers int = 39002 ) // Event Stringer interface, just returns the raw JSON as a string. diff --git a/nip29/group.go b/nip29/group.go new file mode 100644 index 0000000..a631436 --- /dev/null +++ b/nip29/group.go @@ -0,0 +1,75 @@ +package nip29 + +import ( + "fmt" + + "github.com/nbd-wtf/go-nostr" +) + +type Group struct { + ID string + Name string + Picture string + About string + Members map[string]*Role + Private bool + Closed bool +} + +func (group Group) MetadataEvent() *nostr.Event { + evt := &nostr.Event{ + Kind: 39000, + CreatedAt: nostr.Now(), + Content: group.About, + Tags: nostr.Tags{ + nostr.Tag{"d", group.ID}, + }, + } + if group.Name != "" { + evt.Tags = append(evt.Tags, nostr.Tag{"name", group.Name}) + } + if group.About != "" { + evt.Tags = append(evt.Tags, nostr.Tag{"about", group.Name}) + } + if group.Picture != "" { + evt.Tags = append(evt.Tags, nostr.Tag{"picture", group.Picture}) + } + + // status + if group.Private { + evt.Tags = append(evt.Tags, nostr.Tag{"private"}) + } else { + evt.Tags = append(evt.Tags, nostr.Tag{"public"}) + } + if group.Closed { + evt.Tags = append(evt.Tags, nostr.Tag{"closed"}) + } else { + evt.Tags = append(evt.Tags, nostr.Tag{"open"}) + } + + return evt +} + +func MetadataEventToGroup(evt *nostr.Event) (*Group, error) { + if evt.Kind != nostr.KindSimpleGroupMetadata { + return nil, fmt.Errorf("expected kind %d, got %d", nostr.KindSimpleGroupMetadata, evt.Kind) + } + + group := &Group{} + group.ID = evt.Tags.GetD() + + if tag := nostr.Tags.GetFirst([]string{"name", ""}); tag != nil { + group.Name = (*tag)[1] + } + if tag := nostr.Tags.GetFirst([]string{"about", ""}); tag != nil { + group.About = (*tag)[1] + } + if tag := nostr.Tags.GetFirst([]string{"picture", ""}); tag != nil { + group.Picture = (*tag)[1] + } + + + Members map[string]*Role + Private bool + Closed bool +} diff --git a/nip29/nip29.go b/nip29/nip29.go new file mode 100644 index 0000000..48a9dc2 --- /dev/null +++ b/nip29/nip29.go @@ -0,0 +1,46 @@ +package nip29 + +import ( + "github.com/nbd-wtf/go-nostr" + "golang.org/x/exp/slices" +) + +type Role struct { + Name string + Permissions map[Permission]struct{} +} + +type Permission = string + +const ( + PermAddUser Permission = "add-user" + PermEditMetadata Permission = "edit-metadata" + PermDeleteEvent Permission = "delete-event" + PermRemoveUser Permission = "remove-user" + PermAddPermission Permission = "add-permission" + PermRemovePermission Permission = "remove-permission" + PermEditGroupStatus Permission = "edit-group-status" +) + +type KindRange []int + +var ModerationEventKinds = KindRange{ + nostr.KindSimpleGroupAddUser, + nostr.KindSimpleGroupRemoveUser, + nostr.KindSimpleGroupEditMetadata, + nostr.KindSimpleGroupAddPermission, + nostr.KindSimpleGroupRemovePermission, + nostr.KindSimpleGroupDeleteEvent, + nostr.KindSimpleGroupEditGroupStatus, +} + +var MetadataEventKinds = KindRange{ + nostr.KindSimpleGroupMetadata, + nostr.KindSimpleGroupAdmins, + nostr.KindSimpleGroupMembers, +} + +func (kr KindRange) Includes(kind int) bool { + _, ok := slices.BinarySearch(kr, kind) + return ok +}