Add support for roles in nip 86

This commit is contained in:
Jon Staab
2026-06-22 09:50:44 -07:00
parent 545f2109ae
commit a525b66054
2 changed files with 193 additions and 0 deletions
+148
View File
@@ -4,6 +4,7 @@ import (
"fmt"
"math"
"net"
"strconv"
"fiatjaf.com/nostr"
)
@@ -240,6 +241,95 @@ func DecodeRequest(req Request) (MethodParams, error) {
Pubkey: pk,
DisallowMethods: disallowedMethods,
}, nil
case "createrole":
if len(req.Params) == 0 {
return nil, fmt.Errorf("invalid number of params for '%s'", req.Method)
}
id, ok := req.Params[0].(string)
if !ok {
return nil, fmt.Errorf("missing id param for '%s'", req.Method)
}
var label, description string
if len(req.Params) >= 2 {
label, _ = req.Params[1].(string)
}
if len(req.Params) >= 3 {
description, _ = req.Params[2].(string)
}
var color, order int
if len(req.Params) >= 4 {
color = coerceInt(req.Params[3])
}
if len(req.Params) >= 5 {
order = coerceInt(req.Params[4])
}
return CreateRole{id, label, description, color, order}, nil
case "editrole":
if len(req.Params) == 0 {
return nil, fmt.Errorf("invalid number of params for '%s'", req.Method)
}
id, ok := req.Params[0].(string)
if !ok {
return nil, fmt.Errorf("missing id param for '%s'", req.Method)
}
var label, description string
if len(req.Params) >= 2 {
label, _ = req.Params[1].(string)
}
if len(req.Params) >= 3 {
description, _ = req.Params[2].(string)
}
var color, order int
if len(req.Params) >= 4 {
color = coerceInt(req.Params[3])
}
if len(req.Params) >= 5 {
order = coerceInt(req.Params[4])
}
return EditRole{id, label, description, color, order}, nil
case "deleterole":
if len(req.Params) == 0 {
return nil, fmt.Errorf("invalid number of params for '%s'", req.Method)
}
id, ok := req.Params[0].(string)
if !ok {
return nil, fmt.Errorf("missing id param for '%s'", req.Method)
}
return DeleteRole{id}, nil
case "assignrole":
if len(req.Params) < 2 {
return nil, fmt.Errorf("invalid number of params for '%s'", req.Method)
}
pkh, ok := req.Params[0].(string)
if !ok {
return nil, fmt.Errorf("missing pubkey param for '%s'", req.Method)
}
pk, err := nostr.PubKeyFromHex(pkh)
if err != nil {
return nil, fmt.Errorf("invalid pubkey param for '%s'", req.Method)
}
roleID, ok := req.Params[1].(string)
if !ok {
return nil, fmt.Errorf("missing role id param for '%s'", req.Method)
}
return AssignRole{pk, roleID}, nil
case "unassignrole":
if len(req.Params) < 2 {
return nil, fmt.Errorf("invalid number of params for '%s'", req.Method)
}
pkh, ok := req.Params[0].(string)
if !ok {
return nil, fmt.Errorf("missing pubkey param for '%s'", req.Method)
}
pk, err := nostr.PubKeyFromHex(pkh)
if err != nil {
return nil, fmt.Errorf("invalid pubkey param for '%s'", req.Method)
}
roleID, ok := req.Params[1].(string)
if !ok {
return nil, fmt.Errorf("missing role id param for '%s'", req.Method)
}
return UnassignRole{pk, roleID}, nil
case "stats":
return Stats{}, nil
default:
@@ -247,6 +337,19 @@ func DecodeRequest(req Request) (MethodParams, error) {
}
}
// coerceInt converts a decoded JSON param (a float64 number or a numeric
// string) into an int, returning 0 when the value is neither.
func coerceInt(v any) int {
switch n := v.(type) {
case float64:
return int(n)
case string:
i, _ := strconv.Atoi(n)
return i
}
return 0
}
type MethodParams interface {
MethodName() string
}
@@ -276,6 +379,11 @@ var (
_ MethodParams = (*ListDisallowedKinds)(nil)
_ MethodParams = (*GrantAdmin)(nil)
_ MethodParams = (*RevokeAdmin)(nil)
_ MethodParams = (*CreateRole)(nil)
_ MethodParams = (*EditRole)(nil)
_ MethodParams = (*DeleteRole)(nil)
_ MethodParams = (*AssignRole)(nil)
_ MethodParams = (*UnassignRole)(nil)
_ MethodParams = (*Stats)(nil)
)
@@ -415,6 +523,46 @@ type RevokeAdmin struct {
func (RevokeAdmin) MethodName() string { return "revokeadmin" }
type CreateRole struct {
ID string
Label string
Description string
Color int
Order int
}
func (CreateRole) MethodName() string { return "createrole" }
type EditRole struct {
ID string
Label string
Description string
Color int
Order int
}
func (EditRole) MethodName() string { return "editrole" }
type DeleteRole struct {
ID string
}
func (DeleteRole) MethodName() string { return "deleterole" }
type AssignRole struct {
PubKey nostr.PubKey
RoleID string
}
func (AssignRole) MethodName() string { return "assignrole" }
type UnassignRole struct {
PubKey nostr.PubKey
RoleID string
}
func (UnassignRole) MethodName() string { return "unassignrole" }
type Stats struct{}
func (Stats) MethodName() string { return "stats" }