nip29: some more group helpers.

This commit is contained in:
fiatjaf
2024-05-10 17:54:08 -03:00
parent b43d0e374a
commit b8ec1343cc
2 changed files with 43 additions and 13 deletions

View File

@@ -2,12 +2,37 @@ package nip29
import ( import (
"fmt" "fmt"
"strings"
"github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr"
) )
type Group struct { type GroupAddress struct {
Relay string
ID string ID string
}
func (gid GroupAddress) String() string { return fmt.Sprintf("%s'%s", gid.ID, gid.Relay) }
func (gid GroupAddress) IsValid() bool {
return gid.Relay != "" && gid.ID != ""
}
func (gid GroupAddress) Equals(gid2 GroupAddress) bool {
return gid.Relay == gid2.Relay && gid.ID == gid2.ID
}
func ParseGroupAddress(raw string) (GroupAddress, error) {
spl := strings.Split(raw, "'")
if len(spl) != 2 {
return GroupAddress{}, fmt.Errorf("invalid group id")
}
return GroupAddress{ID: spl[0], Relay: nostr.NormalizeURL(spl[1])}, nil
}
type Group struct {
Address GroupAddress
Name string Name string
Picture string Picture string
About string About string
@@ -20,12 +45,17 @@ type Group struct {
LastMembersUpdate nostr.Timestamp LastMembersUpdate nostr.Timestamp
} }
func NewGroup(id string) Group { func NewGroup(id string) (Group, error) {
return Group{ gad, err := ParseGroupAddress(id)
ID: id, if err != nil {
Name: id, return Group{}, fmt.Errorf("invalid group id '%s': %w", id, err)
Members: make(map[string]*Role),
} }
return Group{
Address: gad,
Name: gad.ID,
Members: make(map[string]*Role),
}, nil
} }
func (group Group) ToMetadataEvent() *nostr.Event { func (group Group) ToMetadataEvent() *nostr.Event {
@@ -34,7 +64,7 @@ func (group Group) ToMetadataEvent() *nostr.Event {
CreatedAt: group.LastMetadataUpdate, CreatedAt: group.LastMetadataUpdate,
Content: group.About, Content: group.About,
Tags: nostr.Tags{ Tags: nostr.Tags{
nostr.Tag{"d", group.ID}, nostr.Tag{"d", group.Address.ID},
}, },
} }
if group.Name != "" { if group.Name != "" {
@@ -68,7 +98,7 @@ func (group Group) ToAdminsEvent() *nostr.Event {
CreatedAt: group.LastAdminsUpdate, CreatedAt: group.LastAdminsUpdate,
Tags: make(nostr.Tags, 1, 1+len(group.Members)/3), Tags: make(nostr.Tags, 1, 1+len(group.Members)/3),
} }
evt.Tags[0] = nostr.Tag{"d", group.ID} evt.Tags[0] = nostr.Tag{"d", group.Address.ID}
for member, role := range group.Members { for member, role := range group.Members {
if role != nil { if role != nil {
@@ -93,7 +123,7 @@ func (group Group) ToMembersEvent() *nostr.Event {
CreatedAt: group.LastMembersUpdate, CreatedAt: group.LastMembersUpdate,
Tags: make(nostr.Tags, 1, 1+len(group.Members)), Tags: make(nostr.Tags, 1, 1+len(group.Members)),
} }
evt.Tags[0] = nostr.Tag{"d", group.ID} evt.Tags[0] = nostr.Tag{"d", group.Address.ID}
for member := range group.Members { for member := range group.Members {
// include both admins and normal members // include both admins and normal members
@@ -112,7 +142,7 @@ func (group *Group) MergeInMetadataEvent(evt *nostr.Event) error {
} }
group.LastMetadataUpdate = evt.CreatedAt group.LastMetadataUpdate = evt.CreatedAt
group.Name = group.ID group.Name = group.Address.ID
if tag := evt.Tags.GetFirst([]string{"name", ""}); tag != nil { if tag := evt.Tags.GetFirst([]string{"name", ""}); tag != nil {
group.Name = (*tag)[1] group.Name = (*tag)[1]

View File

@@ -12,7 +12,7 @@ const (
) )
func TestGroupEventBackAndForth(t *testing.T) { func TestGroupEventBackAndForth(t *testing.T) {
group1 := NewGroup("xyz") group1, _ := NewGroup("xyz")
group1.Name = "banana" group1.Name = "banana"
group1.Private = true group1.Private = true
meta1 := group1.ToMetadataEvent() meta1 := group1.ToMetadataEvent()
@@ -22,7 +22,7 @@ func TestGroupEventBackAndForth(t *testing.T) {
t.Fatalf("translation of group1 to meta1data event failed") t.Fatalf("translation of group1 to meta1data event failed")
} }
group2 := NewGroup("abc") group2, _ := NewGroup("abc")
group2.Members[ALICE] = &Role{Name: "nada", Permissions: map[Permission]struct{}{PermAddUser: {}}} group2.Members[ALICE] = &Role{Name: "nada", Permissions: map[Permission]struct{}{PermAddUser: {}}}
group2.Members[BOB] = &Role{Name: "nada", Permissions: map[Permission]struct{}{PermEditMetadata: {}}} group2.Members[BOB] = &Role{Name: "nada", Permissions: map[Permission]struct{}{PermEditMetadata: {}}}
group2.Members[CAROL] = EmptyRole group2.Members[CAROL] = EmptyRole
@@ -55,7 +55,7 @@ func TestGroupEventBackAndForth(t *testing.T) {
} }
group2.MergeInMetadataEvent(meta1) group2.MergeInMetadataEvent(meta1)
if group2.Name != "banana" || group2.ID != "abc" { if group2.Name != "banana" || group2.Address.ID != "abc" {
t.Fatalf("merge of meta1 into group2 failed") t.Fatalf("merge of meta1 into group2 failed")
} }
} }