feat: add CommunityTokenPermission to community description

This adds token permission capabilities to CommunityDescription such that token permissions can be created, updated and deleted.
This commit is contained in:
Pascal Precht 2023-03-02 17:27:48 +01:00 committed by r4bbit
parent 2ef10f23e5
commit 596660c110
10 changed files with 750 additions and 165 deletions

View File

@ -95,23 +95,24 @@ func (o *Community) MarshalPublicAPIJSON() ([]byte, error) {
return nil, errors.New("member identity not set") return nil, errors.New("member identity not set")
} }
communityItem := struct { communityItem := struct {
ID types.HexBytes `json:"id"` ID types.HexBytes `json:"id"`
Verified bool `json:"verified"` Verified bool `json:"verified"`
Chats map[string]CommunityChat `json:"chats"` Chats map[string]CommunityChat `json:"chats"`
Categories map[string]CommunityCategory `json:"categories"` Categories map[string]CommunityCategory `json:"categories"`
Name string `json:"name"` Name string `json:"name"`
Description string `json:"description"` Description string `json:"description"`
IntroMessage string `json:"introMessage"` IntroMessage string `json:"introMessage"`
OutroMessage string `json:"outroMessage"` OutroMessage string `json:"outroMessage"`
Tags []CommunityTag `json:"tags"` Tags []CommunityTag `json:"tags"`
Images map[string]images.IdentityImage `json:"images"` Images map[string]images.IdentityImage `json:"images"`
Color string `json:"color"` Color string `json:"color"`
MembersCount int `json:"membersCount"` MembersCount int `json:"membersCount"`
EnsName string `json:"ensName"` EnsName string `json:"ensName"`
Link string `json:"link"` Link string `json:"link"`
CommunityAdminSettings CommunityAdminSettings `json:"adminSettings"` CommunityAdminSettings CommunityAdminSettings `json:"adminSettings"`
Encrypted bool `json:"encrypted"` Encrypted bool `json:"encrypted"`
BanList []string `json:"banList"` BanList []string `json:"banList"`
TokenPermissions map[string]*protobuf.CommunityTokenPermission `json:"tokenPermissions"`
}{ }{
ID: o.ID(), ID: o.ID(),
Verified: o.config.Verified, Verified: o.config.Verified,
@ -148,6 +149,8 @@ func (o *Community) MarshalPublicAPIJSON() ([]byte, error) {
} }
communityItem.Chats[id] = chat communityItem.Chats[id] = chat
} }
communityItem.TokenPermissions = o.config.CommunityDescription.TokenPermissions
communityItem.MembersCount = len(o.config.CommunityDescription.Members) communityItem.MembersCount = len(o.config.CommunityDescription.Members)
communityItem.Link = fmt.Sprintf("https://join.status.im/c/0x%x", o.ID()) communityItem.Link = fmt.Sprintf("https://join.status.im/c/0x%x", o.ID())
communityItem.IntroMessage = o.config.CommunityDescription.IntroMessage communityItem.IntroMessage = o.config.CommunityDescription.IntroMessage
@ -183,33 +186,34 @@ func (o *Community) MarshalJSON() ([]byte, error) {
return nil, errors.New("member identity not set") return nil, errors.New("member identity not set")
} }
communityItem := struct { communityItem := struct {
ID types.HexBytes `json:"id"` ID types.HexBytes `json:"id"`
Admin bool `json:"admin"` Admin bool `json:"admin"`
Verified bool `json:"verified"` Verified bool `json:"verified"`
Joined bool `json:"joined"` Joined bool `json:"joined"`
Spectated bool `json:"spectated"` Spectated bool `json:"spectated"`
RequestedAccessAt int `json:"requestedAccessAt"` RequestedAccessAt int `json:"requestedAccessAt"`
Name string `json:"name"` Name string `json:"name"`
Description string `json:"description"` Description string `json:"description"`
IntroMessage string `json:"introMessage"` IntroMessage string `json:"introMessage"`
OutroMessage string `json:"outroMessage"` OutroMessage string `json:"outroMessage"`
Tags []CommunityTag `json:"tags"` Tags []CommunityTag `json:"tags"`
Chats map[string]CommunityChat `json:"chats"` Chats map[string]CommunityChat `json:"chats"`
Categories map[string]CommunityCategory `json:"categories"` Categories map[string]CommunityCategory `json:"categories"`
Images map[string]images.IdentityImage `json:"images"` Images map[string]images.IdentityImage `json:"images"`
Permissions *protobuf.CommunityPermissions `json:"permissions"` Permissions *protobuf.CommunityPermissions `json:"permissions"`
Members map[string]*protobuf.CommunityMember `json:"members"` Members map[string]*protobuf.CommunityMember `json:"members"`
CanRequestAccess bool `json:"canRequestAccess"` CanRequestAccess bool `json:"canRequestAccess"`
CanManageUsers bool `json:"canManageUsers"` CanManageUsers bool `json:"canManageUsers"`
CanDeleteMessageForEveryone bool `json:"canDeleteMessageForEveryone"` CanDeleteMessageForEveryone bool `json:"canDeleteMessageForEveryone"`
CanJoin bool `json:"canJoin"` CanJoin bool `json:"canJoin"`
Color string `json:"color"` Color string `json:"color"`
RequestedToJoinAt uint64 `json:"requestedToJoinAt,omitempty"` RequestedToJoinAt uint64 `json:"requestedToJoinAt,omitempty"`
IsMember bool `json:"isMember"` IsMember bool `json:"isMember"`
Muted bool `json:"muted"` Muted bool `json:"muted"`
CommunityAdminSettings CommunityAdminSettings `json:"adminSettings"` CommunityAdminSettings CommunityAdminSettings `json:"adminSettings"`
Encrypted bool `json:"encrypted"` Encrypted bool `json:"encrypted"`
BanList []string `json:"banList"` BanList []string `json:"banList"`
TokenPermissions map[string]*protobuf.CommunityTokenPermission `json:"tokenPermissions"`
}{ }{
ID: o.ID(), ID: o.ID(),
Admin: o.IsAdmin(), Admin: o.IsAdmin(),
@ -257,6 +261,7 @@ func (o *Community) MarshalJSON() ([]byte, error) {
} }
communityItem.Chats[id] = chat communityItem.Chats[id] = chat
} }
communityItem.TokenPermissions = o.config.CommunityDescription.TokenPermissions
communityItem.Members = o.config.CommunityDescription.Members communityItem.Members = o.config.CommunityDescription.Members
communityItem.Permissions = o.config.CommunityDescription.Permissions communityItem.Permissions = o.config.CommunityDescription.Permissions
communityItem.IntroMessage = o.config.CommunityDescription.IntroMessage communityItem.IntroMessage = o.config.CommunityDescription.IntroMessage
@ -432,6 +437,10 @@ type CommunityChanges struct {
MembersAdded map[string]*protobuf.CommunityMember `json:"membersAdded"` MembersAdded map[string]*protobuf.CommunityMember `json:"membersAdded"`
MembersRemoved map[string]*protobuf.CommunityMember `json:"membersRemoved"` MembersRemoved map[string]*protobuf.CommunityMember `json:"membersRemoved"`
TokenPermissionsAdded map[string]*protobuf.CommunityTokenPermission `json:"tokenPermissionsAdded"`
TokenPermissionsModified map[string]*protobuf.CommunityTokenPermission `json:"tokenPermissionsModified"`
TokenPermissionsRemoved []string `json:"tokenPermissionsRemoved"`
ChatsRemoved map[string]*protobuf.CommunityChat `json:"chatsRemoved"` ChatsRemoved map[string]*protobuf.CommunityChat `json:"chatsRemoved"`
ChatsAdded map[string]*protobuf.CommunityChat `json:"chatsAdded"` ChatsAdded map[string]*protobuf.CommunityChat `json:"chatsAdded"`
ChatsModified map[string]*CommunityChatChanges `json:"chatsModified"` ChatsModified map[string]*CommunityChatChanges `json:"chatsModified"`
@ -1390,6 +1399,80 @@ func (o *Community) Categories() map[string]*protobuf.CommunityCategory {
return response return response
} }
func (o *Community) AddTokenPermission(permission *protobuf.CommunityTokenPermission) (*CommunityChanges, error) {
o.mutex.Lock()
defer o.mutex.Unlock()
if o.config.PrivateKey == nil {
return nil, ErrNotAdmin
}
if o.config.CommunityDescription.TokenPermissions == nil {
o.config.CommunityDescription.TokenPermissions = make(map[string]*protobuf.CommunityTokenPermission)
}
if _, exists := o.config.CommunityDescription.TokenPermissions[permission.Id]; exists {
return nil, ErrTokenPermissionAlreadyExists
}
o.config.CommunityDescription.TokenPermissions[permission.Id] = permission
o.increaseClock()
changes := o.emptyCommunityChanges()
if changes.TokenPermissionsAdded == nil {
changes.TokenPermissionsAdded = make(map[string]*protobuf.CommunityTokenPermission)
}
changes.TokenPermissionsAdded[permission.Id] = permission
return changes, nil
}
func (o *Community) UpdateTokenPermission(permissionID string, tokenPermission *protobuf.CommunityTokenPermission) (*CommunityChanges, error) {
o.mutex.Lock()
defer o.mutex.Unlock()
if o.config.PrivateKey == nil {
return nil, ErrNotAdmin
}
if o.config.CommunityDescription.TokenPermissions == nil {
o.config.CommunityDescription.TokenPermissions = make(map[string]*protobuf.CommunityTokenPermission)
}
if _, ok := o.config.CommunityDescription.TokenPermissions[permissionID]; !ok {
return nil, ErrTokenPermissionNotFound
}
changes := o.emptyCommunityChanges()
o.config.CommunityDescription.TokenPermissions[permissionID] = tokenPermission
o.increaseClock()
if changes.TokenPermissionsModified == nil {
changes.TokenPermissionsModified = make(map[string]*protobuf.CommunityTokenPermission)
}
changes.TokenPermissionsModified[permissionID] = o.config.CommunityDescription.TokenPermissions[tokenPermission.Id]
return changes, nil
}
func (o *Community) DeleteTokenPermission(permissionID string) (*CommunityChanges, error) {
o.mutex.Lock()
defer o.mutex.Unlock()
if o.config.PrivateKey == nil {
return nil, ErrNotAdmin
}
if _, exists := o.config.CommunityDescription.TokenPermissions[permissionID]; !exists {
return nil, ErrTokenPermissionNotFound
}
delete(o.config.CommunityDescription.TokenPermissions, permissionID)
changes := o.emptyCommunityChanges()
changes.TokenPermissionsRemoved = append(changes.TokenPermissionsRemoved, permissionID)
o.increaseClock()
return changes, nil
}
func (o *Community) VerifyGrantSignature(data []byte) (*protobuf.Grant, error) { func (o *Community) VerifyGrantSignature(data []byte) (*protobuf.Grant, error) {
if len(data) <= signatureLength { if len(data) <= signatureLength {
return nil, ErrInvalidGrant return nil, ErrInvalidGrant

View File

@ -29,3 +29,5 @@ var ErrAlreadyMember = errors.New("already a member")
var ErrAlreadyJoined = errors.New("already joined") var ErrAlreadyJoined = errors.New("already joined")
var ErrInvalidMessage = errors.New("invalid community description message") var ErrInvalidMessage = errors.New("invalid community description message")
var ErrMemberNotFound = errors.New("member not found") var ErrMemberNotFound = errors.New("member not found")
var ErrTokenPermissionAlreadyExists = errors.New("token permission already exists")
var ErrTokenPermissionNotFound = errors.New("token permission not found")

View File

@ -439,6 +439,83 @@ func (m *Manager) CreateCommunity(request *requests.CreateCommunity, publish boo
return community, nil return community, nil
} }
func (m *Manager) CreateCommunityTokenPermission(request *requests.CreateCommunityTokenPermission) (*Community, *CommunityChanges, error) {
community, err := m.GetByID(request.CommunityID)
if err != nil {
return nil, nil, err
}
if community == nil {
return nil, nil, ErrOrgNotFound
}
tokenPermission := request.ToCommunityTokenPermission()
tokenPermission.Id = uuid.New().String()
changes, err := community.AddTokenPermission(&tokenPermission)
if err != nil {
return nil, nil, err
}
err = m.persistence.SaveCommunity(community)
if err != nil {
return nil, nil, err
}
m.publish(&Subscription{Community: community})
return community, changes, nil
}
func (m *Manager) EditCommunityTokenPermission(request *requests.EditCommunityTokenPermission) (*Community, *CommunityChanges, error) {
community, err := m.GetByID(request.CommunityID)
if err != nil {
return nil, nil, err
}
if community == nil {
return nil, nil, ErrOrgNotFound
}
tokenPermission := request.ToCommunityTokenPermission()
changes, err := community.UpdateTokenPermission(tokenPermission.Id, &tokenPermission)
if err != nil {
return nil, nil, err
}
err = m.persistence.SaveCommunity(community)
if err != nil {
return nil, nil, err
}
m.publish(&Subscription{Community: community})
return community, changes, nil
}
func (m *Manager) DeleteCommunityTokenPermission(request *requests.DeleteCommunityTokenPermission) (*Community, *CommunityChanges, error) {
community, err := m.GetByID(request.CommunityID)
if err != nil {
return nil, nil, err
}
if community == nil {
return nil, nil, ErrOrgNotFound
}
changes, err := community.DeleteTokenPermission(request.PermissionID)
if err != nil {
return nil, nil, err
}
err = m.persistence.SaveCommunity(community)
if err != nil {
return nil, nil, err
}
m.publish(&Subscription{Community: community})
return community, changes, nil
}
func (m *Manager) DeleteCommunity(id types.HexBytes) error { func (m *Manager) DeleteCommunity(id types.HexBytes) error {
err := m.persistence.DeleteCommunity(id) err := m.persistence.DeleteCommunity(id)
if err != nil { if err != nil {

View File

@ -1070,6 +1070,56 @@ func (m *Messenger) CreateCommunity(request *requests.CreateCommunity, createDef
return response, nil return response, nil
} }
func (m *Messenger) CreateCommunityTokenPermission(request *requests.CreateCommunityTokenPermission) (*MessengerResponse, error) {
if err := request.Validate(); err != nil {
return nil, err
}
community, changes, err := m.communitiesManager.CreateCommunityTokenPermission(request)
if err != nil {
return nil, err
}
response := &MessengerResponse{}
response.AddCommunity(community)
response.CommunityChanges = []*communities.CommunityChanges{changes}
return response, nil
}
func (m *Messenger) EditCommunityTokenPermission(request *requests.EditCommunityTokenPermission) (*MessengerResponse, error) {
if err := request.Validate(); err != nil {
return nil, err
}
community, changes, err := m.communitiesManager.EditCommunityTokenPermission(request)
if err != nil {
return nil, err
}
response := &MessengerResponse{}
response.AddCommunity(community)
response.CommunityChanges = []*communities.CommunityChanges{changes}
return response, nil
}
func (m *Messenger) DeleteCommunityTokenPermission(request *requests.DeleteCommunityTokenPermission) (*MessengerResponse, error) {
if err := request.Validate(); err != nil {
return nil, err
}
community, changes, err := m.communitiesManager.DeleteCommunityTokenPermission(request)
if err != nil {
return nil, err
}
response := &MessengerResponse{}
response.AddCommunity(community)
response.CommunityChanges = []*communities.CommunityChanges{changes}
return response, nil
}
func (m *Messenger) EditCommunity(request *requests.EditCommunity) (*MessengerResponse, error) { func (m *Messenger) EditCommunity(request *requests.EditCommunity) (*MessengerResponse, error) {
if err := request.Validate(); err != nil { if err := request.Validate(); err != nil {
return nil, err return nil, err

View File

@ -82,6 +82,34 @@ func (CommunityPermissions_Access) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{2, 0} return fileDescriptor_f937943d74c1cd8b, []int{2, 0}
} }
type CommunityTokenPermission_Type int32
const (
CommunityTokenPermission_UNKNOWN_TOKEN_PERMISSION CommunityTokenPermission_Type = 0
CommunityTokenPermission_BECOME_ADMIN CommunityTokenPermission_Type = 1
CommunityTokenPermission_BECOME_MEMBER CommunityTokenPermission_Type = 2
)
var CommunityTokenPermission_Type_name = map[int32]string{
0: "UNKNOWN_TOKEN_PERMISSION",
1: "BECOME_ADMIN",
2: "BECOME_MEMBER",
}
var CommunityTokenPermission_Type_value = map[string]int32{
"UNKNOWN_TOKEN_PERMISSION": 0,
"BECOME_ADMIN": 1,
"BECOME_MEMBER": 2,
}
func (x CommunityTokenPermission_Type) String() string {
return proto.EnumName(CommunityTokenPermission_Type_name, int32(x))
}
func (CommunityTokenPermission_Type) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{4, 0}
}
type Grant struct { type Grant struct {
CommunityId []byte `protobuf:"bytes,1,opt,name=community_id,json=communityId,proto3" json:"community_id,omitempty"` CommunityId []byte `protobuf:"bytes,1,opt,name=community_id,json=communityId,proto3" json:"community_id,omitempty"`
MemberId []byte `protobuf:"bytes,2,opt,name=member_id,json=memberId,proto3" json:"member_id,omitempty"` MemberId []byte `protobuf:"bytes,2,opt,name=member_id,json=memberId,proto3" json:"member_id,omitempty"`
@ -240,30 +268,189 @@ func (m *CommunityPermissions) GetAccess() CommunityPermissions_Access {
return CommunityPermissions_UNKNOWN_ACCESS return CommunityPermissions_UNKNOWN_ACCESS
} }
type TokenCriteria struct {
ContractAddresses map[uint64]string `protobuf:"bytes,1,rep,name=contract_addresses,json=contractAddresses,proto3" json:"contract_addresses,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Type CommunityTokenType `protobuf:"varint,2,opt,name=type,proto3,enum=protobuf.CommunityTokenType" json:"type,omitempty"`
Symbol string `protobuf:"bytes,3,opt,name=symbol,proto3" json:"symbol,omitempty"`
Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"`
Amount string `protobuf:"bytes,5,opt,name=amount,proto3" json:"amount,omitempty"`
TokenIds []uint64 `protobuf:"varint,6,rep,packed,name=token_ids,json=tokenIds,proto3" json:"token_ids,omitempty"`
EnsPattern string `protobuf:"bytes,7,opt,name=ens_pattern,json=ensPattern,proto3" json:"ens_pattern,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *TokenCriteria) Reset() { *m = TokenCriteria{} }
func (m *TokenCriteria) String() string { return proto.CompactTextString(m) }
func (*TokenCriteria) ProtoMessage() {}
func (*TokenCriteria) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{3}
}
func (m *TokenCriteria) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_TokenCriteria.Unmarshal(m, b)
}
func (m *TokenCriteria) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_TokenCriteria.Marshal(b, m, deterministic)
}
func (m *TokenCriteria) XXX_Merge(src proto.Message) {
xxx_messageInfo_TokenCriteria.Merge(m, src)
}
func (m *TokenCriteria) XXX_Size() int {
return xxx_messageInfo_TokenCriteria.Size(m)
}
func (m *TokenCriteria) XXX_DiscardUnknown() {
xxx_messageInfo_TokenCriteria.DiscardUnknown(m)
}
var xxx_messageInfo_TokenCriteria proto.InternalMessageInfo
func (m *TokenCriteria) GetContractAddresses() map[uint64]string {
if m != nil {
return m.ContractAddresses
}
return nil
}
func (m *TokenCriteria) GetType() CommunityTokenType {
if m != nil {
return m.Type
}
return CommunityTokenType_UNKNOWN_TOKEN_TYPE
}
func (m *TokenCriteria) GetSymbol() string {
if m != nil {
return m.Symbol
}
return ""
}
func (m *TokenCriteria) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *TokenCriteria) GetAmount() string {
if m != nil {
return m.Amount
}
return ""
}
func (m *TokenCriteria) GetTokenIds() []uint64 {
if m != nil {
return m.TokenIds
}
return nil
}
func (m *TokenCriteria) GetEnsPattern() string {
if m != nil {
return m.EnsPattern
}
return ""
}
type CommunityTokenPermission struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Type CommunityTokenPermission_Type `protobuf:"varint,2,opt,name=type,proto3,enum=protobuf.CommunityTokenPermission_Type" json:"type,omitempty"`
TokenCriteria []*TokenCriteria `protobuf:"bytes,3,rep,name=token_criteria,json=tokenCriteria,proto3" json:"token_criteria,omitempty"`
ChatIds []string `protobuf:"bytes,4,rep,name=chat_ids,json=chatIds,proto3" json:"chat_ids,omitempty"`
IsPrivate bool `protobuf:"varint,5,opt,name=is_private,json=isPrivate,proto3" json:"is_private,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CommunityTokenPermission) Reset() { *m = CommunityTokenPermission{} }
func (m *CommunityTokenPermission) String() string { return proto.CompactTextString(m) }
func (*CommunityTokenPermission) ProtoMessage() {}
func (*CommunityTokenPermission) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{4}
}
func (m *CommunityTokenPermission) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CommunityTokenPermission.Unmarshal(m, b)
}
func (m *CommunityTokenPermission) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CommunityTokenPermission.Marshal(b, m, deterministic)
}
func (m *CommunityTokenPermission) XXX_Merge(src proto.Message) {
xxx_messageInfo_CommunityTokenPermission.Merge(m, src)
}
func (m *CommunityTokenPermission) XXX_Size() int {
return xxx_messageInfo_CommunityTokenPermission.Size(m)
}
func (m *CommunityTokenPermission) XXX_DiscardUnknown() {
xxx_messageInfo_CommunityTokenPermission.DiscardUnknown(m)
}
var xxx_messageInfo_CommunityTokenPermission proto.InternalMessageInfo
func (m *CommunityTokenPermission) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *CommunityTokenPermission) GetType() CommunityTokenPermission_Type {
if m != nil {
return m.Type
}
return CommunityTokenPermission_UNKNOWN_TOKEN_PERMISSION
}
func (m *CommunityTokenPermission) GetTokenCriteria() []*TokenCriteria {
if m != nil {
return m.TokenCriteria
}
return nil
}
func (m *CommunityTokenPermission) GetChatIds() []string {
if m != nil {
return m.ChatIds
}
return nil
}
func (m *CommunityTokenPermission) GetIsPrivate() bool {
if m != nil {
return m.IsPrivate
}
return false
}
type CommunityDescription struct { type CommunityDescription struct {
Clock uint64 `protobuf:"varint,1,opt,name=clock,proto3" json:"clock,omitempty"` Clock uint64 `protobuf:"varint,1,opt,name=clock,proto3" json:"clock,omitempty"`
Members map[string]*CommunityMember `protobuf:"bytes,2,rep,name=members,proto3" json:"members,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` Members map[string]*CommunityMember `protobuf:"bytes,2,rep,name=members,proto3" json:"members,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Permissions *CommunityPermissions `protobuf:"bytes,3,opt,name=permissions,proto3" json:"permissions,omitempty"` Permissions *CommunityPermissions `protobuf:"bytes,3,opt,name=permissions,proto3" json:"permissions,omitempty"`
Identity *ChatIdentity `protobuf:"bytes,5,opt,name=identity,proto3" json:"identity,omitempty"` Identity *ChatIdentity `protobuf:"bytes,5,opt,name=identity,proto3" json:"identity,omitempty"`
Chats map[string]*CommunityChat `protobuf:"bytes,6,rep,name=chats,proto3" json:"chats,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` Chats map[string]*CommunityChat `protobuf:"bytes,6,rep,name=chats,proto3" json:"chats,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
BanList []string `protobuf:"bytes,7,rep,name=ban_list,json=banList,proto3" json:"ban_list,omitempty"` BanList []string `protobuf:"bytes,7,rep,name=ban_list,json=banList,proto3" json:"ban_list,omitempty"`
Categories map[string]*CommunityCategory `protobuf:"bytes,8,rep,name=categories,proto3" json:"categories,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` Categories map[string]*CommunityCategory `protobuf:"bytes,8,rep,name=categories,proto3" json:"categories,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
ArchiveMagnetlinkClock uint64 `protobuf:"varint,9,opt,name=archive_magnetlink_clock,json=archiveMagnetlinkClock,proto3" json:"archive_magnetlink_clock,omitempty"` ArchiveMagnetlinkClock uint64 `protobuf:"varint,9,opt,name=archive_magnetlink_clock,json=archiveMagnetlinkClock,proto3" json:"archive_magnetlink_clock,omitempty"`
AdminSettings *CommunityAdminSettings `protobuf:"bytes,10,opt,name=admin_settings,json=adminSettings,proto3" json:"admin_settings,omitempty"` AdminSettings *CommunityAdminSettings `protobuf:"bytes,10,opt,name=admin_settings,json=adminSettings,proto3" json:"admin_settings,omitempty"`
IntroMessage string `protobuf:"bytes,11,opt,name=intro_message,json=introMessage,proto3" json:"intro_message,omitempty"` IntroMessage string `protobuf:"bytes,11,opt,name=intro_message,json=introMessage,proto3" json:"intro_message,omitempty"`
OutroMessage string `protobuf:"bytes,12,opt,name=outro_message,json=outroMessage,proto3" json:"outro_message,omitempty"` OutroMessage string `protobuf:"bytes,12,opt,name=outro_message,json=outroMessage,proto3" json:"outro_message,omitempty"`
Encrypted bool `protobuf:"varint,13,opt,name=encrypted,proto3" json:"encrypted,omitempty"` Encrypted bool `protobuf:"varint,13,opt,name=encrypted,proto3" json:"encrypted,omitempty"`
Tags []string `protobuf:"bytes,14,rep,name=tags,proto3" json:"tags,omitempty"` Tags []string `protobuf:"bytes,14,rep,name=tags,proto3" json:"tags,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` TokenPermissions map[string]*CommunityTokenPermission `protobuf:"bytes,15,rep,name=token_permissions,json=tokenPermissions,proto3" json:"token_permissions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_unrecognized []byte `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *CommunityDescription) Reset() { *m = CommunityDescription{} } func (m *CommunityDescription) Reset() { *m = CommunityDescription{} }
func (m *CommunityDescription) String() string { return proto.CompactTextString(m) } func (m *CommunityDescription) String() string { return proto.CompactTextString(m) }
func (*CommunityDescription) ProtoMessage() {} func (*CommunityDescription) ProtoMessage() {}
func (*CommunityDescription) Descriptor() ([]byte, []int) { func (*CommunityDescription) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{3} return fileDescriptor_f937943d74c1cd8b, []int{5}
} }
func (m *CommunityDescription) XXX_Unmarshal(b []byte) error { func (m *CommunityDescription) XXX_Unmarshal(b []byte) error {
@ -375,6 +562,13 @@ func (m *CommunityDescription) GetTags() []string {
return nil return nil
} }
func (m *CommunityDescription) GetTokenPermissions() map[string]*CommunityTokenPermission {
if m != nil {
return m.TokenPermissions
}
return nil
}
type CommunityAdminSettings struct { type CommunityAdminSettings struct {
PinMessageAllMembersEnabled bool `protobuf:"varint,1,opt,name=pin_message_all_members_enabled,json=pinMessageAllMembersEnabled,proto3" json:"pin_message_all_members_enabled,omitempty"` PinMessageAllMembersEnabled bool `protobuf:"varint,1,opt,name=pin_message_all_members_enabled,json=pinMessageAllMembersEnabled,proto3" json:"pin_message_all_members_enabled,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
@ -386,7 +580,7 @@ func (m *CommunityAdminSettings) Reset() { *m = CommunityAdminSettings{}
func (m *CommunityAdminSettings) String() string { return proto.CompactTextString(m) } func (m *CommunityAdminSettings) String() string { return proto.CompactTextString(m) }
func (*CommunityAdminSettings) ProtoMessage() {} func (*CommunityAdminSettings) ProtoMessage() {}
func (*CommunityAdminSettings) Descriptor() ([]byte, []int) { func (*CommunityAdminSettings) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{4} return fileDescriptor_f937943d74c1cd8b, []int{6}
} }
func (m *CommunityAdminSettings) XXX_Unmarshal(b []byte) error { func (m *CommunityAdminSettings) XXX_Unmarshal(b []byte) error {
@ -429,7 +623,7 @@ func (m *CommunityChat) Reset() { *m = CommunityChat{} }
func (m *CommunityChat) String() string { return proto.CompactTextString(m) } func (m *CommunityChat) String() string { return proto.CompactTextString(m) }
func (*CommunityChat) ProtoMessage() {} func (*CommunityChat) ProtoMessage() {}
func (*CommunityChat) Descriptor() ([]byte, []int) { func (*CommunityChat) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{5} return fileDescriptor_f937943d74c1cd8b, []int{7}
} }
func (m *CommunityChat) XXX_Unmarshal(b []byte) error { func (m *CommunityChat) XXX_Unmarshal(b []byte) error {
@ -498,7 +692,7 @@ func (m *CommunityCategory) Reset() { *m = CommunityCategory{} }
func (m *CommunityCategory) String() string { return proto.CompactTextString(m) } func (m *CommunityCategory) String() string { return proto.CompactTextString(m) }
func (*CommunityCategory) ProtoMessage() {} func (*CommunityCategory) ProtoMessage() {}
func (*CommunityCategory) Descriptor() ([]byte, []int) { func (*CommunityCategory) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{6} return fileDescriptor_f937943d74c1cd8b, []int{8}
} }
func (m *CommunityCategory) XXX_Unmarshal(b []byte) error { func (m *CommunityCategory) XXX_Unmarshal(b []byte) error {
@ -554,7 +748,7 @@ func (m *CommunityInvitation) Reset() { *m = CommunityInvitation{} }
func (m *CommunityInvitation) String() string { return proto.CompactTextString(m) } func (m *CommunityInvitation) String() string { return proto.CompactTextString(m) }
func (*CommunityInvitation) ProtoMessage() {} func (*CommunityInvitation) ProtoMessage() {}
func (*CommunityInvitation) Descriptor() ([]byte, []int) { func (*CommunityInvitation) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{7} return fileDescriptor_f937943d74c1cd8b, []int{9}
} }
func (m *CommunityInvitation) XXX_Unmarshal(b []byte) error { func (m *CommunityInvitation) XXX_Unmarshal(b []byte) error {
@ -618,7 +812,7 @@ func (m *CommunityRequestToJoin) Reset() { *m = CommunityRequestToJoin{}
func (m *CommunityRequestToJoin) String() string { return proto.CompactTextString(m) } func (m *CommunityRequestToJoin) String() string { return proto.CompactTextString(m) }
func (*CommunityRequestToJoin) ProtoMessage() {} func (*CommunityRequestToJoin) ProtoMessage() {}
func (*CommunityRequestToJoin) Descriptor() ([]byte, []int) { func (*CommunityRequestToJoin) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{8} return fileDescriptor_f937943d74c1cd8b, []int{10}
} }
func (m *CommunityRequestToJoin) XXX_Unmarshal(b []byte) error { func (m *CommunityRequestToJoin) XXX_Unmarshal(b []byte) error {
@ -689,7 +883,7 @@ func (m *CommunityCancelRequestToJoin) Reset() { *m = CommunityCancelReq
func (m *CommunityCancelRequestToJoin) String() string { return proto.CompactTextString(m) } func (m *CommunityCancelRequestToJoin) String() string { return proto.CompactTextString(m) }
func (*CommunityCancelRequestToJoin) ProtoMessage() {} func (*CommunityCancelRequestToJoin) ProtoMessage() {}
func (*CommunityCancelRequestToJoin) Descriptor() ([]byte, []int) { func (*CommunityCancelRequestToJoin) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{9} return fileDescriptor_f937943d74c1cd8b, []int{11}
} }
func (m *CommunityCancelRequestToJoin) XXX_Unmarshal(b []byte) error { func (m *CommunityCancelRequestToJoin) XXX_Unmarshal(b []byte) error {
@ -761,7 +955,7 @@ func (m *CommunityRequestToJoinResponse) Reset() { *m = CommunityRequest
func (m *CommunityRequestToJoinResponse) String() string { return proto.CompactTextString(m) } func (m *CommunityRequestToJoinResponse) String() string { return proto.CompactTextString(m) }
func (*CommunityRequestToJoinResponse) ProtoMessage() {} func (*CommunityRequestToJoinResponse) ProtoMessage() {}
func (*CommunityRequestToJoinResponse) Descriptor() ([]byte, []int) { func (*CommunityRequestToJoinResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{10} return fileDescriptor_f937943d74c1cd8b, []int{12}
} }
func (m *CommunityRequestToJoinResponse) XXX_Unmarshal(b []byte) error { func (m *CommunityRequestToJoinResponse) XXX_Unmarshal(b []byte) error {
@ -836,7 +1030,7 @@ func (m *CommunityRequestToLeave) Reset() { *m = CommunityRequestToLeave
func (m *CommunityRequestToLeave) String() string { return proto.CompactTextString(m) } func (m *CommunityRequestToLeave) String() string { return proto.CompactTextString(m) }
func (*CommunityRequestToLeave) ProtoMessage() {} func (*CommunityRequestToLeave) ProtoMessage() {}
func (*CommunityRequestToLeave) Descriptor() ([]byte, []int) { func (*CommunityRequestToLeave) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{11} return fileDescriptor_f937943d74c1cd8b, []int{13}
} }
func (m *CommunityRequestToLeave) XXX_Unmarshal(b []byte) error { func (m *CommunityRequestToLeave) XXX_Unmarshal(b []byte) error {
@ -883,7 +1077,7 @@ func (m *CommunityMessageArchiveMagnetlink) Reset() { *m = CommunityMess
func (m *CommunityMessageArchiveMagnetlink) String() string { return proto.CompactTextString(m) } func (m *CommunityMessageArchiveMagnetlink) String() string { return proto.CompactTextString(m) }
func (*CommunityMessageArchiveMagnetlink) ProtoMessage() {} func (*CommunityMessageArchiveMagnetlink) ProtoMessage() {}
func (*CommunityMessageArchiveMagnetlink) Descriptor() ([]byte, []int) { func (*CommunityMessageArchiveMagnetlink) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{12} return fileDescriptor_f937943d74c1cd8b, []int{14}
} }
func (m *CommunityMessageArchiveMagnetlink) XXX_Unmarshal(b []byte) error { func (m *CommunityMessageArchiveMagnetlink) XXX_Unmarshal(b []byte) error {
@ -935,7 +1129,7 @@ func (m *WakuMessage) Reset() { *m = WakuMessage{} }
func (m *WakuMessage) String() string { return proto.CompactTextString(m) } func (m *WakuMessage) String() string { return proto.CompactTextString(m) }
func (*WakuMessage) ProtoMessage() {} func (*WakuMessage) ProtoMessage() {}
func (*WakuMessage) Descriptor() ([]byte, []int) { func (*WakuMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{13} return fileDescriptor_f937943d74c1cd8b, []int{15}
} }
func (m *WakuMessage) XXX_Unmarshal(b []byte) error { func (m *WakuMessage) XXX_Unmarshal(b []byte) error {
@ -1019,7 +1213,7 @@ func (m *WakuMessageArchiveMetadata) Reset() { *m = WakuMessageArchiveMe
func (m *WakuMessageArchiveMetadata) String() string { return proto.CompactTextString(m) } func (m *WakuMessageArchiveMetadata) String() string { return proto.CompactTextString(m) }
func (*WakuMessageArchiveMetadata) ProtoMessage() {} func (*WakuMessageArchiveMetadata) ProtoMessage() {}
func (*WakuMessageArchiveMetadata) Descriptor() ([]byte, []int) { func (*WakuMessageArchiveMetadata) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{14} return fileDescriptor_f937943d74c1cd8b, []int{16}
} }
func (m *WakuMessageArchiveMetadata) XXX_Unmarshal(b []byte) error { func (m *WakuMessageArchiveMetadata) XXX_Unmarshal(b []byte) error {
@ -1081,7 +1275,7 @@ func (m *WakuMessageArchive) Reset() { *m = WakuMessageArchive{} }
func (m *WakuMessageArchive) String() string { return proto.CompactTextString(m) } func (m *WakuMessageArchive) String() string { return proto.CompactTextString(m) }
func (*WakuMessageArchive) ProtoMessage() {} func (*WakuMessageArchive) ProtoMessage() {}
func (*WakuMessageArchive) Descriptor() ([]byte, []int) { func (*WakuMessageArchive) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{15} return fileDescriptor_f937943d74c1cd8b, []int{17}
} }
func (m *WakuMessageArchive) XXX_Unmarshal(b []byte) error { func (m *WakuMessageArchive) XXX_Unmarshal(b []byte) error {
@ -1138,7 +1332,7 @@ func (m *WakuMessageArchiveIndexMetadata) Reset() { *m = WakuMessageArch
func (m *WakuMessageArchiveIndexMetadata) String() string { return proto.CompactTextString(m) } func (m *WakuMessageArchiveIndexMetadata) String() string { return proto.CompactTextString(m) }
func (*WakuMessageArchiveIndexMetadata) ProtoMessage() {} func (*WakuMessageArchiveIndexMetadata) ProtoMessage() {}
func (*WakuMessageArchiveIndexMetadata) Descriptor() ([]byte, []int) { func (*WakuMessageArchiveIndexMetadata) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{16} return fileDescriptor_f937943d74c1cd8b, []int{18}
} }
func (m *WakuMessageArchiveIndexMetadata) XXX_Unmarshal(b []byte) error { func (m *WakuMessageArchiveIndexMetadata) XXX_Unmarshal(b []byte) error {
@ -1205,7 +1399,7 @@ func (m *WakuMessageArchiveIndex) Reset() { *m = WakuMessageArchiveIndex
func (m *WakuMessageArchiveIndex) String() string { return proto.CompactTextString(m) } func (m *WakuMessageArchiveIndex) String() string { return proto.CompactTextString(m) }
func (*WakuMessageArchiveIndex) ProtoMessage() {} func (*WakuMessageArchiveIndex) ProtoMessage() {}
func (*WakuMessageArchiveIndex) Descriptor() ([]byte, []int) { func (*WakuMessageArchiveIndex) Descriptor() ([]byte, []int) {
return fileDescriptor_f937943d74c1cd8b, []int{17} return fileDescriptor_f937943d74c1cd8b, []int{19}
} }
func (m *WakuMessageArchiveIndex) XXX_Unmarshal(b []byte) error { func (m *WakuMessageArchiveIndex) XXX_Unmarshal(b []byte) error {
@ -1236,13 +1430,18 @@ func (m *WakuMessageArchiveIndex) GetArchives() map[string]*WakuMessageArchiveIn
func init() { func init() {
proto.RegisterEnum("protobuf.CommunityMember_Roles", CommunityMember_Roles_name, CommunityMember_Roles_value) proto.RegisterEnum("protobuf.CommunityMember_Roles", CommunityMember_Roles_name, CommunityMember_Roles_value)
proto.RegisterEnum("protobuf.CommunityPermissions_Access", CommunityPermissions_Access_name, CommunityPermissions_Access_value) proto.RegisterEnum("protobuf.CommunityPermissions_Access", CommunityPermissions_Access_name, CommunityPermissions_Access_value)
proto.RegisterEnum("protobuf.CommunityTokenPermission_Type", CommunityTokenPermission_Type_name, CommunityTokenPermission_Type_value)
proto.RegisterType((*Grant)(nil), "protobuf.Grant") proto.RegisterType((*Grant)(nil), "protobuf.Grant")
proto.RegisterType((*CommunityMember)(nil), "protobuf.CommunityMember") proto.RegisterType((*CommunityMember)(nil), "protobuf.CommunityMember")
proto.RegisterType((*CommunityPermissions)(nil), "protobuf.CommunityPermissions") proto.RegisterType((*CommunityPermissions)(nil), "protobuf.CommunityPermissions")
proto.RegisterType((*TokenCriteria)(nil), "protobuf.TokenCriteria")
proto.RegisterMapType((map[uint64]string)(nil), "protobuf.TokenCriteria.ContractAddressesEntry")
proto.RegisterType((*CommunityTokenPermission)(nil), "protobuf.CommunityTokenPermission")
proto.RegisterType((*CommunityDescription)(nil), "protobuf.CommunityDescription") proto.RegisterType((*CommunityDescription)(nil), "protobuf.CommunityDescription")
proto.RegisterMapType((map[string]*CommunityCategory)(nil), "protobuf.CommunityDescription.CategoriesEntry") proto.RegisterMapType((map[string]*CommunityCategory)(nil), "protobuf.CommunityDescription.CategoriesEntry")
proto.RegisterMapType((map[string]*CommunityChat)(nil), "protobuf.CommunityDescription.ChatsEntry") proto.RegisterMapType((map[string]*CommunityChat)(nil), "protobuf.CommunityDescription.ChatsEntry")
proto.RegisterMapType((map[string]*CommunityMember)(nil), "protobuf.CommunityDescription.MembersEntry") proto.RegisterMapType((map[string]*CommunityMember)(nil), "protobuf.CommunityDescription.MembersEntry")
proto.RegisterMapType((map[string]*CommunityTokenPermission)(nil), "protobuf.CommunityDescription.TokenPermissionsEntry")
proto.RegisterType((*CommunityAdminSettings)(nil), "protobuf.CommunityAdminSettings") proto.RegisterType((*CommunityAdminSettings)(nil), "protobuf.CommunityAdminSettings")
proto.RegisterType((*CommunityChat)(nil), "protobuf.CommunityChat") proto.RegisterType((*CommunityChat)(nil), "protobuf.CommunityChat")
proto.RegisterMapType((map[string]*CommunityMember)(nil), "protobuf.CommunityChat.MembersEntry") proto.RegisterMapType((map[string]*CommunityMember)(nil), "protobuf.CommunityChat.MembersEntry")
@ -1266,94 +1465,114 @@ func init() {
} }
var fileDescriptor_f937943d74c1cd8b = []byte{ var fileDescriptor_f937943d74c1cd8b = []byte{
// 1411 bytes of a gzipped FileDescriptorProto // 1730 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcd, 0x6f, 0x1b, 0x45, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcd, 0x6f, 0x23, 0x49,
0x14, 0xef, 0xfa, 0x23, 0xb6, 0x9f, 0xed, 0xd4, 0x99, 0x36, 0xc9, 0x36, 0xfd, 0x88, 0xbb, 0x80, 0x15, 0x9f, 0xf6, 0x47, 0x62, 0x3f, 0x7f, 0x8c, 0x53, 0x33, 0x49, 0x7a, 0x32, 0x33, 0x9b, 0x4c,
0x94, 0x0a, 0xe1, 0xaa, 0xa9, 0x90, 0x2a, 0xbe, 0x5a, 0x37, 0xb5, 0x8a, 0x69, 0x62, 0xb7, 0x13, 0x03, 0x22, 0x2b, 0x84, 0x87, 0xf5, 0x82, 0x34, 0x62, 0x61, 0x77, 0x3d, 0x89, 0x35, 0x98, 0x89,
0x87, 0xd2, 0x1e, 0x58, 0x4d, 0x76, 0x27, 0xce, 0x28, 0xeb, 0x59, 0xb3, 0x33, 0x8e, 0x30, 0x07, 0xed, 0x6c, 0xd9, 0x61, 0xd9, 0x95, 0xa0, 0x55, 0xe9, 0xae, 0x38, 0xa5, 0xb4, 0xbb, 0x4d, 0x57,
0xfe, 0x0e, 0xc4, 0x95, 0x0b, 0x27, 0xfe, 0x05, 0x0e, 0xdc, 0xb9, 0x73, 0xe3, 0xc8, 0x9f, 0x81, 0x39, 0xc2, 0x1c, 0xf8, 0x3b, 0xb8, 0x73, 0xe1, 0x80, 0xf8, 0x17, 0x38, 0x70, 0xe7, 0xce, 0x8d,
0x66, 0xf6, 0xc3, 0xeb, 0xaf, 0xb4, 0x52, 0x85, 0xc4, 0xc9, 0xf3, 0xde, 0xbe, 0xf7, 0x7b, 0xdf, 0x13, 0xda, 0x3f, 0x03, 0xd5, 0x47, 0xb7, 0xdb, 0x8e, 0x3d, 0x19, 0x69, 0x85, 0xc4, 0xc9, 0xf5,
0xf3, 0xc6, 0xb0, 0xe6, 0xf8, 0x83, 0xc1, 0x88, 0x33, 0xc9, 0xa8, 0x68, 0x0c, 0x03, 0x5f, 0xfa, 0x5e, 0xbf, 0xef, 0xfa, 0xd5, 0xab, 0x57, 0x86, 0x1d, 0x2f, 0x9a, 0x4c, 0x66, 0x21, 0x13, 0x8c,
0xa8, 0xa8, 0x7f, 0x8e, 0x47, 0x27, 0x5b, 0x57, 0x9c, 0x53, 0x22, 0x6d, 0xe6, 0x52, 0x2e, 0x99, 0xf2, 0xe6, 0x34, 0x8e, 0x44, 0x84, 0x4a, 0xea, 0xe7, 0x72, 0x76, 0x75, 0xf0, 0xc8, 0xbb, 0x26,
0x1c, 0x87, 0x9f, 0xb7, 0xca, 0x94, 0x8f, 0x06, 0x91, 0xac, 0x75, 0x0e, 0xf9, 0xa7, 0x01, 0xe1, 0xc2, 0x65, 0x3e, 0x0d, 0x05, 0x13, 0x73, 0xfd, 0xf9, 0xa0, 0x42, 0xc3, 0xd9, 0xc4, 0xc8, 0x3a,
0x12, 0xdd, 0x86, 0x4a, 0x8c, 0x34, 0xb6, 0x99, 0x6b, 0x1a, 0x75, 0x63, 0xa7, 0x82, 0xcb, 0x09, 0xb7, 0x50, 0x7c, 0x13, 0x93, 0x50, 0xa0, 0x17, 0x50, 0x4d, 0x2c, 0xcd, 0x5d, 0xe6, 0xdb, 0xd6,
0xaf, 0xed, 0xa2, 0xeb, 0x50, 0x1a, 0xd0, 0xc1, 0x31, 0x0d, 0xd4, 0xf7, 0x8c, 0xfe, 0x5e, 0x0c, 0x91, 0x75, 0x5c, 0xc5, 0x95, 0x94, 0xd7, 0xf5, 0xd1, 0x53, 0x28, 0x4f, 0xe8, 0xe4, 0x92, 0xc6,
0x19, 0x6d, 0x17, 0x6d, 0x42, 0x21, 0x32, 0x66, 0x66, 0xeb, 0xc6, 0x4e, 0x09, 0xaf, 0x28, 0xb2, 0xf2, 0x7b, 0x4e, 0x7d, 0x2f, 0x69, 0x46, 0xd7, 0x47, 0xfb, 0xb0, 0x6d, 0x9c, 0xd9, 0xf9, 0x23,
0xed, 0xa2, 0xab, 0x90, 0x77, 0x3c, 0xdf, 0x39, 0x33, 0x73, 0x75, 0x63, 0x27, 0x87, 0x43, 0xc2, 0xeb, 0xb8, 0x8c, 0xb7, 0x24, 0xd9, 0xf5, 0xd1, 0x63, 0x28, 0x7a, 0x41, 0xe4, 0xdd, 0xd8, 0x85,
0xfa, 0xc5, 0x80, 0xcb, 0x7b, 0x31, 0xf6, 0x81, 0x06, 0x41, 0x1f, 0x43, 0x3e, 0xf0, 0x3d, 0x2a, 0x23, 0xeb, 0xb8, 0x80, 0x35, 0xe1, 0xfc, 0xd9, 0x82, 0x87, 0x27, 0x89, 0xed, 0x9e, 0x32, 0x82,
0x4c, 0xa3, 0x9e, 0xdd, 0x59, 0xdd, 0xdd, 0x6e, 0xc4, 0x71, 0x34, 0x66, 0x24, 0x1b, 0x58, 0x89, 0x7e, 0x02, 0xc5, 0x38, 0x0a, 0x28, 0xb7, 0xad, 0xa3, 0xfc, 0x71, 0xbd, 0x75, 0xd8, 0x4c, 0xf2,
0xe1, 0x50, 0xda, 0x7a, 0x05, 0x79, 0x4d, 0xa3, 0x1a, 0x54, 0x8e, 0x3a, 0xcf, 0x3a, 0xdd, 0x97, 0x68, 0xae, 0x48, 0x36, 0xb1, 0x14, 0xc3, 0x5a, 0xda, 0xf9, 0x0a, 0x8a, 0x8a, 0x46, 0x0d, 0xa8,
0x1d, 0x1b, 0x77, 0xf7, 0x5b, 0xb5, 0x4b, 0xa8, 0x02, 0x45, 0x75, 0xb2, 0x9b, 0xfb, 0xfb, 0x35, 0x5e, 0xf4, 0xdf, 0xf6, 0x07, 0x5f, 0xf6, 0x5d, 0x3c, 0x38, 0xeb, 0x34, 0x1e, 0xa0, 0x2a, 0x94,
0x03, 0xad, 0xc3, 0x9a, 0xa6, 0x0e, 0x9a, 0x9d, 0xe6, 0xd3, 0x96, 0x7d, 0x74, 0xd8, 0xc2, 0x87, 0xe4, 0xca, 0x6d, 0x9f, 0x9d, 0x35, 0x2c, 0xb4, 0x0b, 0x3b, 0x8a, 0xea, 0xb5, 0xfb, 0xed, 0x37,
0xb5, 0x0c, 0xba, 0x06, 0xeb, 0x21, 0xbb, 0xfb, 0xa4, 0x85, 0x9b, 0xbd, 0x96, 0xbd, 0xd7, 0xed, 0x1d, 0xf7, 0x62, 0xd8, 0xc1, 0xc3, 0x46, 0x0e, 0x3d, 0x81, 0x5d, 0xcd, 0x1e, 0x9c, 0x76, 0x70,
0xf4, 0x5a, 0x9d, 0x5e, 0x2d, 0x6b, 0xfd, 0x6d, 0xc0, 0xd5, 0xc4, 0xf6, 0x73, 0x1a, 0x0c, 0x98, 0x7b, 0xd4, 0x71, 0x4f, 0x06, 0xfd, 0x51, 0xa7, 0x3f, 0x6a, 0xe4, 0x9d, 0x7f, 0x5b, 0xf0, 0x38,
0x10, 0xcc, 0xe7, 0x02, 0x5d, 0x83, 0x22, 0xe5, 0xc2, 0xf6, 0xb9, 0x37, 0xd6, 0x99, 0x2a, 0xe2, 0xf5, 0x7d, 0x4e, 0xe3, 0x09, 0xe3, 0x9c, 0x45, 0x21, 0x47, 0x4f, 0xa0, 0x44, 0x43, 0xee, 0x46,
0x02, 0xe5, 0xa2, 0xcb, 0xbd, 0x31, 0x32, 0xa1, 0x30, 0x0c, 0xd8, 0x39, 0x91, 0x54, 0xe7, 0xa8, 0x61, 0x30, 0x57, 0x95, 0x2a, 0xe1, 0x6d, 0x1a, 0xf2, 0x41, 0x18, 0xcc, 0x91, 0x0d, 0xdb, 0xd3,
0x88, 0x63, 0x12, 0x7d, 0x0e, 0x2b, 0xc4, 0x71, 0xa8, 0x10, 0x3a, 0x43, 0xab, 0xbb, 0x1f, 0x2c, 0x98, 0xdd, 0x12, 0x41, 0x55, 0x8d, 0x4a, 0x38, 0x21, 0xd1, 0xcf, 0x61, 0x8b, 0x78, 0x1e, 0xe5,
0x08, 0x30, 0x65, 0xa4, 0xd1, 0xd4, 0xc2, 0x38, 0x52, 0xb2, 0x7a, 0xb0, 0x12, 0x72, 0x10, 0x82, 0x5c, 0x55, 0xa8, 0xde, 0xfa, 0xde, 0x9a, 0x04, 0x33, 0x4e, 0x9a, 0x6d, 0x25, 0x8c, 0x8d, 0x92,
0xd5, 0x38, 0xd0, 0xe6, 0xde, 0x5e, 0xeb, 0xf0, 0xb0, 0x76, 0x09, 0xad, 0x41, 0xb5, 0xd3, 0xb5, 0x33, 0x82, 0x2d, 0xcd, 0x41, 0x08, 0xea, 0x49, 0xa2, 0xed, 0x93, 0x93, 0xce, 0x70, 0xd8, 0x78,
0x0f, 0x5a, 0x07, 0x8f, 0x5b, 0xf8, 0xf0, 0xcb, 0xf6, 0xf3, 0x9a, 0x81, 0xae, 0xc0, 0xe5, 0x76, 0x80, 0x76, 0xa0, 0xd6, 0x1f, 0xb8, 0xbd, 0x4e, 0xef, 0x75, 0x07, 0x0f, 0x7f, 0xd1, 0x3d, 0x6f,
0xe7, 0xeb, 0x76, 0xaf, 0xd9, 0x6b, 0x77, 0x3b, 0x76, 0xb7, 0xb3, 0xff, 0xaa, 0x96, 0x41, 0xab, 0x58, 0xe8, 0x11, 0x3c, 0xec, 0xf6, 0x7f, 0xd5, 0x1d, 0xb5, 0x47, 0xdd, 0x41, 0xdf, 0x1d, 0xf4,
0x00, 0xdd, 0x8e, 0x8d, 0x5b, 0x2f, 0x8e, 0x5a, 0x87, 0x2a, 0xc4, 0x9f, 0x0b, 0xa9, 0x10, 0x9f, 0xcf, 0xbe, 0x6a, 0xe4, 0x50, 0x1d, 0x60, 0xd0, 0x77, 0x71, 0xe7, 0x8b, 0x8b, 0xce, 0x50, 0xa6,
0x50, 0xe1, 0x04, 0x6c, 0x28, 0x99, 0xcf, 0x27, 0x75, 0x33, 0x52, 0x75, 0x43, 0x2d, 0x28, 0x84, 0xf8, 0x4d, 0x0e, 0x6a, 0xa3, 0xe8, 0x86, 0x86, 0x27, 0x31, 0x13, 0x34, 0x66, 0x04, 0xfd, 0x06,
0x25, 0x17, 0x66, 0xa6, 0x9e, 0xdd, 0x29, 0xef, 0x7e, 0xb8, 0x20, 0x88, 0x14, 0x4c, 0x23, 0xac, 0x90, 0x17, 0x85, 0x22, 0x26, 0x9e, 0x70, 0x89, 0xef, 0xc7, 0x94, 0x73, 0xb3, 0x27, 0x95, 0x56,
0x98, 0x68, 0x71, 0x19, 0x8c, 0x71, 0xac, 0x8b, 0x1e, 0x41, 0x79, 0x38, 0x89, 0x54, 0xe7, 0xa3, 0x73, 0x11, 0xf2, 0x92, 0x52, 0xf3, 0xc4, 0x68, 0xb4, 0x13, 0x85, 0x4e, 0x28, 0xe2, 0x39, 0xde,
0xbc, 0x7b, 0xeb, 0xe2, 0x7c, 0xe0, 0xb4, 0x0a, 0xda, 0x85, 0x62, 0xdc, 0xd7, 0x66, 0x5e, 0xab, 0xf1, 0x56, 0xf9, 0xe8, 0x47, 0x50, 0x10, 0xf3, 0xa9, 0x2e, 0x4e, 0xbd, 0xf5, 0x6c, 0x4d, 0x0d,
0x6f, 0xa4, 0xd4, 0x75, 0xeb, 0x85, 0x5f, 0x71, 0x22, 0x87, 0x1e, 0x42, 0x5e, 0x35, 0xa5, 0x30, 0x94, 0xe5, 0xd1, 0x7c, 0x4a, 0xb1, 0x92, 0x44, 0x7b, 0xb0, 0xc5, 0xe7, 0x93, 0xcb, 0x28, 0x48,
0x57, 0xb4, 0xeb, 0x77, 0xde, 0xe0, 0xba, 0x42, 0x89, 0x1c, 0x0f, 0xf5, 0x54, 0xd9, 0x8f, 0x09, 0x90, 0xa5, 0x29, 0x84, 0xa0, 0x10, 0x92, 0x09, 0x55, 0xc0, 0x2a, 0x63, 0xb5, 0x96, 0xb2, 0x64,
0xb7, 0x3d, 0x26, 0xa4, 0x59, 0xa8, 0x67, 0x77, 0x4a, 0xb8, 0x70, 0x4c, 0xf8, 0x3e, 0x13, 0x12, 0x12, 0xcd, 0x42, 0x61, 0x17, 0xb5, 0xac, 0xa6, 0x24, 0x76, 0x85, 0x34, 0xeb, 0x32, 0x9f, 0xdb,
0x75, 0x00, 0x1c, 0x22, 0x69, 0xdf, 0x0f, 0x18, 0x15, 0x66, 0x51, 0x1b, 0x68, 0xbc, 0xc9, 0x40, 0x5b, 0x47, 0xf9, 0xe3, 0x02, 0x2e, 0x29, 0x46, 0xd7, 0xe7, 0xe8, 0x10, 0x2a, 0x72, 0x37, 0xa7,
0xa2, 0x10, 0x5a, 0x49, 0x21, 0xa0, 0x07, 0x60, 0x92, 0xc0, 0x39, 0x65, 0xe7, 0xd4, 0x1e, 0x90, 0x44, 0x08, 0x1a, 0x87, 0xf6, 0xb6, 0xd2, 0x04, 0x1a, 0xf2, 0x73, 0xcd, 0x39, 0x38, 0x85, 0xbd,
0x3e, 0xa7, 0xd2, 0x63, 0xfc, 0xcc, 0x0e, 0x2b, 0x52, 0xd2, 0x15, 0xd9, 0x88, 0xbe, 0x1f, 0x24, 0xf5, 0x09, 0xa2, 0x06, 0xe4, 0x6f, 0xa8, 0xc6, 0x40, 0x01, 0xcb, 0xa5, 0xc4, 0xfb, 0x2d, 0x09,
0x9f, 0xf7, 0x74, 0x89, 0x9e, 0xc2, 0x2a, 0x71, 0x07, 0x8c, 0xdb, 0x82, 0x4a, 0xc9, 0x78, 0x5f, 0x66, 0x3a, 0xc1, 0x32, 0xd6, 0xc4, 0x4f, 0x73, 0xaf, 0x2c, 0xe7, 0xaf, 0x39, 0xb0, 0x97, 0x93,
0x98, 0xa0, 0xf3, 0x53, 0x5f, 0xe0, 0x4d, 0x53, 0x09, 0x1e, 0x46, 0x72, 0xb8, 0x4a, 0xd2, 0x24, 0x5c, 0xec, 0x36, 0xaa, 0x43, 0xce, 0x9c, 0xba, 0x32, 0xce, 0x31, 0x1f, 0x7d, 0xb2, 0x54, 0xa6,
0x7a, 0x0f, 0xaa, 0x8c, 0xcb, 0xc0, 0xb7, 0x07, 0x54, 0x08, 0xd2, 0xa7, 0x66, 0x59, 0x0f, 0x76, 0xef, 0x6f, 0x2a, 0xd3, 0xc2, 0x42, 0x33, 0x53, 0xb1, 0x4f, 0xa1, 0xae, 0xb3, 0xf5, 0xcc, 0xfe,
0x45, 0x33, 0x0f, 0x42, 0x9e, 0x12, 0xf2, 0x47, 0x69, 0xa1, 0x4a, 0x28, 0xa4, 0x99, 0xb1, 0xd0, 0xd8, 0x79, 0xb5, 0x7d, 0xfb, 0x1b, 0xb6, 0x0f, 0xd7, 0xc4, 0x12, 0x04, 0x9e, 0x40, 0xc9, 0x1c,
0x0d, 0x28, 0x51, 0xee, 0x04, 0xe3, 0xa1, 0xa4, 0xae, 0x59, 0xd5, 0x53, 0x31, 0x61, 0x20, 0x04, 0x66, 0x6e, 0x17, 0x8e, 0xf2, 0xc7, 0x65, 0xbc, 0xad, 0x4f, 0x33, 0x47, 0xcf, 0x01, 0x18, 0x77,
0x39, 0x49, 0xfa, 0xc2, 0x5c, 0xd5, 0x19, 0xd5, 0xe7, 0xad, 0x23, 0xa8, 0xa4, 0x3b, 0x07, 0xd5, 0x13, 0x84, 0x17, 0x15, 0xc2, 0xcb, 0x8c, 0x9f, 0x6b, 0x86, 0xd3, 0x85, 0x82, 0x8c, 0x03, 0x3d,
0x20, 0x7b, 0x46, 0xc3, 0x59, 0x2b, 0x61, 0x75, 0x44, 0x77, 0x21, 0x7f, 0x4e, 0xbc, 0x51, 0x38, 0x03, 0x3b, 0x81, 0xe8, 0x68, 0xf0, 0xb6, 0xd3, 0x77, 0xcf, 0x3b, 0xb8, 0xd7, 0x1d, 0x0e, 0xbb,
0x65, 0xe5, 0xdd, 0x6b, 0x4b, 0x6f, 0x0b, 0x1c, 0xca, 0x7d, 0x92, 0x79, 0x60, 0x6c, 0xbd, 0x00, 0x83, 0x7e, 0xe3, 0x81, 0x3c, 0xa9, 0xaf, 0x3b, 0x27, 0x83, 0x5e, 0xc7, 0x6d, 0x9f, 0xf6, 0xba,
0x98, 0x54, 0x75, 0x01, 0xe8, 0x47, 0xd3, 0xa0, 0x9b, 0x0b, 0x40, 0x95, 0x7e, 0x1a, 0xf2, 0x35, 0xfd, 0x86, 0x25, 0xe1, 0x6b, 0x38, 0x1a, 0xc2, 0x8d, 0x9c, 0xf3, 0x9f, 0x52, 0xe6, 0xf0, 0x9d,
0x5c, 0x9e, 0xa9, 0xe3, 0x02, 0xdc, 0x7b, 0xd3, 0xb8, 0xd7, 0x17, 0xe1, 0x86, 0x20, 0xe3, 0x14, 0x52, 0xee, 0xc5, 0x6c, 0x2a, 0x64, 0xa9, 0xd2, 0x8e, 0x62, 0x65, 0x3a, 0x0a, 0xea, 0xc0, 0xb6,
0xb6, 0xf5, 0x2d, 0x6c, 0x2c, 0x2e, 0x15, 0x7a, 0x02, 0xdb, 0x43, 0xc6, 0xe3, 0xa4, 0xdb, 0xc4, 0x6e, 0x46, 0xdc, 0xce, 0xa9, 0x64, 0x7f, 0xb0, 0xa6, 0x66, 0x19, 0x33, 0x4d, 0xdd, 0x4b, 0x0c,
0xf3, 0xec, 0x68, 0xb6, 0x6c, 0xca, 0xc9, 0xb1, 0x47, 0xdd, 0xe8, 0x5e, 0xba, 0x3e, 0x64, 0x3c, 0x50, 0x13, 0x5d, 0xf4, 0x39, 0x54, 0xa6, 0x8b, 0x33, 0xa8, 0x10, 0x57, 0x69, 0x7d, 0xf0, 0xee,
0x2a, 0x43, 0xd3, 0xf3, 0x92, 0x9c, 0x6a, 0x11, 0xeb, 0xaf, 0x0c, 0x54, 0xa7, 0x02, 0x43, 0x5f, 0x93, 0x8a, 0xb3, 0x2a, 0xa8, 0x05, 0xa5, 0xa4, 0xe3, 0xaa, 0xfa, 0x54, 0x5a, 0x7b, 0x19, 0x75,
0x4c, 0xe6, 0xdb, 0xd0, 0x3d, 0xfc, 0xfe, 0x92, 0x14, 0xbc, 0xdd, 0x60, 0x67, 0xde, 0x6d, 0xb0, 0x55, 0x46, 0xfd, 0x15, 0xa7, 0x72, 0xe8, 0x33, 0x28, 0xca, 0x02, 0x6b, 0x68, 0x56, 0x5a, 0x1f,
0xb3, 0x6f, 0x39, 0xd8, 0xdb, 0x50, 0x8e, 0x46, 0x47, 0xef, 0xae, 0x9c, 0x4e, 0x7c, 0x3c, 0x4d, 0xde, 0x13, 0xba, 0xb4, 0x62, 0x02, 0xd7, 0x7a, 0x72, 0xc7, 0x2e, 0x49, 0xe8, 0x06, 0x8c, 0x0b,
0x6a, 0x75, 0x6d, 0x41, 0x71, 0xe8, 0x0b, 0xa6, 0xa6, 0x4e, 0xdf, 0x16, 0x79, 0x9c, 0xd0, 0xff, 0x7b, 0x5b, 0xef, 0xd8, 0x25, 0x09, 0xcf, 0x18, 0x17, 0xa8, 0x0f, 0xe0, 0x11, 0x41, 0xc7, 0x51,
0x51, 0xab, 0x59, 0x2e, 0xac, 0xcd, 0xd5, 0x76, 0xd6, 0x51, 0x63, 0xce, 0x51, 0x04, 0x39, 0x4e, 0xcc, 0x28, 0xb7, 0x4b, 0xab, 0xe7, 0x78, 0xbd, 0x83, 0x54, 0x41, 0x7b, 0xc9, 0x58, 0x40, 0xaf,
0x06, 0xa1, 0xa5, 0x12, 0xd6, 0xe7, 0x29, 0xe7, 0xb3, 0xd3, 0xce, 0x5b, 0x3f, 0x19, 0x70, 0x25, 0xc0, 0x26, 0xb1, 0x77, 0xcd, 0x6e, 0xa9, 0x3b, 0x21, 0xe3, 0x90, 0x8a, 0x80, 0x85, 0x37, 0xae,
0x31, 0xd3, 0xe6, 0xe7, 0x4c, 0x12, 0x7d, 0x7b, 0xdf, 0x87, 0xf5, 0xc9, 0x3a, 0x77, 0x27, 0x77, 0xde, 0x91, 0xb2, 0xda, 0x91, 0x3d, 0xf3, 0xbd, 0x97, 0x7e, 0x3e, 0x51, 0x5b, 0xf4, 0x06, 0xea,
0x4e, 0xb4, 0xd7, 0xaf, 0x3a, 0x4b, 0xae, 0xfc, 0xbe, 0x7a, 0x0c, 0x44, 0xcb, 0x3d, 0x24, 0x96, 0xc4, 0x9f, 0xb0, 0xd0, 0xe5, 0x54, 0x08, 0x16, 0x8e, 0xb9, 0x0d, 0xaa, 0x3e, 0x47, 0x6b, 0xa2,
0x6f, 0xf6, 0x9b, 0x00, 0xc3, 0xd1, 0xb1, 0xc7, 0x1c, 0x5b, 0xe5, 0x2b, 0xa7, 0x75, 0x4a, 0x21, 0x69, 0x4b, 0xc1, 0xa1, 0x91, 0xc3, 0x35, 0x92, 0x25, 0xd1, 0x77, 0xa0, 0xc6, 0x42, 0x11, 0x47,
0xe7, 0x19, 0x1d, 0x5b, 0xbf, 0x1a, 0xa9, 0xee, 0xc5, 0xf4, 0xbb, 0x11, 0x15, 0xb2, 0xe7, 0x7f, 0xee, 0x84, 0x72, 0x4e, 0xc6, 0xd4, 0xae, 0xa8, 0x73, 0x53, 0x55, 0xcc, 0x9e, 0xe6, 0x49, 0xa1,
0xe5, 0xb3, 0x65, 0xbb, 0x25, 0x5a, 0xaa, 0xa9, 0xf8, 0xd5, 0x52, 0xed, 0xa8, 0x14, 0x2c, 0xf5, 0x68, 0x96, 0x15, 0xaa, 0x6a, 0x21, 0xc5, 0x4c, 0x84, 0x9e, 0x41, 0x99, 0x86, 0x5e, 0x3c, 0x9f,
0x61, 0xf6, 0xd9, 0x92, 0x9b, 0x7f, 0xb6, 0xdc, 0x86, 0x8a, 0xcb, 0xc4, 0xd0, 0x23, 0xe3, 0x10, 0x0a, 0xea, 0xdb, 0x35, 0x8d, 0xe6, 0x94, 0x21, 0x3b, 0x8c, 0x20, 0x63, 0x6e, 0xd7, 0x55, 0x45,
0x3a, 0xaf, 0x01, 0xca, 0x11, 0x4f, 0xc1, 0x5b, 0xbf, 0x19, 0x70, 0x23, 0x55, 0x2c, 0xee, 0x50, 0xd5, 0x1a, 0x11, 0xd8, 0xd1, 0x67, 0x2b, 0x0b, 0x93, 0x87, 0xaa, 0xaa, 0x3f, 0xbe, 0xa7, 0xaa,
0xef, 0xff, 0xed, 0xf0, 0x3f, 0x06, 0xdc, 0x5a, 0x9c, 0x5b, 0x4c, 0xc5, 0xd0, 0xe7, 0x82, 0x2e, 0x2b, 0x27, 0xd6, 0xd4, 0xb6, 0x21, 0x56, 0xd8, 0x07, 0x17, 0x50, 0xcd, 0x82, 0x33, 0xdb, 0x64,
0x71, 0xf9, 0x33, 0x28, 0x25, 0xa6, 0x2e, 0x98, 0xce, 0x54, 0x57, 0xe0, 0x89, 0x82, 0xea, 0x44, 0xca, 0xba, 0xc9, 0xbc, 0xcc, 0x36, 0x99, 0x4a, 0xeb, 0xc9, 0xc6, 0xab, 0x32, 0xd3, 0x7f, 0x0e,
0xf5, 0x18, 0xd1, 0xd7, 0x78, 0x56, 0x5f, 0x2f, 0x09, 0x3d, 0x69, 0x9e, 0x5c, 0xba, 0x79, 0x66, 0xbe, 0x00, 0x58, 0x00, 0x67, 0x8d, 0xd1, 0x1f, 0x2e, 0x1b, 0xdd, 0x5f, 0x63, 0x54, 0xea, 0x67,
0xc3, 0xcd, 0xcf, 0x87, 0x7b, 0x13, 0x20, 0xdc, 0x70, 0xf6, 0x28, 0x60, 0xe6, 0x8a, 0x0e, 0xb6, 0x4d, 0x7e, 0x0d, 0x0f, 0x57, 0xa0, 0xb2, 0xc6, 0xee, 0x47, 0xcb, 0x76, 0x9f, 0xae, 0xb3, 0xab,
0x14, 0x72, 0x8e, 0x02, 0x66, 0x61, 0xd8, 0x9c, 0x8f, 0x74, 0x9f, 0x92, 0xf3, 0x65, 0x21, 0xce, 0x8d, 0xcc, 0xb3, 0xb6, 0xc7, 0xb0, 0xbb, 0xb6, 0x60, 0x6b, 0x3c, 0xbc, 0x5a, 0xf6, 0xe0, 0xdc,
0x9a, 0xcc, 0xcc, 0x99, 0xb4, 0xbe, 0x81, 0xdb, 0xa9, 0xc9, 0x0d, 0x2f, 0xc7, 0xd9, 0x65, 0xba, 0xdf, 0x2d, 0xb3, 0x7d, 0xf9, 0xb7, 0xb2, 0xbb, 0xaf, 0x83, 0x1d, 0x3a, 0x85, 0xc3, 0x29, 0x0b,
0x04, 0x7d, 0xda, 0xdb, 0xcc, 0xac, 0xb7, 0xbf, 0x1b, 0x50, 0x7e, 0x49, 0xce, 0x46, 0xf1, 0xe6, 0x13, 0x00, 0xb9, 0x24, 0x08, 0x5c, 0xd3, 0x27, 0x5c, 0x1a, 0x92, 0xcb, 0x80, 0xfa, 0xe6, 0xf6,
0xab, 0x41, 0x56, 0xb0, 0x7e, 0x34, 0x75, 0xea, 0xa8, 0x76, 0xa1, 0x64, 0x03, 0x2a, 0x24, 0x19, 0x7f, 0x3a, 0x65, 0xa1, 0x81, 0x54, 0x3b, 0x08, 0xd2, 0xcd, 0x53, 0x22, 0xce, 0xbf, 0x72, 0x50,
0x0c, 0xb5, 0x7e, 0x0e, 0x4f, 0x18, 0xca, 0xa8, 0xf4, 0x87, 0xcc, 0xd1, 0xe9, 0xad, 0xe0, 0x90, 0x5b, 0xaa, 0x20, 0xfa, 0x74, 0xd1, 0xab, 0xf4, 0xbd, 0xfa, 0xdd, 0x0d, 0xb5, 0x7e, 0xbf, 0x26,
0xd0, 0x6f, 0x4a, 0x32, 0xf6, 0x7c, 0x12, 0xf7, 0x4b, 0x4c, 0x86, 0x5f, 0x5c, 0x97, 0xf1, 0x7e, 0x95, 0xfb, 0x76, 0x4d, 0x2a, 0xff, 0x9e, 0x4d, 0xea, 0x10, 0x2a, 0xa6, 0x0d, 0xa8, 0x09, 0x51,
0x94, 0xda, 0x98, 0x54, 0x37, 0xc9, 0x29, 0x11, 0xa7, 0x3a, 0xa1, 0x15, 0xac, 0xcf, 0xc8, 0x82, 0x5f, 0xbb, 0x49, 0x67, 0x90, 0x03, 0xe2, 0x01, 0x94, 0xa6, 0x11, 0x67, 0x12, 0xeb, 0xaa, 0xf3,
0x8a, 0x3c, 0x65, 0x81, 0xfb, 0x9c, 0x04, 0x2a, 0x0f, 0x66, 0x21, 0xdc, 0xd5, 0x69, 0x9e, 0xf5, 0x15, 0x71, 0x4a, 0xff, 0x8f, 0x30, 0xed, 0xf8, 0xb0, 0x73, 0x07, 0x44, 0xab, 0x81, 0x5a, 0x77,
0x23, 0x6c, 0xa5, 0x02, 0x88, 0xd3, 0x42, 0x25, 0x71, 0x89, 0x24, 0xca, 0xde, 0x39, 0x0d, 0x44, 0x02, 0x4d, 0x26, 0x87, 0x5c, 0x66, 0x72, 0xc8, 0x06, 0x9f, 0x5f, 0x0e, 0xde, 0xf9, 0x93, 0x05,
0x7c, 0x93, 0x54, 0x71, 0x4c, 0x2a, 0x7b, 0x27, 0x81, 0x3f, 0x88, 0x42, 0xd2, 0x67, 0xb4, 0x0a, 0x8f, 0x52, 0x37, 0xdd, 0xf0, 0x96, 0x09, 0xa2, 0x6e, 0xa2, 0x8f, 0x61, 0x77, 0x31, 0x34, 0xfb,
0x19, 0xe9, 0xeb, 0x50, 0x72, 0x38, 0x23, 0x7d, 0x65, 0xdf, 0xf1, 0xb9, 0xa4, 0x5c, 0xf6, 0x74, 0x8b, 0x93, 0x6e, 0xa6, 0xe7, 0xc7, 0xde, 0x86, 0xeb, 0x6b, 0x2c, 0x47, 0x6e, 0x33, 0x42, 0x6b,
0x90, 0xb9, 0x7a, 0x76, 0xa7, 0x82, 0xa7, 0x78, 0xea, 0x9f, 0x01, 0x9a, 0x77, 0xe0, 0x02, 0xc3, 0x62, 0xf3, 0xfc, 0xfc, 0x1c, 0x60, 0x3a, 0xbb, 0x0c, 0x98, 0xe7, 0xca, 0x7a, 0x15, 0x94, 0x4e,
0x8f, 0xa0, 0x38, 0x88, 0xdc, 0x8b, 0x3a, 0x3a, 0xb5, 0xb3, 0x96, 0x87, 0x82, 0x13, 0x2d, 0x74, 0x59, 0x73, 0xde, 0xd2, 0xb9, 0xf3, 0x17, 0x2b, 0x83, 0x5e, 0x4c, 0x7f, 0x37, 0xa3, 0x5c, 0x8c,
0x4f, 0x21, 0x68, 0x19, 0xf5, 0x14, 0x55, 0x5b, 0x6f, 0x7d, 0x21, 0x02, 0x4e, 0xc4, 0xac, 0x3f, 0xa2, 0x5f, 0x46, 0x6c, 0xd3, 0x3d, 0x69, 0x46, 0xd7, 0x4c, 0xfe, 0x72, 0x74, 0xed, 0xcb, 0x12,
0x0c, 0xd8, 0x9e, 0xc7, 0x6e, 0x73, 0x97, 0x7e, 0xff, 0x16, 0xb9, 0x7a, 0x77, 0x97, 0x37, 0x60, 0x6c, 0x8c, 0x61, 0xf5, 0x71, 0x50, 0xb8, 0xfb, 0x38, 0x78, 0x01, 0x55, 0x9f, 0xf1, 0x69, 0x40,
0xc5, 0x3f, 0x39, 0x11, 0x54, 0x46, 0xd9, 0x8d, 0x28, 0x55, 0x05, 0xc1, 0x7e, 0xa0, 0xd1, 0x9f, 0xe6, 0xda, 0xb4, 0x1e, 0xbf, 0x2a, 0x86, 0x27, 0xcd, 0x3b, 0x7f, 0xb3, 0xe0, 0x59, 0x66, 0xb3,
0x2d, 0x7d, 0x9e, 0xed, 0x91, 0x5c, 0xd2, 0x23, 0xd6, 0x9f, 0x06, 0x6c, 0x2e, 0x89, 0x02, 0x3d, 0x42, 0x8f, 0x06, 0xff, 0xdf, 0x01, 0x7f, 0x63, 0xc1, 0x07, 0xeb, 0x6b, 0x8b, 0x29, 0x9f, 0x46,
0x83, 0x62, 0xf4, 0xc0, 0x8c, 0x9f, 0x02, 0x77, 0x2f, 0xf2, 0x51, 0x2b, 0x35, 0x22, 0x22, 0x7a, 0x21, 0xa7, 0x1b, 0x42, 0xfe, 0x19, 0x94, 0x53, 0x57, 0xef, 0x38, 0x9d, 0x19, 0x54, 0xe0, 0x85,
0x15, 0x24, 0x00, 0x5b, 0x27, 0x50, 0x9d, 0xfa, 0xb4, 0x60, 0xc9, 0x3e, 0x9c, 0x5e, 0xb2, 0x77, 0x82, 0x44, 0xa2, 0x1c, 0xf9, 0xd5, 0x95, 0x94, 0x57, 0xed, 0x25, 0xa5, 0x17, 0xe0, 0x29, 0x64,
0xde, 0x68, 0x2c, 0xc9, 0xca, 0x64, 0xe9, 0x3e, 0xae, 0xbe, 0x2e, 0x37, 0xee, 0x7e, 0x1a, 0x6b, 0xc1, 0xb3, 0x9a, 0x6e, 0xf1, 0x6e, 0xba, 0xcf, 0x01, 0xf4, 0x6d, 0xed, 0xce, 0x62, 0x66, 0x6f,
0x1e, 0xaf, 0xe8, 0xd3, 0xfd, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x07, 0x30, 0x39, 0xf5, 0x25, 0xa9, 0x64, 0xcb, 0x9a, 0x73, 0x11, 0x33, 0x07, 0xc3, 0xfe, 0xdd, 0x4c, 0xcf, 0x28, 0xb9, 0xdd,
0x0f, 0x00, 0x00, 0x94, 0xe2, 0xaa, 0xcb, 0xdc, 0x1d, 0x97, 0xce, 0xaf, 0xe1, 0x45, 0xe6, 0xe4, 0xea, 0xe6, 0xb8,
0x3a, 0x18, 0x6c, 0xb0, 0xbe, 0x1c, 0x6d, 0x6e, 0x35, 0xda, 0xbf, 0x5b, 0x50, 0xf9, 0x92, 0xdc,
0xcc, 0x92, 0x5b, 0xbc, 0x01, 0x79, 0xce, 0xc6, 0xe6, 0xd4, 0xc9, 0xa5, 0xbc, 0xd7, 0x05, 0x9b,
0x50, 0x2e, 0xc8, 0x64, 0xaa, 0xf4, 0x0b, 0x78, 0xc1, 0x90, 0x4e, 0x45, 0x34, 0x65, 0x9e, 0x2a,
0x6f, 0x15, 0x6b, 0x42, 0xbd, 0xdc, 0xc8, 0x3c, 0x88, 0x48, 0x82, 0x97, 0x84, 0xd4, 0x5f, 0x7c,
0x9f, 0x85, 0x63, 0x53, 0xda, 0x84, 0x94, 0x9d, 0xe4, 0x9a, 0xf0, 0x6b, 0x55, 0xd0, 0x2a, 0x56,
0x6b, 0xe4, 0x40, 0x55, 0x5c, 0xb3, 0xd8, 0x3f, 0x27, 0xb1, 0xac, 0x83, 0x79, 0x4f, 0x2c, 0xf1,
0x9c, 0x3f, 0xc2, 0x41, 0x26, 0x81, 0xa4, 0x2c, 0x54, 0x10, 0x9f, 0x08, 0x22, 0xfd, 0xdd, 0xd2,
0x98, 0x27, 0x9d, 0xa4, 0x86, 0x13, 0x52, 0xfa, 0xbb, 0x8a, 0xa3, 0x89, 0x49, 0x49, 0xad, 0xe5,
0xd3, 0x41, 0x44, 0x2a, 0x95, 0x02, 0xce, 0x89, 0x48, 0xfa, 0x97, 0xcf, 0x2e, 0x1a, 0x8a, 0x91,
0x4a, 0x52, 0x4e, 0xf0, 0x55, 0xbc, 0xc4, 0x93, 0xef, 0x6f, 0x74, 0x37, 0x80, 0x77, 0x38, 0xfe,
0x1c, 0x4a, 0x13, 0x13, 0x9e, 0x41, 0x74, 0xe6, 0xce, 0xda, 0x9c, 0x0a, 0x4e, 0xb5, 0xd0, 0x47,
0xd2, 0x82, 0x92, 0xe1, 0xe6, 0x39, 0xb2, 0xbb, 0xd6, 0x02, 0x4e, 0xc5, 0x9c, 0x7f, 0x58, 0x70,
0x78, 0xd7, 0x76, 0x37, 0xf4, 0xe9, 0xef, 0xdf, 0xa3, 0x56, 0xdf, 0x3e, 0xe4, 0x3d, 0xd8, 0x8a,
0xae, 0xae, 0x38, 0x15, 0xa6, 0xba, 0x86, 0x92, 0xbb, 0xc0, 0xd9, 0x1f, 0xa8, 0xf9, 0x4b, 0x43,
0xad, 0x57, 0x31, 0x52, 0x48, 0x31, 0xe2, 0xfc, 0xd3, 0x82, 0xfd, 0x0d, 0x59, 0xa0, 0xb7, 0x50,
0x32, 0xc3, 0x72, 0x32, 0x0a, 0xbc, 0x7c, 0x57, 0x8c, 0x4a, 0xa9, 0x69, 0x08, 0x33, 0x15, 0xa4,
0x06, 0x0e, 0xae, 0xa0, 0xb6, 0xf4, 0x69, 0xcd, 0x25, 0xfb, 0xd9, 0xf2, 0x25, 0xfb, 0xe1, 0xbd,
0xce, 0xd2, 0xaa, 0x2c, 0x2e, 0xdd, 0xd7, 0xb5, 0xaf, 0x2b, 0xcd, 0x97, 0x9f, 0x24, 0x9a, 0x97,
0x5b, 0x6a, 0xf5, 0xf1, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x59, 0xa3, 0xa0, 0xfc, 0x8b, 0x12,
0x00, 0x00,
} }

View File

@ -37,6 +37,31 @@ message CommunityPermissions {
Access access = 3; Access access = 3;
} }
message TokenCriteria {
map<uint64, string> contract_addresses = 1;
CommunityTokenType type = 2;
string symbol = 3;
string name = 4;
string amount = 5;
repeated uint64 token_ids = 6;
string ens_pattern = 7;
}
message CommunityTokenPermission {
enum Type {
UNKNOWN_TOKEN_PERMISSION = 0;
BECOME_ADMIN = 1;
BECOME_MEMBER = 2;
}
string id = 1;
Type type = 2;
repeated TokenCriteria token_criteria = 3;
repeated string chat_ids = 4;
bool is_private = 5;
}
message CommunityDescription { message CommunityDescription {
uint64 clock = 1; uint64 clock = 1;
map<string,CommunityMember> members = 2; map<string,CommunityMember> members = 2;
@ -51,6 +76,7 @@ message CommunityDescription {
string outro_message = 12; string outro_message = 12;
bool encrypted = 13; bool encrypted = 13;
repeated string tags = 14; repeated string tags = 14;
map<string, CommunityTokenPermission> token_permissions = 15;
} }
message CommunityAdminSettings { message CommunityAdminSettings {

View File

@ -0,0 +1,58 @@
package requests
import (
"errors"
"strconv"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/protocol/protobuf"
)
const maxTokenCriteriaPerPermission = 5
var (
ErrCreateCommunityTokenPermissionInvalidCommunityID = errors.New("create community token permission needs a valid community id")
ErrCreateCommunityTokenPermissionTooManyTokenCriteria = errors.New("too many token criteria")
ErrCreateCommunityTokenPermissionInvalidPermissionType = errors.New("invalid community token permission type")
ErrCreateCommunityTokenPermissionInvalidTokenCriteria = errors.New("invalid community permission token criteria data")
)
type CreateCommunityTokenPermission struct {
CommunityID types.HexBytes `json:"communityId"`
Type protobuf.CommunityTokenPermission_Type `json:"type"`
TokenCriteria []*protobuf.TokenCriteria `json:"tokenCriteria"`
}
func (p *CreateCommunityTokenPermission) Validate() error {
if len(p.CommunityID) == 0 {
return ErrCreateCommunityTokenPermissionInvalidCommunityID
}
if len(p.TokenCriteria) > maxTokenCriteriaPerPermission {
return ErrCreateCommunityTokenPermissionTooManyTokenCriteria
}
if p.Type == protobuf.CommunityTokenPermission_UNKNOWN_TOKEN_PERMISSION {
return ErrCreateCommunityTokenPermissionInvalidPermissionType
}
for _, c := range p.TokenCriteria {
if c.EnsPattern == "" && len(c.ContractAddresses) == 0 {
return ErrCreateCommunityTokenPermissionInvalidTokenCriteria
}
floatAmount, _ := strconv.ParseFloat(c.Amount, 32)
if len(c.ContractAddresses) > 0 && floatAmount == 0 {
return ErrCreateCommunityTokenPermissionInvalidTokenCriteria
}
}
return nil
}
func (p *CreateCommunityTokenPermission) ToCommunityTokenPermission() protobuf.CommunityTokenPermission {
return protobuf.CommunityTokenPermission{
Type: p.Type,
TokenCriteria: p.TokenCriteria,
}
}

View File

@ -0,0 +1,26 @@
package requests
import (
"errors"
"github.com/status-im/status-go/eth-node/types"
)
var ErrDeleteCommunityTokenPermissionInvalidCommunityID = errors.New("delete community token permission needs a valid community id ")
var ErrDeleteCommunityTokenPermissionInvalidPermissionID = errors.New("invalid token permission id")
type DeleteCommunityTokenPermission struct {
CommunityID types.HexBytes `json:"communityId"`
PermissionID string `json:"permissionId"`
}
func (r *DeleteCommunityTokenPermission) Validate() error {
if len(r.CommunityID) == 0 {
return ErrDeleteCommunityCategoryInvalidCommunityID
}
if len(r.PermissionID) == 0 {
return ErrDeleteCommunityTokenPermissionInvalidPermissionID
}
return nil
}

View File

@ -0,0 +1,32 @@
package requests
import (
"errors"
"github.com/status-im/status-go/protocol/protobuf"
)
var (
ErrEditCommunityTokenPermissionInvalidID = errors.New("invalid community token permission id")
)
type EditCommunityTokenPermission struct {
PermissionID string `json:"permissionId"`
CreateCommunityTokenPermission
}
func (u *EditCommunityTokenPermission) Validate() error {
if len(u.PermissionID) == 0 {
return ErrEditCommunityTokenPermissionInvalidID
}
return u.CreateCommunityTokenPermission.Validate()
}
func (u *EditCommunityTokenPermission) ToCommunityTokenPermission() protobuf.CommunityTokenPermission {
return protobuf.CommunityTokenPermission{
Id: u.PermissionID,
Type: u.Type,
TokenCriteria: u.TokenCriteria,
}
}

View File

@ -484,6 +484,18 @@ func (api *PublicAPI) RemoveRoleFromMember(request *requests.RemoveRoleFromMembe
return api.service.messenger.RemoveRoleFromMember(request) return api.service.messenger.RemoveRoleFromMember(request)
} }
func (api *PublicAPI) CreateCommunityTokenPermission(request *requests.CreateCommunityTokenPermission) (*protocol.MessengerResponse, error) {
return api.service.messenger.CreateCommunityTokenPermission(request)
}
func (api *PublicAPI) DeleteCommunityTokenPermission(request *requests.DeleteCommunityTokenPermission) (*protocol.MessengerResponse, error) {
return api.service.messenger.DeleteCommunityTokenPermission(request)
}
func (api *PublicAPI) EditCommunityTokenPermission(request *requests.EditCommunityTokenPermission) (*protocol.MessengerResponse, error) {
return api.service.messenger.EditCommunityTokenPermission(request)
}
// MyPendingRequestsToJoin returns the pending requests for the logged in user // MyPendingRequestsToJoin returns the pending requests for the logged in user
func (api *PublicAPI) MyPendingRequestsToJoin() ([]*communities.RequestToJoin, error) { func (api *PublicAPI) MyPendingRequestsToJoin() ([]*communities.RequestToJoin, error) {
return api.service.messenger.MyPendingRequestsToJoin() return api.service.messenger.MyPendingRequestsToJoin()