Feat: proof of membership for profile showcase communities (#4713)

* chore: move profile showcase structures to the indentity package

* feat: implement proof of membership for unecrypted communities

* feat: implement proof of membership for encrypted communties with grants
This commit is contained in:
Mikhail Rogachev 2024-02-15 22:13:12 +03:00 committed by GitHub
parent 12d70e0ce4
commit 526e3d74f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 1270 additions and 845 deletions

View File

@ -797,6 +797,16 @@ func (m *Manager) CreateCommunity(request *requests.CreateCommunity, publish boo
return nil, err
}
// Save grant for own community
grant, err := community.BuildGrant(&m.identity.PublicKey, "")
if err != nil {
return nil, err
}
err = m.persistence.SaveCommunityGrant(community.IDString(), grant, description.Clock)
if err != nil {
return nil, err
}
// Mark this device as the control node
syncControlNode := &protobuf.SyncCommunityControlNode{
Clock: 1,
@ -1272,6 +1282,16 @@ func (m *Manager) ImportCommunity(key *ecdsa.PrivateKey, clock uint64) (*Communi
return nil, err
}
// Save grant for own community
grant, err := community.BuildGrant(&m.identity.PublicKey, "")
if err != nil {
return nil, err
}
err = m.persistence.SaveCommunityGrant(community.IDString(), grant, community.Description().Clock)
if err != nil {
return nil, err
}
// Mark this device as the control node
syncControlNode := &protobuf.SyncCommunityControlNode{
Clock: clock,
@ -2850,6 +2870,10 @@ func (m *Manager) HandleCommunityRequestToJoinResponse(signer *ecdsa.PublicKey,
return nil, err
}
if err = m.handleCommunityGrant(community.ID(), request.Grant, request.Clock); err != nil {
return nil, err
}
err = m.persistence.SaveCommunity(community)
if err != nil {
@ -4405,6 +4429,10 @@ func (m *Manager) GetAllCommunityTokens() ([]*community_token.CommunityToken, er
return m.persistence.GetAllCommunityTokens()
}
func (m *Manager) GetCommunityGrant(communityID string) ([]byte, uint64, error) {
return m.persistence.GetCommunityGrant(communityID)
}
func (m *Manager) ImageToBase64(uri string) string {
if uri == "" {
return ""
@ -4720,6 +4748,19 @@ func (m *Manager) handleCommunityTokensMetadata(community *Community) error {
return nil
}
func (m *Manager) handleCommunityGrant(communityID types.HexBytes, grant []byte, clock uint64) error {
_, oldClock, err := m.persistence.GetCommunityGrant(communityID.String())
if err != nil {
return err
}
if oldClock >= clock {
return nil
}
return m.persistence.SaveCommunityGrant(communityID.String(), grant, clock)
}
func (m *Manager) FetchCommunityToken(community *Community, tokenMetadata *protobuf.CommunityTokenMetadata, chainID uint64, contractAddress string) (*community_token.CommunityToken, error) {
communityID := community.IDString()

View File

@ -1326,6 +1326,31 @@ func (p *Persistence) RemoveCommunityToken(chainID int, contractAddress string)
return err
}
func (p *Persistence) GetCommunityGrant(communityID string) ([]byte, uint64, error) {
var grant []byte
var clock uint64
err := p.db.QueryRow(`SELECT grant, clock FROM community_grants WHERE community_id = ?`, communityID).Scan(&grant, &clock)
if err == sql.ErrNoRows {
return []byte{}, 0, nil
} else if err != nil {
return []byte{}, 0, err
}
return grant, clock, nil
}
func (p *Persistence) SaveCommunityGrant(communityID string, grant []byte, clock uint64) error {
_, err := p.db.Exec(`INSERT OR REPLACE INTO community_grants(community_id, grant, clock) VALUES (?, ?, ?)`,
communityID, grant, clock)
return err
}
func (p *Persistence) RemoveCommunityGrant(communityID string) error {
_, err := p.db.Exec(`DELETE FROM community_grants WHERE community_id = ?`, communityID)
return err
}
func decodeWrappedCommunityDescription(wrappedDescriptionBytes []byte) (*protobuf.CommunityDescription, error) {
metadata := &protobuf.ApplicationMetadataMessage{}

View File

@ -0,0 +1,145 @@
package identity
import "errors"
var ErrorNoAccountProvidedWithTokenOrCollectible = errors.New("no account provided with tokens or collectible")
var ErrorDublicateAccountAddress = errors.New("duplicate account address")
var ErrorAccountVisibilityLowerThanCollectible = errors.New("account visibility lower than collectible")
type ProfileShowcaseVisibility int
const (
ProfileShowcaseVisibilityNoOne ProfileShowcaseVisibility = iota
ProfileShowcaseVisibilityIDVerifiedContacts
ProfileShowcaseVisibilityContacts
ProfileShowcaseVisibilityEveryone
)
type ProfileShowcaseMembershipStatus int
const (
ProfileShowcaseMembershipStatusUnproven ProfileShowcaseMembershipStatus = iota
ProfileShowcaseMembershipStatusProvenMember
ProfileShowcaseMembershipStatusNotAMember
)
type ProfileShowcaseCommunityPreference struct {
CommunityID string `json:"communityId"`
ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"`
Order int `json:"order"`
}
type ProfileShowcaseAccountPreference struct {
Address string `json:"address"`
Name string `json:"name"`
ColorID string `json:"colorId"`
Emoji string `json:"emoji"`
ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"`
Order int `json:"order"`
}
type ProfileShowcaseCollectiblePreference struct {
ContractAddress string `json:"contractAddress"`
ChainID uint64 `json:"chainId"`
TokenID string `json:"tokenId"`
CommunityID string `json:"communityId"`
AccountAddress string `json:"accountAddress"`
ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"`
Order int `json:"order"`
}
type ProfileShowcaseVerifiedTokenPreference struct {
Symbol string `json:"symbol"`
ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"`
Order int `json:"order"`
}
type ProfileShowcaseUnverifiedTokenPreference struct {
ContractAddress string `json:"contractAddress"`
ChainID uint64 `json:"chainId"`
CommunityID string `json:"communityId"`
ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"`
Order int `json:"order"`
}
type ProfileShowcasePreferences struct {
Communities []*ProfileShowcaseCommunityPreference `json:"communities"`
Accounts []*ProfileShowcaseAccountPreference `json:"accounts"`
Collectibles []*ProfileShowcaseCollectiblePreference `json:"collectibles"`
VerifiedTokens []*ProfileShowcaseVerifiedTokenPreference `json:"verifiedTokens"`
UnverifiedTokens []*ProfileShowcaseUnverifiedTokenPreference `json:"unverifiedTokens"`
}
type ProfileShowcaseCommunity struct {
CommunityID string `json:"communityId"`
Order int `json:"order"`
MembershipStatus ProfileShowcaseMembershipStatus `json:"membershipStatus"`
}
type ProfileShowcaseAccount struct {
ContactID string `json:"contactId"`
Address string `json:"address"`
Name string `json:"name"`
ColorID string `json:"colorId"`
Emoji string `json:"emoji"`
Order int `json:"order"`
}
type ProfileShowcaseCollectible struct {
ContractAddress string `json:"contractAddress"`
ChainID uint64 `json:"chainId"`
TokenID string `json:"tokenId"`
CommunityID string `json:"communityId"`
AccountAddress string `json:"accountAddress"`
Order int `json:"order"`
}
type ProfileShowcaseVerifiedToken struct {
Symbol string `json:"symbol"`
Order int `json:"order"`
}
type ProfileShowcaseUnverifiedToken struct {
ContractAddress string `json:"contractAddress"`
ChainID uint64 `json:"chainId"`
CommunityID string `json:"communityId"`
Order int `json:"order"`
}
type ProfileShowcase struct {
ContactID string `json:"contactId"`
Communities []*ProfileShowcaseCommunity `json:"communities"`
Accounts []*ProfileShowcaseAccount `json:"accounts"`
Collectibles []*ProfileShowcaseCollectible `json:"collectibles"`
VerifiedTokens []*ProfileShowcaseVerifiedToken `json:"verifiedTokens"`
UnverifiedTokens []*ProfileShowcaseUnverifiedToken `json:"unverifiedTokens"`
}
func Validate(preferences *ProfileShowcasePreferences) error {
if (len(preferences.VerifiedTokens) > 0 || len(preferences.UnverifiedTokens) > 0 || len(preferences.Collectibles) > 0) &&
len(preferences.Accounts) == 0 {
return ErrorNoAccountProvidedWithTokenOrCollectible
}
accountsMap := make(map[string]*ProfileShowcaseAccountPreference)
for _, account := range preferences.Accounts {
if _, ok := accountsMap[account.Address]; ok {
return ErrorDublicateAccountAddress
}
accountsMap[account.Address] = account
}
for _, collectible := range preferences.Collectibles {
account, ok := accountsMap[collectible.AccountAddress]
if !ok {
return nil
// NOTE: with current wallet collectible implementation we don't know account on this stage
// return errorNoAccountAddressForCollectible
}
if account.ShowcaseVisibility < collectible.ShowcaseVisibility {
return ErrorAccountVisibilityLowerThanCollectible
}
}
return nil
}

View File

@ -1,50 +1,65 @@
package protocol
import (
"bytes"
"crypto/ecdsa"
crand "crypto/rand"
"errors"
"reflect"
"sort"
"github.com/golang/protobuf/proto"
"go.uber.org/zap"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/protocol/common"
"github.com/status-im/status-go/protocol/communities"
"github.com/status-im/status-go/protocol/identity"
"github.com/status-im/status-go/protocol/protobuf"
)
var errorNoAccountProvidedWithTokenOrCollectible = errors.New("no account provided with tokens or collectible")
var errorDublicateAccountAddress = errors.New("duplicate account address")
// NOTE: this error is temporary unused because we don't know account on this stage
// var errorNoAccountAddressForCollectible = errors.New("no account found for collectible")
var errorAccountVisibilityLowerThanCollectible = errors.New("account visibility lower than collectible")
var errorDecryptingPayloadEncryptionKey = errors.New("decrypting the payload encryption key resulted in no error and a nil key")
func toProfileShowcaseCommunityProto(preferences []*ProfileShowcaseCommunityPreference, visibility ProfileShowcaseVisibility) []*protobuf.ProfileShowcaseCommunity {
communities := []*protobuf.ProfileShowcaseCommunity{}
func (m *Messenger) toProfileShowcaseCommunityProto(preferences []*identity.ProfileShowcaseCommunityPreference, visibility identity.ProfileShowcaseVisibility) []*protobuf.ProfileShowcaseCommunity {
entries := []*protobuf.ProfileShowcaseCommunity{}
for _, preference := range preferences {
if preference.ShowcaseVisibility != visibility {
continue
}
communities = append(communities, &protobuf.ProfileShowcaseCommunity{
entry := &protobuf.ProfileShowcaseCommunity{
CommunityId: preference.CommunityID,
Order: uint32(preference.Order),
})
}
community, err := m.communitiesManager.GetByIDString(preference.CommunityID)
if err != nil {
m.logger.Warn("failed to get community for profile entry ", zap.Error(err))
}
if community != nil && community.Encrypted() {
grant, _, err := m.communitiesManager.GetCommunityGrant(preference.CommunityID)
if err != nil {
m.logger.Warn("failed to get community for profile entry ", zap.Error(err))
}
entry.Grant = grant
}
entries = append(entries, entry)
}
return communities
return entries
}
func toProfileShowcaseAccountProto(preferences []*ProfileShowcaseAccountPreference, visibility ProfileShowcaseVisibility) []*protobuf.ProfileShowcaseAccount {
accounts := []*protobuf.ProfileShowcaseAccount{}
func (m *Messenger) toProfileShowcaseAccountProto(preferences []*identity.ProfileShowcaseAccountPreference, visibility identity.ProfileShowcaseVisibility) []*protobuf.ProfileShowcaseAccount {
entries := []*protobuf.ProfileShowcaseAccount{}
for _, preference := range preferences {
if preference.ShowcaseVisibility != visibility {
continue
}
accounts = append(accounts, &protobuf.ProfileShowcaseAccount{
entries = append(entries, &protobuf.ProfileShowcaseAccount{
Address: preference.Address,
Name: preference.Name,
ColorId: preference.ColorID,
@ -52,17 +67,17 @@ func toProfileShowcaseAccountProto(preferences []*ProfileShowcaseAccountPreferen
Order: uint32(preference.Order),
})
}
return accounts
return entries
}
func toProfileShowcaseCollectibleProto(preferences []*ProfileShowcaseCollectiblePreference, visibility ProfileShowcaseVisibility) []*protobuf.ProfileShowcaseCollectible {
collectibles := []*protobuf.ProfileShowcaseCollectible{}
func (m *Messenger) toProfileShowcaseCollectibleProto(preferences []*identity.ProfileShowcaseCollectiblePreference, visibility identity.ProfileShowcaseVisibility) []*protobuf.ProfileShowcaseCollectible {
entries := []*protobuf.ProfileShowcaseCollectible{}
for _, preference := range preferences {
if preference.ShowcaseVisibility != visibility {
continue
}
collectibles = append(collectibles, &protobuf.ProfileShowcaseCollectible{
entries = append(entries, &protobuf.ProfileShowcaseCollectible{
ContractAddress: preference.ContractAddress,
ChainId: preference.ChainID,
TokenId: preference.TokenID,
@ -71,55 +86,89 @@ func toProfileShowcaseCollectibleProto(preferences []*ProfileShowcaseCollectible
Order: uint32(preference.Order),
})
}
return collectibles
return entries
}
func toProfileShowcaseVerifiedTokensProto(preferences []*ProfileShowcaseVerifiedTokenPreference, visibility ProfileShowcaseVisibility) []*protobuf.ProfileShowcaseVerifiedToken {
tokens := []*protobuf.ProfileShowcaseVerifiedToken{}
func (m *Messenger) toProfileShowcaseVerifiedTokensProto(preferences []*identity.ProfileShowcaseVerifiedTokenPreference, visibility identity.ProfileShowcaseVisibility) []*protobuf.ProfileShowcaseVerifiedToken {
entries := []*protobuf.ProfileShowcaseVerifiedToken{}
for _, preference := range preferences {
if preference.ShowcaseVisibility != visibility {
continue
}
tokens = append(tokens, &protobuf.ProfileShowcaseVerifiedToken{
entries = append(entries, &protobuf.ProfileShowcaseVerifiedToken{
Symbol: preference.Symbol,
Order: uint32(preference.Order),
})
}
return tokens
return entries
}
func toProfileShowcaseUnverifiedTokensProto(preferences []*ProfileShowcaseUnverifiedTokenPreference, visibility ProfileShowcaseVisibility) []*protobuf.ProfileShowcaseUnverifiedToken {
tokens := []*protobuf.ProfileShowcaseUnverifiedToken{}
func (m *Messenger) toProfileShowcaseUnverifiedTokensProto(preferences []*identity.ProfileShowcaseUnverifiedTokenPreference, visibility identity.ProfileShowcaseVisibility) []*protobuf.ProfileShowcaseUnverifiedToken {
entries := []*protobuf.ProfileShowcaseUnverifiedToken{}
for _, preference := range preferences {
if preference.ShowcaseVisibility != visibility {
continue
}
tokens = append(tokens, &protobuf.ProfileShowcaseUnverifiedToken{
entries = append(entries, &protobuf.ProfileShowcaseUnverifiedToken{
ContractAddress: preference.ContractAddress,
ChainId: preference.ChainID,
Order: uint32(preference.Order),
})
}
return tokens
return entries
}
func fromProfileShowcaseCommunityProto(messages []*protobuf.ProfileShowcaseCommunity) []*ProfileShowcaseCommunity {
communities := []*ProfileShowcaseCommunity{}
for _, entry := range messages {
communities = append(communities, &ProfileShowcaseCommunity{
CommunityID: entry.CommunityId,
Order: int(entry.Order),
func (m *Messenger) fromProfileShowcaseCommunityProto(senderPubKey *ecdsa.PublicKey, messages []*protobuf.ProfileShowcaseCommunity) []*identity.ProfileShowcaseCommunity {
entries := []*identity.ProfileShowcaseCommunity{}
for _, message := range messages {
entry := &identity.ProfileShowcaseCommunity{
CommunityID: message.CommunityId,
Order: int(message.Order),
MembershipStatus: identity.ProfileShowcaseMembershipStatusUnproven,
}
community, err := m.FetchCommunity(&FetchCommunityRequest{
CommunityKey: message.CommunityId,
Shard: nil,
TryDatabase: true,
WaitForResponse: true,
})
if err != nil {
m.logger.Warn("failed to fetch community for profile entry ", zap.Error(err))
}
if community != nil && community.Encrypted() {
grant, err := community.VerifyGrantSignature(message.Grant)
if err != nil {
m.logger.Warn("failed to verify grant signature ", zap.Error(err))
entry.MembershipStatus = identity.ProfileShowcaseMembershipStatusNotAMember
} else {
if grant != nil && bytes.Equal(grant.MemberId, crypto.CompressPubkey(senderPubKey)) {
entry.MembershipStatus = identity.ProfileShowcaseMembershipStatusProvenMember
} else { // Show as not a member if membership can't be proven
entry.MembershipStatus = identity.ProfileShowcaseMembershipStatusNotAMember
}
}
} else if community != nil {
// Use member list as a proof for unecrypted communities
if community.HasMember(senderPubKey) {
entry.MembershipStatus = identity.ProfileShowcaseMembershipStatusProvenMember
} else {
entry.MembershipStatus = identity.ProfileShowcaseMembershipStatusNotAMember
}
}
entries = append(entries, entry)
}
return communities
return entries
}
func fromProfileShowcaseAccountProto(messages []*protobuf.ProfileShowcaseAccount) []*ProfileShowcaseAccount {
accounts := []*ProfileShowcaseAccount{}
func (m *Messenger) fromProfileShowcaseAccountProto(messages []*protobuf.ProfileShowcaseAccount) []*identity.ProfileShowcaseAccount {
entries := []*identity.ProfileShowcaseAccount{}
for _, entry := range messages {
accounts = append(accounts, &ProfileShowcaseAccount{
entries = append(entries, &identity.ProfileShowcaseAccount{
Address: entry.Address,
Name: entry.Name,
ColorID: entry.ColorId,
@ -127,13 +176,13 @@ func fromProfileShowcaseAccountProto(messages []*protobuf.ProfileShowcaseAccount
Order: int(entry.Order),
})
}
return accounts
return entries
}
func fromProfileShowcaseCollectibleProto(messages []*protobuf.ProfileShowcaseCollectible) []*ProfileShowcaseCollectible {
collectibles := []*ProfileShowcaseCollectible{}
func (m *Messenger) fromProfileShowcaseCollectibleProto(messages []*protobuf.ProfileShowcaseCollectible) []*identity.ProfileShowcaseCollectible {
entries := []*identity.ProfileShowcaseCollectible{}
for _, entry := range messages {
collectibles = append(collectibles, &ProfileShowcaseCollectible{
entries = append(entries, &identity.ProfileShowcaseCollectible{
ContractAddress: entry.ContractAddress,
ChainID: entry.ChainId,
TokenID: entry.TokenId,
@ -142,63 +191,34 @@ func fromProfileShowcaseCollectibleProto(messages []*protobuf.ProfileShowcaseCol
Order: int(entry.Order),
})
}
return collectibles
return entries
}
func fromProfileShowcaseVerifiedTokenProto(messages []*protobuf.ProfileShowcaseVerifiedToken) []*ProfileShowcaseVerifiedToken {
tokens := []*ProfileShowcaseVerifiedToken{}
func (m *Messenger) fromProfileShowcaseVerifiedTokenProto(messages []*protobuf.ProfileShowcaseVerifiedToken) []*identity.ProfileShowcaseVerifiedToken {
entries := []*identity.ProfileShowcaseVerifiedToken{}
for _, entry := range messages {
tokens = append(tokens, &ProfileShowcaseVerifiedToken{
entries = append(entries, &identity.ProfileShowcaseVerifiedToken{
Symbol: entry.Symbol,
Order: int(entry.Order),
})
}
return tokens
return entries
}
func fromProfileShowcaseUnverifiedTokenProto(messages []*protobuf.ProfileShowcaseUnverifiedToken) []*ProfileShowcaseUnverifiedToken {
tokens := []*ProfileShowcaseUnverifiedToken{}
func (m *Messenger) fromProfileShowcaseUnverifiedTokenProto(messages []*protobuf.ProfileShowcaseUnverifiedToken) []*identity.ProfileShowcaseUnverifiedToken {
entries := []*identity.ProfileShowcaseUnverifiedToken{}
for _, entry := range messages {
tokens = append(tokens, &ProfileShowcaseUnverifiedToken{
entries = append(entries, &identity.ProfileShowcaseUnverifiedToken{
ContractAddress: entry.ContractAddress,
ChainID: entry.ChainId,
Order: int(entry.Order),
})
}
return tokens
return entries
}
func Validate(preferences *ProfileShowcasePreferences) error {
if (len(preferences.VerifiedTokens) > 0 || len(preferences.UnverifiedTokens) > 0 || len(preferences.Collectibles) > 0) &&
len(preferences.Accounts) == 0 {
return errorNoAccountProvidedWithTokenOrCollectible
}
accountsMap := make(map[string]*ProfileShowcaseAccountPreference)
for _, account := range preferences.Accounts {
if _, ok := accountsMap[account.Address]; ok {
return errorDublicateAccountAddress
}
accountsMap[account.Address] = account
}
for _, collectible := range preferences.Collectibles {
account, ok := accountsMap[collectible.AccountAddress]
if !ok {
return nil
// NOTE: with current wallet collectible implementation we don't know account on this stage
// return errorNoAccountAddressForCollectible
}
if account.ShowcaseVisibility < collectible.ShowcaseVisibility {
return errorAccountVisibilityLowerThanCollectible
}
}
return nil
}
func (m *Messenger) SetProfileShowcasePreferences(preferences *ProfileShowcasePreferences) error {
err := Validate(preferences)
func (m *Messenger) SetProfileShowcasePreferences(preferences *identity.ProfileShowcasePreferences) error {
err := identity.Validate(preferences)
if err != nil {
return err
}
@ -215,15 +235,15 @@ func (m *Messenger) DispatchProfileShowcase() error {
return m.publishContactCode()
}
func (m *Messenger) GetProfileShowcasePreferences() (*ProfileShowcasePreferences, error) {
func (m *Messenger) GetProfileShowcasePreferences() (*identity.ProfileShowcasePreferences, error) {
return m.persistence.GetProfileShowcasePreferences()
}
func (m *Messenger) GetProfileShowcaseForContact(contactID string) (*ProfileShowcase, error) {
func (m *Messenger) GetProfileShowcaseForContact(contactID string) (*identity.ProfileShowcase, error) {
return m.persistence.GetProfileShowcaseForContact(contactID)
}
func (m *Messenger) GetProfileShowcaseAccountsByAddress(address string) ([]*ProfileShowcaseAccount, error) {
func (m *Messenger) GetProfileShowcaseAccountsByAddress(address string) ([]*identity.ProfileShowcaseAccount, error) {
return m.persistence.GetProfileShowcaseAccountsByAddress(address)
}
@ -324,27 +344,27 @@ func (m *Messenger) GetProfileShowcaseForSelfIdentity() (*protobuf.ProfileShowca
}
forEveryone := &protobuf.ProfileShowcaseEntries{
Communities: toProfileShowcaseCommunityProto(preferences.Communities, ProfileShowcaseVisibilityEveryone),
Accounts: toProfileShowcaseAccountProto(preferences.Accounts, ProfileShowcaseVisibilityEveryone),
Collectibles: toProfileShowcaseCollectibleProto(preferences.Collectibles, ProfileShowcaseVisibilityEveryone),
VerifiedTokens: toProfileShowcaseVerifiedTokensProto(preferences.VerifiedTokens, ProfileShowcaseVisibilityEveryone),
UnverifiedTokens: toProfileShowcaseUnverifiedTokensProto(preferences.UnverifiedTokens, ProfileShowcaseVisibilityEveryone),
Communities: m.toProfileShowcaseCommunityProto(preferences.Communities, identity.ProfileShowcaseVisibilityEveryone),
Accounts: m.toProfileShowcaseAccountProto(preferences.Accounts, identity.ProfileShowcaseVisibilityEveryone),
Collectibles: m.toProfileShowcaseCollectibleProto(preferences.Collectibles, identity.ProfileShowcaseVisibilityEveryone),
VerifiedTokens: m.toProfileShowcaseVerifiedTokensProto(preferences.VerifiedTokens, identity.ProfileShowcaseVisibilityEveryone),
UnverifiedTokens: m.toProfileShowcaseUnverifiedTokensProto(preferences.UnverifiedTokens, identity.ProfileShowcaseVisibilityEveryone),
}
forContacts := &protobuf.ProfileShowcaseEntries{
Communities: toProfileShowcaseCommunityProto(preferences.Communities, ProfileShowcaseVisibilityContacts),
Accounts: toProfileShowcaseAccountProto(preferences.Accounts, ProfileShowcaseVisibilityContacts),
Collectibles: toProfileShowcaseCollectibleProto(preferences.Collectibles, ProfileShowcaseVisibilityContacts),
VerifiedTokens: toProfileShowcaseVerifiedTokensProto(preferences.VerifiedTokens, ProfileShowcaseVisibilityContacts),
UnverifiedTokens: toProfileShowcaseUnverifiedTokensProto(preferences.UnverifiedTokens, ProfileShowcaseVisibilityContacts),
Communities: m.toProfileShowcaseCommunityProto(preferences.Communities, identity.ProfileShowcaseVisibilityContacts),
Accounts: m.toProfileShowcaseAccountProto(preferences.Accounts, identity.ProfileShowcaseVisibilityContacts),
Collectibles: m.toProfileShowcaseCollectibleProto(preferences.Collectibles, identity.ProfileShowcaseVisibilityContacts),
VerifiedTokens: m.toProfileShowcaseVerifiedTokensProto(preferences.VerifiedTokens, identity.ProfileShowcaseVisibilityContacts),
UnverifiedTokens: m.toProfileShowcaseUnverifiedTokensProto(preferences.UnverifiedTokens, identity.ProfileShowcaseVisibilityContacts),
}
forIDVerifiedContacts := &protobuf.ProfileShowcaseEntries{
Communities: toProfileShowcaseCommunityProto(preferences.Communities, ProfileShowcaseVisibilityIDVerifiedContacts),
Accounts: toProfileShowcaseAccountProto(preferences.Accounts, ProfileShowcaseVisibilityIDVerifiedContacts),
Collectibles: toProfileShowcaseCollectibleProto(preferences.Collectibles, ProfileShowcaseVisibilityIDVerifiedContacts),
VerifiedTokens: toProfileShowcaseVerifiedTokensProto(preferences.VerifiedTokens, ProfileShowcaseVisibilityIDVerifiedContacts),
UnverifiedTokens: toProfileShowcaseUnverifiedTokensProto(preferences.UnverifiedTokens, ProfileShowcaseVisibilityIDVerifiedContacts),
Communities: m.toProfileShowcaseCommunityProto(preferences.Communities, identity.ProfileShowcaseVisibilityIDVerifiedContacts),
Accounts: m.toProfileShowcaseAccountProto(preferences.Accounts, identity.ProfileShowcaseVisibilityIDVerifiedContacts),
Collectibles: m.toProfileShowcaseCollectibleProto(preferences.Collectibles, identity.ProfileShowcaseVisibilityIDVerifiedContacts),
VerifiedTokens: m.toProfileShowcaseVerifiedTokensProto(preferences.VerifiedTokens, identity.ProfileShowcaseVisibilityIDVerifiedContacts),
UnverifiedTokens: m.toProfileShowcaseUnverifiedTokensProto(preferences.UnverifiedTokens, identity.ProfileShowcaseVisibilityIDVerifiedContacts),
}
mutualContacts := []*Contact{}
@ -377,33 +397,66 @@ func (m *Messenger) GetProfileShowcaseForSelfIdentity() (*protobuf.ProfileShowca
}, nil
}
func (m *Messenger) buildProfileShowcaseFromEntries(
contactID string,
communities []*identity.ProfileShowcaseCommunity,
accounts []*identity.ProfileShowcaseAccount,
collectibles []*identity.ProfileShowcaseCollectible,
verifiedTokens []*identity.ProfileShowcaseVerifiedToken,
unverifiedTokens []*identity.ProfileShowcaseUnverifiedToken) *identity.ProfileShowcase {
sort.Slice(communities, func(i, j int) bool {
return communities[j].Order > communities[i].Order
})
sort.Slice(accounts, func(i, j int) bool {
return accounts[j].Order > accounts[i].Order
})
sort.Slice(collectibles, func(i, j int) bool {
return collectibles[j].Order > collectibles[i].Order
})
sort.Slice(verifiedTokens, func(i, j int) bool {
return verifiedTokens[j].Order > verifiedTokens[i].Order
})
sort.Slice(unverifiedTokens, func(i, j int) bool {
return unverifiedTokens[j].Order > unverifiedTokens[i].Order
})
return &identity.ProfileShowcase{
ContactID: contactID,
Communities: communities,
Accounts: accounts,
Collectibles: collectibles,
VerifiedTokens: verifiedTokens,
UnverifiedTokens: unverifiedTokens,
}
}
func (m *Messenger) BuildProfileShowcaseFromIdentity(state *ReceivedMessageState, message *protobuf.ProfileShowcase) error {
communities := []*ProfileShowcaseCommunity{}
accounts := []*ProfileShowcaseAccount{}
collectibles := []*ProfileShowcaseCollectible{}
verifiedTokens := []*ProfileShowcaseVerifiedToken{}
unverifiedTokens := []*ProfileShowcaseUnverifiedToken{}
communities = append(communities, fromProfileShowcaseCommunityProto(message.ForEveryone.Communities)...)
accounts = append(accounts, fromProfileShowcaseAccountProto(message.ForEveryone.Accounts)...)
collectibles = append(collectibles, fromProfileShowcaseCollectibleProto(message.ForEveryone.Collectibles)...)
verifiedTokens = append(verifiedTokens, fromProfileShowcaseVerifiedTokenProto(message.ForEveryone.VerifiedTokens)...)
unverifiedTokens = append(unverifiedTokens, fromProfileShowcaseUnverifiedTokenProto(message.ForEveryone.UnverifiedTokens)...)
senderPubKey := state.CurrentMessageState.PublicKey
contactID := state.CurrentMessageState.Contact.ID
communities := []*identity.ProfileShowcaseCommunity{}
accounts := []*identity.ProfileShowcaseAccount{}
collectibles := []*identity.ProfileShowcaseCollectible{}
verifiedTokens := []*identity.ProfileShowcaseVerifiedToken{}
unverifiedTokens := []*identity.ProfileShowcaseUnverifiedToken{}
communities = append(communities, m.fromProfileShowcaseCommunityProto(senderPubKey, message.ForEveryone.Communities)...)
accounts = append(accounts, m.fromProfileShowcaseAccountProto(message.ForEveryone.Accounts)...)
collectibles = append(collectibles, m.fromProfileShowcaseCollectibleProto(message.ForEveryone.Collectibles)...)
verifiedTokens = append(verifiedTokens, m.fromProfileShowcaseVerifiedTokenProto(message.ForEveryone.VerifiedTokens)...)
unverifiedTokens = append(unverifiedTokens, m.fromProfileShowcaseUnverifiedTokenProto(message.ForEveryone.UnverifiedTokens)...)
forContacts, err := m.DecryptProfileShowcaseEntriesWithPubKey(senderPubKey, message.ForContacts)
if err != nil {
return err
}
if forContacts != nil {
communities = append(communities, fromProfileShowcaseCommunityProto(forContacts.Communities)...)
accounts = append(accounts, fromProfileShowcaseAccountProto(forContacts.Accounts)...)
collectibles = append(collectibles, fromProfileShowcaseCollectibleProto(forContacts.Collectibles)...)
verifiedTokens = append(verifiedTokens, fromProfileShowcaseVerifiedTokenProto(forContacts.VerifiedTokens)...)
unverifiedTokens = append(unverifiedTokens, fromProfileShowcaseUnverifiedTokenProto(forContacts.UnverifiedTokens)...)
communities = append(communities, m.fromProfileShowcaseCommunityProto(senderPubKey, forContacts.Communities)...)
accounts = append(accounts, m.fromProfileShowcaseAccountProto(forContacts.Accounts)...)
collectibles = append(collectibles, m.fromProfileShowcaseCollectibleProto(forContacts.Collectibles)...)
verifiedTokens = append(verifiedTokens, m.fromProfileShowcaseVerifiedTokenProto(forContacts.VerifiedTokens)...)
unverifiedTokens = append(unverifiedTokens, m.fromProfileShowcaseUnverifiedTokenProto(forContacts.UnverifiedTokens)...)
}
forIDVerifiedContacts, err := m.DecryptProfileShowcaseEntriesWithPubKey(senderPubKey, message.ForIdVerifiedContacts)
@ -412,24 +465,15 @@ func (m *Messenger) BuildProfileShowcaseFromIdentity(state *ReceivedMessageState
}
if forIDVerifiedContacts != nil {
communities = append(communities, fromProfileShowcaseCommunityProto(forIDVerifiedContacts.Communities)...)
accounts = append(accounts, fromProfileShowcaseAccountProto(forIDVerifiedContacts.Accounts)...)
collectibles = append(collectibles, fromProfileShowcaseCollectibleProto(forIDVerifiedContacts.Collectibles)...)
verifiedTokens = append(verifiedTokens, fromProfileShowcaseVerifiedTokenProto(forIDVerifiedContacts.VerifiedTokens)...)
unverifiedTokens = append(unverifiedTokens, fromProfileShowcaseUnverifiedTokenProto(forIDVerifiedContacts.UnverifiedTokens)...)
communities = append(communities, m.fromProfileShowcaseCommunityProto(senderPubKey, forIDVerifiedContacts.Communities)...)
accounts = append(accounts, m.fromProfileShowcaseAccountProto(forIDVerifiedContacts.Accounts)...)
collectibles = append(collectibles, m.fromProfileShowcaseCollectibleProto(forIDVerifiedContacts.Collectibles)...)
verifiedTokens = append(verifiedTokens, m.fromProfileShowcaseVerifiedTokenProto(forIDVerifiedContacts.VerifiedTokens)...)
unverifiedTokens = append(unverifiedTokens, m.fromProfileShowcaseUnverifiedTokenProto(forIDVerifiedContacts.UnverifiedTokens)...)
}
// TODO: validate community membership here (https://github.com/status-im/status-desktop/issues/13081)
// TODO: validate collectible ownership here (https://github.com/status-im/status-desktop/issues/13073)
newShowcase := &ProfileShowcase{
ContactID: contactID,
Communities: communities,
Accounts: accounts,
Collectibles: collectibles,
VerifiedTokens: verifiedTokens,
UnverifiedTokens: unverifiedTokens,
}
newShowcase := m.buildProfileShowcaseFromEntries(
contactID, communities, accounts, collectibles, verifiedTokens, unverifiedTokens)
oldShowcase, err := m.persistence.GetProfileShowcaseForContact(contactID)
if err != nil {

View File

@ -10,6 +10,7 @@ import (
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/protocol/common"
"github.com/status-im/status-go/protocol/identity"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/requests"
)
@ -111,82 +112,66 @@ func (s *TestMessengerProfileShowcase) verifiedContact(theirMessenger *Messenger
s.Require().Equal(common.ContactVerificationStateTrusted, resp.Messages()[0].ContactVerificationState)
}
func (s *TestMessengerProfileShowcase) prepareShowcasePreferences() *ProfileShowcasePreferences {
return &ProfileShowcasePreferences{
Communities: []*ProfileShowcaseCommunityPreference{
&ProfileShowcaseCommunityPreference{
CommunityID: "0x32433445133424",
ShowcaseVisibility: ProfileShowcaseVisibilityEveryone,
Order: 0,
},
&ProfileShowcaseCommunityPreference{
CommunityID: "0x33443246664345",
ShowcaseVisibility: ProfileShowcaseVisibilityContacts,
Order: 1,
},
&ProfileShowcaseCommunityPreference{
CommunityID: "0x33446343643446",
ShowcaseVisibility: ProfileShowcaseVisibilityIDVerifiedContacts,
Order: 2,
},
},
Accounts: []*ProfileShowcaseAccountPreference{
&ProfileShowcaseAccountPreference{
func (s *TestMessengerProfileShowcase) prepareShowcasePreferences() *identity.ProfileShowcasePreferences {
return &identity.ProfileShowcasePreferences{
Communities: []*identity.ProfileShowcaseCommunityPreference{}, // empty to avoid fetching
Accounts: []*identity.ProfileShowcaseAccountPreference{
&identity.ProfileShowcaseAccountPreference{
Address: "0x32433445133424",
Name: "Status Account",
ColorID: "blue",
Emoji: "-_-",
ShowcaseVisibility: ProfileShowcaseVisibilityEveryone,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityEveryone,
Order: 0,
},
&ProfileShowcaseAccountPreference{
&identity.ProfileShowcaseAccountPreference{
Address: "0x3845354643324",
Name: "Money Box",
ColorID: "red",
Emoji: ":o)",
ShowcaseVisibility: ProfileShowcaseVisibilityContacts,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityContacts,
Order: 1,
},
},
Collectibles: []*ProfileShowcaseCollectiblePreference{
&ProfileShowcaseCollectiblePreference{
Collectibles: []*identity.ProfileShowcaseCollectiblePreference{
&identity.ProfileShowcaseCollectiblePreference{
ContractAddress: "0x12378534257568678487683576",
ChainID: 1,
TokenID: "0x12321389592999f903",
CommunityID: "0x01312357798976535",
AccountAddress: "0x32433445133424",
ShowcaseVisibility: ProfileShowcaseVisibilityEveryone,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityEveryone,
Order: 0,
},
},
VerifiedTokens: []*ProfileShowcaseVerifiedTokenPreference{
&ProfileShowcaseVerifiedTokenPreference{
VerifiedTokens: []*identity.ProfileShowcaseVerifiedTokenPreference{
&identity.ProfileShowcaseVerifiedTokenPreference{
Symbol: "ETH",
ShowcaseVisibility: ProfileShowcaseVisibilityEveryone,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityEveryone,
Order: 1,
},
&ProfileShowcaseVerifiedTokenPreference{
&identity.ProfileShowcaseVerifiedTokenPreference{
Symbol: "DAI",
ShowcaseVisibility: ProfileShowcaseVisibilityIDVerifiedContacts,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityIDVerifiedContacts,
Order: 2,
},
&ProfileShowcaseVerifiedTokenPreference{
&identity.ProfileShowcaseVerifiedTokenPreference{
Symbol: "SNT",
ShowcaseVisibility: ProfileShowcaseVisibilityNoOne,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityNoOne,
Order: 3,
},
},
UnverifiedTokens: []*ProfileShowcaseUnverifiedTokenPreference{
&ProfileShowcaseUnverifiedTokenPreference{
UnverifiedTokens: []*identity.ProfileShowcaseUnverifiedTokenPreference{
&identity.ProfileShowcaseUnverifiedTokenPreference{
ContractAddress: "0x454525452023452",
ChainID: 3,
ShowcaseVisibility: ProfileShowcaseVisibilityEveryone,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityEveryone,
Order: 0,
},
&ProfileShowcaseUnverifiedTokenPreference{
&identity.ProfileShowcaseUnverifiedTokenPreference{
ContractAddress: "0x12312323323233",
ChainID: 6,
ShowcaseVisibility: ProfileShowcaseVisibilityContacts,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityContacts,
Order: 1,
},
},
@ -229,32 +214,32 @@ func (s *TestMessengerProfileShowcase) TestSaveAndGetProfileShowcasePreferences(
}
func (s *TestMessengerProfileShowcase) TestFailToSaveProfileShowcasePreferencesWithWrongVisibility() {
accountEntry := &ProfileShowcaseAccountPreference{
accountEntry := &identity.ProfileShowcaseAccountPreference{
Address: "0x32433445133424",
Name: "Status Account",
ColorID: "blue",
Emoji: ">:-]",
ShowcaseVisibility: ProfileShowcaseVisibilityIDVerifiedContacts,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityIDVerifiedContacts,
Order: 17,
}
collectibleEntry := &ProfileShowcaseCollectiblePreference{
collectibleEntry := &identity.ProfileShowcaseCollectiblePreference{
ContractAddress: "0x12378534257568678487683576",
ChainID: 8,
TokenID: "0x12321389592999f903",
CommunityID: "0x01312357798976535",
AccountAddress: "0x32433445133424",
ShowcaseVisibility: ProfileShowcaseVisibilityContacts,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityContacts,
Order: 17,
}
request := &ProfileShowcasePreferences{
Accounts: []*ProfileShowcaseAccountPreference{accountEntry},
Collectibles: []*ProfileShowcaseCollectiblePreference{collectibleEntry},
request := &identity.ProfileShowcasePreferences{
Accounts: []*identity.ProfileShowcaseAccountPreference{accountEntry},
Collectibles: []*identity.ProfileShowcaseCollectiblePreference{collectibleEntry},
}
err := s.m.SetProfileShowcasePreferences(request)
s.Require().Equal(errorAccountVisibilityLowerThanCollectible, err)
s.Require().Equal(identity.ErrorAccountVisibilityLowerThanCollectible, err)
}
func (s *TestMessengerProfileShowcase) TestEncryptAndDecryptProfileShowcaseEntries() {
@ -407,7 +392,7 @@ func (s *TestMessengerProfileShowcase) TestShareShowcasePreferences() {
resp, err := WaitOnMessengerResponse(
mutualContact,
func(r *MessengerResponse) bool {
return len(r.updatedProfileShowcases) > 0 && r.updatedProfileShowcases[contactID] != nil && len(r.updatedProfileShowcases[contactID].Communities) == 2
return len(r.updatedProfileShowcases) > 0 && r.updatedProfileShowcases[contactID] != nil
},
"no messages",
)
@ -416,12 +401,6 @@ func (s *TestMessengerProfileShowcase) TestShareShowcasePreferences() {
profileShowcase := resp.updatedProfileShowcases[contactID]
s.Require().Len(profileShowcase.Communities, 2)
s.Require().Equal(profileShowcase.Communities[0].CommunityID, request.Communities[0].CommunityID)
s.Require().Equal(profileShowcase.Communities[0].Order, request.Communities[0].Order)
s.Require().Equal(profileShowcase.Communities[1].CommunityID, request.Communities[1].CommunityID)
s.Require().Equal(profileShowcase.Communities[1].Order, request.Communities[1].Order)
s.Require().Len(profileShowcase.Accounts, 2)
s.Require().Equal(profileShowcase.Accounts[0].Address, request.Accounts[0].Address)
s.Require().Equal(profileShowcase.Accounts[0].Name, request.Accounts[0].Name)
@ -469,15 +448,6 @@ func (s *TestMessengerProfileShowcase) TestShareShowcasePreferences() {
profileShowcase, err = verifiedContact.GetProfileShowcaseForContact(contactID)
s.Require().NoError(err)
s.Require().Len(profileShowcase.Communities, 3)
s.Require().Equal(profileShowcase.Communities[0].CommunityID, request.Communities[0].CommunityID)
s.Require().Equal(profileShowcase.Communities[0].Order, request.Communities[0].Order)
s.Require().Equal(profileShowcase.Communities[1].CommunityID, request.Communities[1].CommunityID)
s.Require().Equal(profileShowcase.Communities[1].Order, request.Communities[1].Order)
s.Require().Equal(profileShowcase.Communities[2].CommunityID, request.Communities[2].CommunityID)
s.Require().Equal(profileShowcase.Communities[2].Order, request.Communities[2].Order)
s.Require().Len(profileShowcase.Accounts, 2)
s.Require().Equal(profileShowcase.Accounts[0].Address, request.Accounts[0].Address)
s.Require().Equal(profileShowcase.Accounts[0].Name, request.Accounts[0].Name)
@ -511,3 +481,140 @@ func (s *TestMessengerProfileShowcase) TestShareShowcasePreferences() {
s.Require().Equal(profileShowcase.UnverifiedTokens[1].ChainID, request.UnverifiedTokens[1].ChainID)
s.Require().Equal(profileShowcase.UnverifiedTokens[1].Order, request.UnverifiedTokens[1].Order)
}
func (s *TestMessengerProfileShowcase) TestProfileShowcaseProofOfMembershipUnencryptedCommunities() {
alice := s.m
// Set Display name to pass shouldPublishChatIdentity check
profileKp := accounts.GetProfileKeypairForTest(true, false, false)
profileKp.KeyUID = alice.account.KeyUID
profileKp.Accounts[0].KeyUID = alice.account.KeyUID
err := alice.settings.SaveOrUpdateKeypair(profileKp)
s.Require().NoError(err)
err = alice.SetDisplayName("Alice")
s.Require().NoError(err)
// Add bob as a mutual contact
bob := s.newMessenger()
_, err = bob.Start()
s.Require().NoError(err)
defer TearDownMessenger(&s.Suite, bob)
s.mutualContact(bob)
// Alice creates a community
aliceCommunity, _ := createCommunityConfigurable(&s.Suite, alice, protobuf.CommunityPermissions_MANUAL_ACCEPT)
advertiseCommunityTo(&s.Suite, aliceCommunity, alice, bob)
// Bobs creates an another community
bobCommunity, _ := createCommunityConfigurable(&s.Suite, bob, protobuf.CommunityPermissions_AUTO_ACCEPT)
// Add community to the Alice's profile showcase & get it on the Bob's side
err = alice.SetProfileShowcasePreferences(&identity.ProfileShowcasePreferences{
Communities: []*identity.ProfileShowcaseCommunityPreference{
&identity.ProfileShowcaseCommunityPreference{
CommunityID: aliceCommunity.IDString(),
ShowcaseVisibility: identity.ProfileShowcaseVisibilityContacts,
Order: 0,
},
&identity.ProfileShowcaseCommunityPreference{
CommunityID: bobCommunity.IDString(),
ShowcaseVisibility: identity.ProfileShowcaseVisibilityEveryone,
Order: 2,
},
},
})
s.Require().NoError(err)
contactID := types.EncodeHex(crypto.FromECDSAPub(&alice.identity.PublicKey))
resp, err := WaitOnMessengerResponse(
bob,
func(r *MessengerResponse) bool {
return len(r.updatedProfileShowcases) > 0 && r.updatedProfileShowcases[contactID] != nil
},
"no messages",
)
s.Require().NoError(err)
s.Require().Len(resp.updatedProfileShowcases, 1)
profileShowcase := resp.updatedProfileShowcases[contactID]
// Verify community's data
s.Require().Len(profileShowcase.Communities, 2)
s.Require().Equal(profileShowcase.Communities[0].CommunityID, aliceCommunity.IDString())
s.Require().Equal(profileShowcase.Communities[0].MembershipStatus, identity.ProfileShowcaseMembershipStatusProvenMember)
s.Require().Equal(profileShowcase.Communities[1].CommunityID, bobCommunity.IDString())
s.Require().Equal(profileShowcase.Communities[1].MembershipStatus, identity.ProfileShowcaseMembershipStatusNotAMember)
}
func (s *TestMessengerProfileShowcase) TestProfileShowcaseProofOfMembershipEncryptedCommunity() {
alice := s.m
// Set Display name to pass shouldPublishChatIdentity check
profileKp := accounts.GetProfileKeypairForTest(true, false, false)
profileKp.KeyUID = alice.account.KeyUID
profileKp.Accounts[0].KeyUID = alice.account.KeyUID
err := alice.settings.SaveOrUpdateKeypair(profileKp)
s.Require().NoError(err)
err = alice.SetDisplayName("Alice")
s.Require().NoError(err)
// Add bob as a mutual contact
bob := s.newMessenger()
_, err = bob.Start()
s.Require().NoError(err)
defer TearDownMessenger(&s.Suite, bob)
s.mutualContact(bob)
// Alice creates an ecrypted community
aliceCommunity, _ := createEncryptedCommunity(&s.Suite, alice)
s.Require().True(aliceCommunity.Encrypted())
advertiseCommunityTo(&s.Suite, aliceCommunity, alice, bob)
// Bob creates an another encryped community
bobCommunity, _ := createEncryptedCommunity(&s.Suite, bob)
s.Require().True(bobCommunity.Encrypted())
advertiseCommunityTo(&s.Suite, bobCommunity, bob, alice)
// Add community to the Alice's profile showcase & get it on the Bob's side
err = alice.SetProfileShowcasePreferences(&identity.ProfileShowcasePreferences{
Communities: []*identity.ProfileShowcaseCommunityPreference{
&identity.ProfileShowcaseCommunityPreference{
CommunityID: aliceCommunity.IDString(),
ShowcaseVisibility: identity.ProfileShowcaseVisibilityContacts,
Order: 0,
},
&identity.ProfileShowcaseCommunityPreference{
CommunityID: bobCommunity.IDString(),
ShowcaseVisibility: identity.ProfileShowcaseVisibilityEveryone,
Order: 1,
},
},
})
s.Require().NoError(err)
contactID := types.EncodeHex(crypto.FromECDSAPub(&alice.identity.PublicKey))
resp, err := WaitOnMessengerResponse(
bob,
func(r *MessengerResponse) bool {
return len(r.updatedProfileShowcases) > 0 && r.updatedProfileShowcases[contactID] != nil
},
"no messages",
)
s.Require().NoError(err)
s.Require().Len(resp.updatedProfileShowcases, 1)
profileShowcase := resp.updatedProfileShowcases[contactID]
// Verify community's data
s.Require().Len(profileShowcase.Communities, 2)
s.Require().Equal(profileShowcase.Communities[0].CommunityID, aliceCommunity.IDString())
s.Require().Equal(profileShowcase.Communities[0].MembershipStatus, identity.ProfileShowcaseMembershipStatusProvenMember)
s.Require().Equal(profileShowcase.Communities[1].CommunityID, bobCommunity.IDString())
s.Require().Equal(profileShowcase.Communities[1].MembershipStatus, identity.ProfileShowcaseMembershipStatusNotAMember)
}

View File

@ -88,7 +88,7 @@ type MessengerResponse struct {
savedAddresses map[string]*wallet.SavedAddress
SocialLinksInfo *identity.SocialLinksInfo
ensUsernameDetails []*ensservice.UsernameDetail
updatedProfileShowcases map[string]*ProfileShowcase
updatedProfileShowcases map[string]*identity.ProfileShowcase
seenAndUnseenMessages map[string]*SeenUnseenMessages
}
@ -135,7 +135,7 @@ func (r *MessengerResponse) MarshalJSON() ([]byte, error) {
SavedAddresses []*wallet.SavedAddress `json:"savedAddresses,omitempty"`
SocialLinksInfo *identity.SocialLinksInfo `json:"socialLinksInfo,omitempty"`
EnsUsernameDetails []*ensservice.UsernameDetail `json:"ensUsernameDetails,omitempty"`
UpdatedProfileShowcases []*ProfileShowcase `json:"updatedProfileShowcases,omitempty"`
UpdatedProfileShowcases []*identity.ProfileShowcase `json:"updatedProfileShowcases,omitempty"`
SeenAndUnseenMessages []*SeenUnseenMessages `json:"seenAndUnseenMessages,omitempty"`
}{
Contacts: r.Contacts,
@ -823,22 +823,22 @@ func (r *MessengerResponse) HasDiscordChannel(id string) bool {
return false
}
func (r *MessengerResponse) AddProfileShowcases(showcases []*ProfileShowcase) {
func (r *MessengerResponse) AddProfileShowcases(showcases []*identity.ProfileShowcase) {
for _, showcase := range showcases {
r.AddProfileShowcase(showcase)
}
}
func (r *MessengerResponse) AddProfileShowcase(showcase *ProfileShowcase) {
func (r *MessengerResponse) AddProfileShowcase(showcase *identity.ProfileShowcase) {
if r.updatedProfileShowcases == nil {
r.updatedProfileShowcases = make(map[string]*ProfileShowcase)
r.updatedProfileShowcases = make(map[string]*identity.ProfileShowcase)
}
r.updatedProfileShowcases[showcase.ContactID] = showcase
}
func (r *MessengerResponse) GetUpdatedProfileShowcases() []*ProfileShowcase {
var showcases []*ProfileShowcase
func (r *MessengerResponse) GetUpdatedProfileShowcases() []*identity.ProfileShowcase {
var showcases []*identity.ProfileShowcase
for _, showcase := range r.updatedProfileShowcases {
showcases = append(showcases, showcase)
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
CREATE TABLE IF NOT EXISTS community_grants (
community_id TEXT PRIMARY KEY NOT NULL,
grant TEXT DEFAULT "",
clock INT NOT NULL DEFAULT 0
);

View File

@ -4,15 +4,8 @@ import (
"context"
"database/sql"
"errors"
)
type ProfileShowcaseVisibility int
const (
ProfileShowcaseVisibilityNoOne ProfileShowcaseVisibility = iota
ProfileShowcaseVisibilityIDVerifiedContacts
ProfileShowcaseVisibilityContacts
ProfileShowcaseVisibilityEveryone
"github.com/status-im/status-go/protocol/identity"
)
const upsertProfileShowcaseCommunityPreferenceQuery = "INSERT OR REPLACE INTO profile_showcase_communities_preferences(community_id, visibility, sort_order) VALUES (?, ?, ?)" // #nosec G101
@ -65,99 +58,8 @@ WHERE
psa.address = ?
`
type ProfileShowcaseCommunityPreference struct {
CommunityID string `json:"communityId"`
ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"`
Order int `json:"order"`
}
type ProfileShowcaseAccountPreference struct {
Address string `json:"address"`
Name string `json:"name"`
ColorID string `json:"colorId"`
Emoji string `json:"emoji"`
ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"`
Order int `json:"order"`
}
type ProfileShowcaseCollectiblePreference struct {
ContractAddress string `json:"contractAddress"`
ChainID uint64 `json:"chainId"`
TokenID string `json:"tokenId"`
CommunityID string `json:"communityId"`
AccountAddress string `json:"accountAddress"`
ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"`
Order int `json:"order"`
}
type ProfileShowcaseVerifiedTokenPreference struct {
Symbol string `json:"symbol"`
ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"`
Order int `json:"order"`
}
type ProfileShowcaseUnverifiedTokenPreference struct {
ContractAddress string `json:"contractAddress"`
ChainID uint64 `json:"chainId"`
CommunityID string `json:"communityId"`
ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"`
Order int `json:"order"`
}
type ProfileShowcasePreferences struct {
Communities []*ProfileShowcaseCommunityPreference `json:"communities"`
Accounts []*ProfileShowcaseAccountPreference `json:"accounts"`
Collectibles []*ProfileShowcaseCollectiblePreference `json:"collectibles"`
VerifiedTokens []*ProfileShowcaseVerifiedTokenPreference `json:"verifiedTokens"`
UnverifiedTokens []*ProfileShowcaseUnverifiedTokenPreference `json:"unverifiedTokens"`
}
type ProfileShowcaseCommunity struct {
CommunityID string `json:"communityId"`
Order int `json:"order"`
}
type ProfileShowcaseAccount struct {
ContactID string `json:"contactId"`
Address string `json:"address"`
Name string `json:"name"`
ColorID string `json:"colorId"`
Emoji string `json:"emoji"`
Order int `json:"order"`
}
type ProfileShowcaseCollectible struct {
ContractAddress string `json:"contractAddress"`
ChainID uint64 `json:"chainId"`
TokenID string `json:"tokenId"`
CommunityID string `json:"communityId"`
AccountAddress string `json:"accountAddress"`
Order int `json:"order"`
}
type ProfileShowcaseVerifiedToken struct {
Symbol string `json:"symbol"`
Order int `json:"order"`
}
type ProfileShowcaseUnverifiedToken struct {
ContractAddress string `json:"contractAddress"`
ChainID uint64 `json:"chainId"`
CommunityID string `json:"communityId"`
Order int `json:"order"`
}
type ProfileShowcase struct {
ContactID string `json:"contactId"`
Communities []*ProfileShowcaseCommunity `json:"communities"`
Accounts []*ProfileShowcaseAccount `json:"accounts"`
Collectibles []*ProfileShowcaseCollectible `json:"collectibles"`
VerifiedTokens []*ProfileShowcaseVerifiedToken `json:"verifiedTokens"`
UnverifiedTokens []*ProfileShowcaseUnverifiedToken `json:"unverifiedTokens"`
}
// Queries for showcase preferences
func (db sqlitePersistence) saveProfileShowcaseCommunityPreference(tx *sql.Tx, community *ProfileShowcaseCommunityPreference) error {
func (db sqlitePersistence) saveProfileShowcaseCommunityPreference(tx *sql.Tx, community *identity.ProfileShowcaseCommunityPreference) error {
_, err := tx.Exec(upsertProfileShowcaseCommunityPreferenceQuery,
community.CommunityID,
community.ShowcaseVisibility,
@ -167,16 +69,16 @@ func (db sqlitePersistence) saveProfileShowcaseCommunityPreference(tx *sql.Tx, c
return err
}
func (db sqlitePersistence) getProfileShowcaseCommunitiesPreferences(tx *sql.Tx) ([]*ProfileShowcaseCommunityPreference, error) {
func (db sqlitePersistence) getProfileShowcaseCommunitiesPreferences(tx *sql.Tx) ([]*identity.ProfileShowcaseCommunityPreference, error) {
rows, err := tx.Query(selectProfileShowcaseCommunityPreferenceQuery)
if err != nil {
return nil, err
}
communities := []*ProfileShowcaseCommunityPreference{}
communities := []*identity.ProfileShowcaseCommunityPreference{}
for rows.Next() {
community := &ProfileShowcaseCommunityPreference{}
community := &identity.ProfileShowcaseCommunityPreference{}
err := rows.Scan(
&community.CommunityID,
@ -193,7 +95,7 @@ func (db sqlitePersistence) getProfileShowcaseCommunitiesPreferences(tx *sql.Tx)
return communities, nil
}
func (db sqlitePersistence) saveProfileShowcaseAccountPreference(tx *sql.Tx, account *ProfileShowcaseAccountPreference) error {
func (db sqlitePersistence) saveProfileShowcaseAccountPreference(tx *sql.Tx, account *identity.ProfileShowcaseAccountPreference) error {
_, err := tx.Exec(upsertProfileShowcaseAccountPreferenceQuery,
account.Address,
account.Name,
@ -206,13 +108,13 @@ func (db sqlitePersistence) saveProfileShowcaseAccountPreference(tx *sql.Tx, acc
return err
}
func (db sqlitePersistence) processProfileShowcaseAccountPreferences(rows *sql.Rows) (result []*ProfileShowcaseAccountPreference, err error) {
func (db sqlitePersistence) processProfileShowcaseAccountPreferences(rows *sql.Rows) (result []*identity.ProfileShowcaseAccountPreference, err error) {
if rows == nil {
return nil, errors.New("rows is nil")
}
for rows.Next() {
account := &ProfileShowcaseAccountPreference{}
account := &identity.ProfileShowcaseAccountPreference{}
err := rows.Scan(
&account.Address,
@ -234,7 +136,7 @@ func (db sqlitePersistence) processProfileShowcaseAccountPreferences(rows *sql.R
return
}
func (db sqlitePersistence) getProfileShowcaseAccountsPreferences(tx *sql.Tx) ([]*ProfileShowcaseAccountPreference, error) {
func (db sqlitePersistence) getProfileShowcaseAccountsPreferences(tx *sql.Tx) ([]*identity.ProfileShowcaseAccountPreference, error) {
rows, err := tx.Query(selectProfileShowcaseAccountPreferenceQuery)
if err != nil {
return nil, err
@ -243,7 +145,7 @@ func (db sqlitePersistence) getProfileShowcaseAccountsPreferences(tx *sql.Tx) ([
return db.processProfileShowcaseAccountPreferences(rows)
}
func (db sqlitePersistence) GetProfileShowcaseAccountPreference(accountAddress string) (*ProfileShowcaseAccountPreference, error) {
func (db sqlitePersistence) GetProfileShowcaseAccountPreference(accountAddress string) (*identity.ProfileShowcaseAccountPreference, error) {
rows, err := db.db.Query(selectSpecifiedShowcaseAccountPreferenceQuery, accountAddress)
if err != nil {
return nil, err
@ -276,7 +178,7 @@ func (db sqlitePersistence) DeleteProfileShowcaseCommunityPreference(communityID
return rows > 0, err
}
func (db sqlitePersistence) saveProfileShowcaseCollectiblePreference(tx *sql.Tx, collectible *ProfileShowcaseCollectiblePreference) error {
func (db sqlitePersistence) saveProfileShowcaseCollectiblePreference(tx *sql.Tx, collectible *identity.ProfileShowcaseCollectiblePreference) error {
_, err := tx.Exec(upsertProfileShowcaseCollectiblePreferenceQuery,
collectible.ContractAddress,
collectible.ChainID,
@ -290,16 +192,16 @@ func (db sqlitePersistence) saveProfileShowcaseCollectiblePreference(tx *sql.Tx,
return err
}
func (db sqlitePersistence) getProfileShowcaseCollectiblesPreferences(tx *sql.Tx) ([]*ProfileShowcaseCollectiblePreference, error) {
func (db sqlitePersistence) getProfileShowcaseCollectiblesPreferences(tx *sql.Tx) ([]*identity.ProfileShowcaseCollectiblePreference, error) {
rows, err := tx.Query(selectProfileShowcaseCollectiblePreferenceQuery)
if err != nil {
return nil, err
}
collectibles := []*ProfileShowcaseCollectiblePreference{}
collectibles := []*identity.ProfileShowcaseCollectiblePreference{}
for rows.Next() {
collectible := &ProfileShowcaseCollectiblePreference{}
collectible := &identity.ProfileShowcaseCollectiblePreference{}
err := rows.Scan(
&collectible.ContractAddress,
@ -320,7 +222,7 @@ func (db sqlitePersistence) getProfileShowcaseCollectiblesPreferences(tx *sql.Tx
return collectibles, nil
}
func (db sqlitePersistence) saveProfileShowcaseVerifiedTokenPreference(tx *sql.Tx, token *ProfileShowcaseVerifiedTokenPreference) error {
func (db sqlitePersistence) saveProfileShowcaseVerifiedTokenPreference(tx *sql.Tx, token *identity.ProfileShowcaseVerifiedTokenPreference) error {
_, err := tx.Exec(upsertProfileShowcaseVerifiedTokenPreferenceQuery,
token.Symbol,
token.ShowcaseVisibility,
@ -330,7 +232,7 @@ func (db sqlitePersistence) saveProfileShowcaseVerifiedTokenPreference(tx *sql.T
return err
}
func (db sqlitePersistence) saveProfileShowcaseUnverifiedTokenPreference(tx *sql.Tx, token *ProfileShowcaseUnverifiedTokenPreference) error {
func (db sqlitePersistence) saveProfileShowcaseUnverifiedTokenPreference(tx *sql.Tx, token *identity.ProfileShowcaseUnverifiedTokenPreference) error {
_, err := tx.Exec(upsertProfileShowcaseUnverifiedTokenPreferenceQuery,
token.ContractAddress,
token.ChainID,
@ -342,16 +244,16 @@ func (db sqlitePersistence) saveProfileShowcaseUnverifiedTokenPreference(tx *sql
return err
}
func (db sqlitePersistence) getProfileShowcaseVerifiedTokensPreferences(tx *sql.Tx) ([]*ProfileShowcaseVerifiedTokenPreference, error) {
func (db sqlitePersistence) getProfileShowcaseVerifiedTokensPreferences(tx *sql.Tx) ([]*identity.ProfileShowcaseVerifiedTokenPreference, error) {
rows, err := tx.Query(selectProfileShowcaseVerifiedTokenPreferenceQuery)
if err != nil {
return nil, err
}
tokens := []*ProfileShowcaseVerifiedTokenPreference{}
tokens := []*identity.ProfileShowcaseVerifiedTokenPreference{}
for rows.Next() {
token := &ProfileShowcaseVerifiedTokenPreference{}
token := &identity.ProfileShowcaseVerifiedTokenPreference{}
err := rows.Scan(
&token.Symbol,
@ -368,16 +270,16 @@ func (db sqlitePersistence) getProfileShowcaseVerifiedTokensPreferences(tx *sql.
return tokens, nil
}
func (db sqlitePersistence) getProfileShowcaseUnverifiedTokensPreferences(tx *sql.Tx) ([]*ProfileShowcaseUnverifiedTokenPreference, error) {
func (db sqlitePersistence) getProfileShowcaseUnverifiedTokensPreferences(tx *sql.Tx) ([]*identity.ProfileShowcaseUnverifiedTokenPreference, error) {
rows, err := tx.Query(selectProfileShowcaseUnverifiedTokenPreferenceQuery)
if err != nil {
return nil, err
}
tokens := []*ProfileShowcaseUnverifiedTokenPreference{}
tokens := []*identity.ProfileShowcaseUnverifiedTokenPreference{}
for rows.Next() {
token := &ProfileShowcaseUnverifiedTokenPreference{}
token := &identity.ProfileShowcaseUnverifiedTokenPreference{}
err := rows.Scan(
&token.ContractAddress,
@ -397,7 +299,7 @@ func (db sqlitePersistence) getProfileShowcaseUnverifiedTokensPreferences(tx *sq
}
// Queries for contacts showcase
func (db sqlitePersistence) saveProfileShowcaseCommunityContact(tx *sql.Tx, contactID string, community *ProfileShowcaseCommunity) error {
func (db sqlitePersistence) saveProfileShowcaseCommunityContact(tx *sql.Tx, contactID string, community *identity.ProfileShowcaseCommunity) error {
_, err := tx.Exec(upsertContactProfileShowcaseCommunityQuery,
contactID,
community.CommunityID,
@ -407,16 +309,18 @@ func (db sqlitePersistence) saveProfileShowcaseCommunityContact(tx *sql.Tx, cont
return err
}
func (db sqlitePersistence) getProfileShowcaseCommunitiesContact(tx *sql.Tx, contactID string) ([]*ProfileShowcaseCommunity, error) {
func (db sqlitePersistence) getProfileShowcaseCommunitiesContact(tx *sql.Tx, contactID string) ([]*identity.ProfileShowcaseCommunity, error) {
rows, err := tx.Query(selectContactProfileShowcaseCommunityQuery, contactID)
if err != nil {
return nil, err
}
communities := []*ProfileShowcaseCommunity{}
communities := []*identity.ProfileShowcaseCommunity{}
for rows.Next() {
community := &ProfileShowcaseCommunity{}
community := &identity.ProfileShowcaseCommunity{
MembershipStatus: identity.ProfileShowcaseMembershipStatusUnproven,
}
err := rows.Scan(&community.CommunityID, &community.Order)
if err != nil {
@ -437,7 +341,7 @@ func (db sqlitePersistence) clearProfileShowcaseCommunityContact(tx *sql.Tx, con
return nil
}
func (db sqlitePersistence) saveProfileShowcaseAccountContact(tx *sql.Tx, contactID string, account *ProfileShowcaseAccount) error {
func (db sqlitePersistence) saveProfileShowcaseAccountContact(tx *sql.Tx, contactID string, account *identity.ProfileShowcaseAccount) error {
_, err := tx.Exec(upsertContactProfileShowcaseAccountQuery,
contactID,
account.Address,
@ -450,13 +354,13 @@ func (db sqlitePersistence) saveProfileShowcaseAccountContact(tx *sql.Tx, contac
return err
}
func (db sqlitePersistence) processProfileShowcaseAccounts(rows *sql.Rows) (result []*ProfileShowcaseAccount, err error) {
func (db sqlitePersistence) processProfileShowcaseAccounts(rows *sql.Rows) (result []*identity.ProfileShowcaseAccount, err error) {
if rows == nil {
return nil, errors.New("rows is nil")
}
for rows.Next() {
account := &ProfileShowcaseAccount{}
account := &identity.ProfileShowcaseAccount{}
err = rows.Scan(&account.Address, &account.Name, &account.ColorID, &account.Emoji, &account.Order, &account.ContactID)
if err != nil {
@ -470,7 +374,7 @@ func (db sqlitePersistence) processProfileShowcaseAccounts(rows *sql.Rows) (resu
return
}
func (db sqlitePersistence) getProfileShowcaseAccountsContact(tx *sql.Tx, contactID string) ([]*ProfileShowcaseAccount, error) {
func (db sqlitePersistence) getProfileShowcaseAccountsContact(tx *sql.Tx, contactID string) ([]*identity.ProfileShowcaseAccount, error) {
rows, err := tx.Query(selectContactProfileShowcaseAccountQuery, contactID)
if err != nil {
return nil, err
@ -479,7 +383,7 @@ func (db sqlitePersistence) getProfileShowcaseAccountsContact(tx *sql.Tx, contac
return db.processProfileShowcaseAccounts(rows)
}
func (db sqlitePersistence) GetProfileShowcaseAccountsByAddress(address string) ([]*ProfileShowcaseAccount, error) {
func (db sqlitePersistence) GetProfileShowcaseAccountsByAddress(address string) ([]*identity.ProfileShowcaseAccount, error) {
rows, err := db.db.Query(selectProfileShowcaseAccountsWhichMatchTheAddress, address)
if err != nil {
return nil, err
@ -493,7 +397,7 @@ func (db sqlitePersistence) clearProfileShowcaseAccountsContact(tx *sql.Tx, cont
return err
}
func (db sqlitePersistence) saveProfileShowcaseCollectibleContact(tx *sql.Tx, contactID string, collectible *ProfileShowcaseCollectible) error {
func (db sqlitePersistence) saveProfileShowcaseCollectibleContact(tx *sql.Tx, contactID string, collectible *identity.ProfileShowcaseCollectible) error {
_, err := tx.Exec(upsertContactProfileShowcaseCollectibleQuery,
contactID,
collectible.ContractAddress,
@ -507,16 +411,16 @@ func (db sqlitePersistence) saveProfileShowcaseCollectibleContact(tx *sql.Tx, co
return err
}
func (db sqlitePersistence) getProfileShowcaseCollectiblesContact(tx *sql.Tx, contactID string) ([]*ProfileShowcaseCollectible, error) {
func (db sqlitePersistence) getProfileShowcaseCollectiblesContact(tx *sql.Tx, contactID string) ([]*identity.ProfileShowcaseCollectible, error) {
rows, err := tx.Query(selectContactProfileShowcaseCollectibleQuery, contactID)
if err != nil {
return nil, err
}
collectibles := []*ProfileShowcaseCollectible{}
collectibles := []*identity.ProfileShowcaseCollectible{}
for rows.Next() {
collectible := &ProfileShowcaseCollectible{}
collectible := &identity.ProfileShowcaseCollectible{}
err := rows.Scan(
&collectible.ContractAddress,
@ -539,7 +443,7 @@ func (db sqlitePersistence) clearProfileShowcaseCollectiblesContact(tx *sql.Tx,
return err
}
func (db sqlitePersistence) saveProfileShowcaseVerifiedTokenContact(tx *sql.Tx, contactID string, token *ProfileShowcaseVerifiedToken) error {
func (db sqlitePersistence) saveProfileShowcaseVerifiedTokenContact(tx *sql.Tx, contactID string, token *identity.ProfileShowcaseVerifiedToken) error {
_, err := tx.Exec(upsertContactProfileShowcaseVerifiedTokenQuery,
contactID,
token.Symbol,
@ -549,7 +453,7 @@ func (db sqlitePersistence) saveProfileShowcaseVerifiedTokenContact(tx *sql.Tx,
return err
}
func (db sqlitePersistence) saveProfileShowcaseUnverifiedTokenContact(tx *sql.Tx, contactID string, token *ProfileShowcaseUnverifiedToken) error {
func (db sqlitePersistence) saveProfileShowcaseUnverifiedTokenContact(tx *sql.Tx, contactID string, token *identity.ProfileShowcaseUnverifiedToken) error {
_, err := tx.Exec(upsertContactProfileShowcaseUnverifiedTokenQuery,
contactID,
token.ContractAddress,
@ -561,16 +465,16 @@ func (db sqlitePersistence) saveProfileShowcaseUnverifiedTokenContact(tx *sql.Tx
return err
}
func (db sqlitePersistence) getProfileShowcaseVerifiedTokensContact(tx *sql.Tx, contactID string) ([]*ProfileShowcaseVerifiedToken, error) {
func (db sqlitePersistence) getProfileShowcaseVerifiedTokensContact(tx *sql.Tx, contactID string) ([]*identity.ProfileShowcaseVerifiedToken, error) {
rows, err := tx.Query(selectContactProfileShowcaseVerifiedTokenQuery, contactID)
if err != nil {
return nil, err
}
tokens := []*ProfileShowcaseVerifiedToken{}
tokens := []*identity.ProfileShowcaseVerifiedToken{}
for rows.Next() {
token := &ProfileShowcaseVerifiedToken{}
token := &identity.ProfileShowcaseVerifiedToken{}
err := rows.Scan(
&token.Symbol,
@ -584,16 +488,16 @@ func (db sqlitePersistence) getProfileShowcaseVerifiedTokensContact(tx *sql.Tx,
return tokens, nil
}
func (db sqlitePersistence) getProfileShowcaseUnverifiedTokensContact(tx *sql.Tx, contactID string) ([]*ProfileShowcaseUnverifiedToken, error) {
func (db sqlitePersistence) getProfileShowcaseUnverifiedTokensContact(tx *sql.Tx, contactID string) ([]*identity.ProfileShowcaseUnverifiedToken, error) {
rows, err := tx.Query(selectContactProfileShowcaseUnverifiedTokenQuery, contactID)
if err != nil {
return nil, err
}
tokens := []*ProfileShowcaseUnverifiedToken{}
tokens := []*identity.ProfileShowcaseUnverifiedToken{}
for rows.Next() {
token := &ProfileShowcaseUnverifiedToken{}
token := &identity.ProfileShowcaseUnverifiedToken{}
err := rows.Scan(
&token.ContractAddress,
@ -620,7 +524,7 @@ func (db sqlitePersistence) clearProfileShowcaseUnverifiedTokensContact(tx *sql.
}
// public functions
func (db sqlitePersistence) SaveProfileShowcasePreferences(preferences *ProfileShowcasePreferences) error {
func (db sqlitePersistence) SaveProfileShowcasePreferences(preferences *identity.ProfileShowcasePreferences) error {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return err
@ -672,7 +576,7 @@ func (db sqlitePersistence) SaveProfileShowcasePreferences(preferences *ProfileS
return nil
}
func (db sqlitePersistence) SaveProfileShowcaseAccountPreference(account *ProfileShowcaseAccountPreference) error {
func (db sqlitePersistence) SaveProfileShowcaseAccountPreference(account *identity.ProfileShowcaseAccountPreference) error {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return err
@ -688,7 +592,7 @@ func (db sqlitePersistence) SaveProfileShowcaseAccountPreference(account *Profil
return db.saveProfileShowcaseAccountPreference(tx, account)
}
func (db sqlitePersistence) GetProfileShowcasePreferences() (*ProfileShowcasePreferences, error) {
func (db sqlitePersistence) GetProfileShowcasePreferences() (*identity.ProfileShowcasePreferences, error) {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return nil, err
@ -727,7 +631,7 @@ func (db sqlitePersistence) GetProfileShowcasePreferences() (*ProfileShowcasePre
return nil, err
}
return &ProfileShowcasePreferences{
return &identity.ProfileShowcasePreferences{
Communities: communities,
Accounts: accounts,
Collectibles: collectibles,
@ -736,7 +640,7 @@ func (db sqlitePersistence) GetProfileShowcasePreferences() (*ProfileShowcasePre
}, nil
}
func (db sqlitePersistence) SaveProfileShowcaseForContact(showcase *ProfileShowcase) error {
func (db sqlitePersistence) SaveProfileShowcaseForContact(showcase *identity.ProfileShowcase) error {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return err
@ -788,7 +692,7 @@ func (db sqlitePersistence) SaveProfileShowcaseForContact(showcase *ProfileShowc
return nil
}
func (db sqlitePersistence) GetProfileShowcaseForContact(contactID string) (*ProfileShowcase, error) {
func (db sqlitePersistence) GetProfileShowcaseForContact(contactID string) (*identity.ProfileShowcase, error) {
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
if err != nil {
return nil, err
@ -827,7 +731,7 @@ func (db sqlitePersistence) GetProfileShowcaseForContact(contactID string) (*Pro
return nil, err
}
return &ProfileShowcase{
return &identity.ProfileShowcase{
ContactID: contactID,
Communities: communities,
Accounts: accounts,

View File

@ -4,6 +4,8 @@ import (
"testing"
"github.com/stretchr/testify/suite"
"github.com/status-im/status-go/protocol/identity"
)
func TestProfileShowcasePersistenceSuite(t *testing.T) {
@ -19,73 +21,73 @@ func (s *TestProfileShowcasePersistence) TestProfileShowcasePreferences() {
s.Require().NoError(err)
persistence := newSQLitePersistence(db)
preferences := &ProfileShowcasePreferences{
Communities: []*ProfileShowcaseCommunityPreference{
&ProfileShowcaseCommunityPreference{
preferences := &identity.ProfileShowcasePreferences{
Communities: []*identity.ProfileShowcaseCommunityPreference{
&identity.ProfileShowcaseCommunityPreference{
CommunityID: "0x32433445133424",
ShowcaseVisibility: ProfileShowcaseVisibilityEveryone,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityEveryone,
Order: 0,
},
},
Accounts: []*ProfileShowcaseAccountPreference{
&ProfileShowcaseAccountPreference{
Accounts: []*identity.ProfileShowcaseAccountPreference{
&identity.ProfileShowcaseAccountPreference{
Address: "0x32433445133424",
Name: "Status Account",
ColorID: "blue",
Emoji: "-_-",
ShowcaseVisibility: ProfileShowcaseVisibilityEveryone,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityEveryone,
Order: 0,
},
&ProfileShowcaseAccountPreference{
&identity.ProfileShowcaseAccountPreference{
Address: "0x3845354643324",
Name: "Money Box",
ColorID: "red",
Emoji: ":o)",
ShowcaseVisibility: ProfileShowcaseVisibilityContacts,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityContacts,
Order: 1,
},
},
Collectibles: []*ProfileShowcaseCollectiblePreference{
&ProfileShowcaseCollectiblePreference{
Collectibles: []*identity.ProfileShowcaseCollectiblePreference{
&identity.ProfileShowcaseCollectiblePreference{
ContractAddress: "0x12378534257568678487683576",
ChainID: 3,
TokenID: "0x12321389592999f903",
CommunityID: "0x01312357798976535",
AccountAddress: "0x32433445133424",
ShowcaseVisibility: ProfileShowcaseVisibilityEveryone,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityEveryone,
Order: 0,
},
},
VerifiedTokens: []*ProfileShowcaseVerifiedTokenPreference{
&ProfileShowcaseVerifiedTokenPreference{
VerifiedTokens: []*identity.ProfileShowcaseVerifiedTokenPreference{
&identity.ProfileShowcaseVerifiedTokenPreference{
Symbol: "ETH",
ShowcaseVisibility: ProfileShowcaseVisibilityEveryone,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityEveryone,
Order: 1,
},
&ProfileShowcaseVerifiedTokenPreference{
&identity.ProfileShowcaseVerifiedTokenPreference{
Symbol: "DAI",
ShowcaseVisibility: ProfileShowcaseVisibilityIDVerifiedContacts,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityIDVerifiedContacts,
Order: 2,
},
&ProfileShowcaseVerifiedTokenPreference{
&identity.ProfileShowcaseVerifiedTokenPreference{
Symbol: "SNT",
ShowcaseVisibility: ProfileShowcaseVisibilityNoOne,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityNoOne,
Order: 3,
},
},
UnverifiedTokens: []*ProfileShowcaseUnverifiedTokenPreference{
&ProfileShowcaseUnverifiedTokenPreference{
UnverifiedTokens: []*identity.ProfileShowcaseUnverifiedTokenPreference{
&identity.ProfileShowcaseUnverifiedTokenPreference{
ContractAddress: "0x454525452023452",
ChainID: 1,
CommunityID: "0x32433445133424",
ShowcaseVisibility: ProfileShowcaseVisibilityEveryone,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityEveryone,
Order: 0,
},
&ProfileShowcaseUnverifiedTokenPreference{
&identity.ProfileShowcaseUnverifiedTokenPreference{
ContractAddress: "0x12312323323233",
ChainID: 2,
CommunityID: "",
ShowcaseVisibility: ProfileShowcaseVisibilityContacts,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityContacts,
Order: 1,
},
},
@ -128,20 +130,20 @@ func (s *TestProfileShowcasePersistence) TestProfileShowcaseContacts() {
s.Require().NoError(err)
persistence := newSQLitePersistence(db)
showcase1 := &ProfileShowcase{
showcase1 := &identity.ProfileShowcase{
ContactID: "contact_1",
Communities: []*ProfileShowcaseCommunity{
&ProfileShowcaseCommunity{
Communities: []*identity.ProfileShowcaseCommunity{
&identity.ProfileShowcaseCommunity{
CommunityID: "0x012312234234234",
Order: 6,
},
&ProfileShowcaseCommunity{
&identity.ProfileShowcaseCommunity{
CommunityID: "0x04523233466753",
Order: 7,
},
},
Accounts: []*ProfileShowcaseAccount{
&ProfileShowcaseAccount{
Accounts: []*identity.ProfileShowcaseAccount{
&identity.ProfileShowcaseAccount{
ContactID: "contact_1",
Address: "0x32433445133424",
Name: "Status Account",
@ -149,7 +151,7 @@ func (s *TestProfileShowcasePersistence) TestProfileShowcaseContacts() {
Emoji: "-_-",
Order: 0,
},
&ProfileShowcaseAccount{
&identity.ProfileShowcaseAccount{
ContactID: "contact_1",
Address: "0x3845354643324",
Name: "Money Box",
@ -158,8 +160,8 @@ func (s *TestProfileShowcasePersistence) TestProfileShowcaseContacts() {
Order: 1,
},
},
Collectibles: []*ProfileShowcaseCollectible{
&ProfileShowcaseCollectible{
Collectibles: []*identity.ProfileShowcaseCollectible{
&identity.ProfileShowcaseCollectible{
ContractAddress: "0x12378534257568678487683576",
ChainID: 2,
TokenID: "0x12321389592999f903",
@ -167,28 +169,28 @@ func (s *TestProfileShowcasePersistence) TestProfileShowcaseContacts() {
Order: 0,
},
},
VerifiedTokens: []*ProfileShowcaseVerifiedToken{
&ProfileShowcaseVerifiedToken{
VerifiedTokens: []*identity.ProfileShowcaseVerifiedToken{
&identity.ProfileShowcaseVerifiedToken{
Symbol: "ETH",
Order: 1,
},
&ProfileShowcaseVerifiedToken{
&identity.ProfileShowcaseVerifiedToken{
Symbol: "DAI",
Order: 2,
},
&ProfileShowcaseVerifiedToken{
&identity.ProfileShowcaseVerifiedToken{
Symbol: "SNT",
Order: 3,
},
},
UnverifiedTokens: []*ProfileShowcaseUnverifiedToken{
&ProfileShowcaseUnverifiedToken{
UnverifiedTokens: []*identity.ProfileShowcaseUnverifiedToken{
&identity.ProfileShowcaseUnverifiedToken{
ContractAddress: "0x454525452023452",
ChainID: 1,
CommunityID: "",
Order: 0,
},
&ProfileShowcaseUnverifiedToken{
&identity.ProfileShowcaseUnverifiedToken{
ContractAddress: "0x12312323323233",
ChainID: 2,
CommunityID: "0x32433445133424",
@ -199,20 +201,20 @@ func (s *TestProfileShowcasePersistence) TestProfileShowcaseContacts() {
err = persistence.SaveProfileShowcaseForContact(showcase1)
s.Require().NoError(err)
showcase2 := &ProfileShowcase{
showcase2 := &identity.ProfileShowcase{
ContactID: "contact_2",
Communities: []*ProfileShowcaseCommunity{
&ProfileShowcaseCommunity{
Communities: []*identity.ProfileShowcaseCommunity{
&identity.ProfileShowcaseCommunity{
CommunityID: "0x012312234234234", // same id to check query
Order: 3,
},
&ProfileShowcaseCommunity{
&identity.ProfileShowcaseCommunity{
CommunityID: "0x096783478384593",
Order: 7,
},
},
Collectibles: []*ProfileShowcaseCollectible{
&ProfileShowcaseCollectible{
Collectibles: []*identity.ProfileShowcaseCollectible{
&identity.ProfileShowcaseCollectible{
ContractAddress: "0x12378534257568678487683576",
ChainID: 2,
TokenID: "0x12321389592999f903",
@ -281,10 +283,10 @@ func (s *TestProfileShowcasePersistence) TestFetchingProfileShowcaseAccountsByAd
err = persistence.SaveContacts(conatacts)
s.Require().NoError(err)
showcase1 := &ProfileShowcase{
showcase1 := &identity.ProfileShowcase{
ContactID: "contact_1",
Accounts: []*ProfileShowcaseAccount{
&ProfileShowcaseAccount{
Accounts: []*identity.ProfileShowcaseAccount{
&identity.ProfileShowcaseAccount{
ContactID: "contact_1",
Address: "0x0000000000000000000000000000000000000001",
Name: "Contact1-Account1",
@ -292,7 +294,7 @@ func (s *TestProfileShowcasePersistence) TestFetchingProfileShowcaseAccountsByAd
Emoji: "-_-",
Order: 0,
},
&ProfileShowcaseAccount{
&identity.ProfileShowcaseAccount{
ContactID: "contact_1",
Address: "0x0000000000000000000000000000000000000002",
Name: "Contact1-Account2",
@ -302,10 +304,10 @@ func (s *TestProfileShowcasePersistence) TestFetchingProfileShowcaseAccountsByAd
},
},
}
showcase2 := &ProfileShowcase{
showcase2 := &identity.ProfileShowcase{
ContactID: "contact_2",
Accounts: []*ProfileShowcaseAccount{
&ProfileShowcaseAccount{
Accounts: []*identity.ProfileShowcaseAccount{
&identity.ProfileShowcaseAccount{
ContactID: "contact_2",
Address: "0x0000000000000000000000000000000000000001",
Name: "Contact2-Account1",
@ -313,7 +315,7 @@ func (s *TestProfileShowcasePersistence) TestFetchingProfileShowcaseAccountsByAd
Emoji: "-_-",
Order: 0,
},
&ProfileShowcaseAccount{
&identity.ProfileShowcaseAccount{
ContactID: "contact_2",
Address: "0x0000000000000000000000000000000000000002",
Name: "Contact2-Account2",
@ -323,10 +325,10 @@ func (s *TestProfileShowcasePersistence) TestFetchingProfileShowcaseAccountsByAd
},
},
}
showcase3 := &ProfileShowcase{
showcase3 := &identity.ProfileShowcase{
ContactID: "contact_3",
Accounts: []*ProfileShowcaseAccount{
&ProfileShowcaseAccount{
Accounts: []*identity.ProfileShowcaseAccount{
&identity.ProfileShowcaseAccount{
ContactID: "contact_3",
Address: "0x0000000000000000000000000000000000000001",
Name: "Contact3-Account1",
@ -383,22 +385,22 @@ func (s *TestProfileShowcasePersistence) TestUpdateProfileShowcaseAccountOnWalle
deleteAccountAddress := "0x3243344513424"
updateAccountAddress := "0x3845354643324"
preferences := &ProfileShowcasePreferences{
Accounts: []*ProfileShowcaseAccountPreference{
&ProfileShowcaseAccountPreference{
preferences := &identity.ProfileShowcasePreferences{
Accounts: []*identity.ProfileShowcaseAccountPreference{
&identity.ProfileShowcaseAccountPreference{
Address: deleteAccountAddress,
Name: "Status Account",
ColorID: "blue",
Emoji: "-_-",
ShowcaseVisibility: ProfileShowcaseVisibilityEveryone,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityEveryone,
Order: 0,
},
&ProfileShowcaseAccountPreference{
&identity.ProfileShowcaseAccountPreference{
Address: updateAccountAddress,
Name: "Money Box",
ColorID: "red",
Emoji: ":o)",
ShowcaseVisibility: ProfileShowcaseVisibilityContacts,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityContacts,
Order: 1,
},
},
@ -415,7 +417,7 @@ func (s *TestProfileShowcasePersistence) TestUpdateProfileShowcaseAccountOnWalle
account.Name = "Music Box"
account.ColorID = "green"
account.Emoji = ">:-]"
account.ShowcaseVisibility = ProfileShowcaseVisibilityIDVerifiedContacts
account.ShowcaseVisibility = identity.ProfileShowcaseVisibilityIDVerifiedContacts
account.Order = 7
err = persistence.SaveProfileShowcaseAccountPreference(account)
@ -444,16 +446,16 @@ func (s *TestProfileShowcasePersistence) TestUpdateProfileShowcaseCommunityOnCha
deleteCommunityID := "0x3243344513424"
preferences := &ProfileShowcasePreferences{
Communities: []*ProfileShowcaseCommunityPreference{
&ProfileShowcaseCommunityPreference{
preferences := &identity.ProfileShowcasePreferences{
Communities: []*identity.ProfileShowcaseCommunityPreference{
&identity.ProfileShowcaseCommunityPreference{
CommunityID: "0x32433445133424",
ShowcaseVisibility: ProfileShowcaseVisibilityEveryone,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityEveryone,
Order: 0,
},
&ProfileShowcaseCommunityPreference{
&identity.ProfileShowcaseCommunityPreference{
CommunityID: deleteCommunityID,
ShowcaseVisibility: ProfileShowcaseVisibilityContacts,
ShowcaseVisibility: identity.ProfileShowcaseVisibilityContacts,
Order: 1,
},
},

View File

@ -23,6 +23,7 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type ProfileShowcaseCommunity struct {
CommunityId string `protobuf:"bytes,1,opt,name=community_id,json=communityId,proto3" json:"community_id,omitempty"`
Order uint32 `protobuf:"varint,2,opt,name=order,proto3" json:"order,omitempty"`
Grant []byte `protobuf:"bytes,3,opt,name=grant,proto3" json:"grant,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -67,6 +68,13 @@ func (m *ProfileShowcaseCommunity) GetOrder() uint32 {
return 0
}
func (m *ProfileShowcaseCommunity) GetGrant() []byte {
if m != nil {
return m.Grant
}
return nil
}
type ProfileShowcaseAccount struct {
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
@ -525,43 +533,43 @@ func init() {
}
var fileDescriptor_5bcd51b424a05798 = []byte{
// 596 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0xcd, 0x6e, 0xd3, 0x40,
0x10, 0xc7, 0xe5, 0x38, 0x6d, 0xd3, 0x49, 0x9a, 0x84, 0x55, 0x89, 0x0c, 0x42, 0x10, 0x2c, 0x44,
0x53, 0x21, 0x05, 0x09, 0x8e, 0x70, 0x69, 0x43, 0x24, 0x2a, 0x2a, 0x84, 0xb6, 0x85, 0x03, 0x17,
0xcb, 0xb1, 0xd7, 0xea, 0x52, 0x67, 0x37, 0x5a, 0x3b, 0xad, 0xfc, 0x06, 0x1c, 0xe0, 0x19, 0x78,
0x4a, 0xee, 0x68, 0xbf, 0x9c, 0xc4, 0x49, 0x5a, 0x71, 0xb2, 0x67, 0x77, 0xe6, 0x37, 0x33, 0xff,
0x19, 0x1b, 0x7a, 0x33, 0xc1, 0x13, 0x9a, 0x92, 0x20, 0xbb, 0xe2, 0xb7, 0x51, 0x98, 0x91, 0xe1,
0x4c, 0xf0, 0x9c, 0xa3, 0x86, 0x7a, 0x4c, 0xe6, 0x89, 0x7f, 0x01, 0xde, 0x17, 0xed, 0x73, 0x61,
0x5c, 0x46, 0x7c, 0x3a, 0x9d, 0x33, 0x9a, 0x17, 0xe8, 0x39, 0xb4, 0x22, 0x6b, 0x04, 0x34, 0xf6,
0x9c, 0xbe, 0x33, 0xd8, 0xc7, 0xcd, 0xf2, 0xec, 0x2c, 0x46, 0x87, 0xb0, 0xc3, 0x45, 0x4c, 0x84,
0x57, 0xeb, 0x3b, 0x83, 0x03, 0xac, 0x0d, 0xff, 0xb7, 0x03, 0xbd, 0x0a, 0xf5, 0x24, 0x8a, 0xf8,
0x9c, 0xe5, 0xc8, 0x83, 0xbd, 0x30, 0x8e, 0x05, 0xc9, 0x32, 0x83, 0xb3, 0x26, 0x42, 0x50, 0x67,
0xe1, 0x94, 0x28, 0xd2, 0x3e, 0x56, 0xef, 0xe8, 0x11, 0x34, 0x22, 0x9e, 0x72, 0x21, 0xb3, 0xbb,
0xda, 0x5d, 0xd9, 0x3a, 0x33, 0x99, 0xf2, 0x1f, 0xd4, 0xab, 0xab, 0x73, 0x6d, 0x2c, 0xea, 0xd9,
0x59, 0xae, 0xe7, 0xaf, 0x03, 0x8f, 0xd7, 0xba, 0x4c, 0x53, 0x12, 0xe5, 0x74, 0x92, 0x12, 0x74,
0x08, 0xee, 0xdc, 0xb6, 0x77, 0x5a, 0xf3, 0x1c, 0x2c, 0xcd, 0xcd, 0xad, 0xa1, 0x63, 0xe8, 0x46,
0x9c, 0xe5, 0x22, 0x8c, 0xf2, 0xc0, 0x36, 0xa2, 0x2b, 0xeb, 0xd8, 0xf3, 0x13, 0xd3, 0x50, 0x55,
0xbe, 0xfa, 0xba, 0x7c, 0xb2, 0xbf, 0xab, 0x90, 0x32, 0x79, 0x2d, 0x2b, 0xae, 0xe3, 0x3d, 0x65,
0xeb, 0xab, 0x9c, 0x5f, 0x13, 0x75, 0xb5, 0xab, 0x5b, 0x57, 0xf6, 0x59, 0x8c, 0x8e, 0xa0, 0x13,
0x6a, 0x39, 0xcb, 0x12, 0xf6, 0x94, 0x47, 0xdb, 0x1c, 0x9b, 0x0a, 0xfc, 0x73, 0x78, 0x52, 0x69,
0xfb, 0x1b, 0x11, 0x34, 0xa1, 0x24, 0xbe, 0x94, 0x28, 0xd4, 0x83, 0xdd, 0xac, 0x98, 0x4e, 0x78,
0x6a, 0x66, 0x61, 0xac, 0x2d, 0x53, 0xfd, 0xe3, 0xc0, 0xd3, 0x0a, 0xee, 0x2b, 0xbb, 0x59, 0x01,
0x6e, 0x52, 0xc7, 0xd9, 0xac, 0xce, 0x66, 0x79, 0x97, 0x05, 0x71, 0x57, 0x05, 0xb9, 0x5f, 0x4e,
0xff, 0x97, 0xbb, 0xb6, 0x77, 0x63, 0x96, 0x0b, 0x4a, 0x32, 0xf4, 0x01, 0x4a, 0x4f, 0x4a, 0x64,
0x51, 0xee, 0xa0, 0xf9, 0xc6, 0x1f, 0xda, 0xef, 0x60, 0xb8, 0xed, 0x23, 0xc0, 0xcb, 0x61, 0xe8,
0x3d, 0x34, 0x8c, 0xc4, 0x99, 0x57, 0x53, 0x88, 0xfe, 0x56, 0x84, 0xd9, 0x78, 0x5c, 0x46, 0xa0,
0x8f, 0xb2, 0x83, 0x72, 0xed, 0xe4, 0xde, 0x48, 0xc2, 0x8b, 0x3b, 0x8a, 0x28, 0x9d, 0xf1, 0x4a,
0x24, 0xfa, 0x0c, 0xed, 0x15, 0xe1, 0x33, 0xaf, 0xae, 0x58, 0x2f, 0xb7, 0xb2, 0x56, 0x06, 0x8f,
0x2b, 0xd1, 0xe8, 0x12, 0xba, 0x73, 0x56, 0x21, 0xee, 0x28, 0xe2, 0x60, 0x2b, 0xb1, 0x32, 0x7b,
0xbc, 0x46, 0xf0, 0x6f, 0xe1, 0xd9, 0xe6, 0x69, 0x8c, 0x59, 0x24, 0x8a, 0x59, 0x4e, 0x62, 0xf4,
0x0a, 0x1e, 0x10, 0x6b, 0x04, 0x44, 0xdf, 0xaa, 0x8d, 0x69, 0xe1, 0x6e, 0x79, 0x61, 0x67, 0x78,
0x04, 0x1d, 0x73, 0x46, 0x39, 0x0b, 0xae, 0x49, 0xa1, 0x87, 0xd0, 0xc2, 0xed, 0xc5, 0xf1, 0x27,
0x52, 0x64, 0xfe, 0xcf, 0x1a, 0x74, 0x2a, 0x99, 0xd1, 0x08, 0x5a, 0x09, 0x17, 0x01, 0xb9, 0x21,
0xa2, 0xe0, 0x8c, 0xa8, 0x24, 0x77, 0x8d, 0xcf, 0x24, 0xc5, 0xcd, 0x84, 0x8b, 0xb1, 0x09, 0x42,
0xe7, 0x1a, 0x22, 0x77, 0x39, 0x8c, 0xd4, 0x0e, 0x48, 0xc8, 0xf1, 0x7d, 0x90, 0xb2, 0x5f, 0x45,
0x1b, 0x99, 0x68, 0x34, 0x01, 0x2f, 0x51, 0xff, 0xb6, 0xc0, 0x0a, 0xb7, 0x20, 0xbb, 0xff, 0x4b,
0x7e, 0x98, 0xc8, 0xdf, 0xa2, 0x1d, 0xb3, 0xcd, 0x71, 0x7a, 0xf0, 0xbd, 0x39, 0x7c, 0xfd, 0xce,
0x52, 0x26, 0xbb, 0xea, 0xed, 0xed, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa2, 0x77, 0xf8, 0xf3,
0x19, 0x06, 0x00, 0x00,
// 608 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x4d, 0x6f, 0xd3, 0x40,
0x10, 0x95, 0xe3, 0xb4, 0x4d, 0x27, 0x69, 0x12, 0x56, 0x25, 0x32, 0x08, 0x41, 0xb0, 0x10, 0x4d,
0x85, 0x14, 0x24, 0x38, 0xc2, 0xa5, 0x0d, 0x91, 0xa8, 0xa8, 0x10, 0x5a, 0x0a, 0x07, 0x2e, 0x96,
0x63, 0xaf, 0xe9, 0x52, 0x67, 0x37, 0x5a, 0x3b, 0xad, 0xfc, 0x0f, 0x38, 0xc0, 0x6f, 0xe0, 0x57,
0x72, 0x47, 0xfb, 0xe5, 0x24, 0x4e, 0xd2, 0x8a, 0x93, 0xfd, 0x66, 0x77, 0xde, 0xcc, 0x7b, 0x33,
0x36, 0xf4, 0x66, 0x82, 0x27, 0x34, 0x25, 0x41, 0x76, 0xc9, 0x6f, 0xa2, 0x30, 0x23, 0xc3, 0x99,
0xe0, 0x39, 0x47, 0x0d, 0xf5, 0x98, 0xcc, 0x13, 0x9f, 0x82, 0xf7, 0x49, 0xdf, 0xf9, 0x6c, 0xae,
0x8c, 0xf8, 0x74, 0x3a, 0x67, 0x34, 0x2f, 0xd0, 0x53, 0x68, 0x45, 0x16, 0x04, 0x34, 0xf6, 0x9c,
0xbe, 0x33, 0xd8, 0xc7, 0xcd, 0x32, 0x76, 0x16, 0xa3, 0x43, 0xd8, 0xe1, 0x22, 0x26, 0xc2, 0xab,
0xf5, 0x9d, 0xc1, 0x01, 0xd6, 0x40, 0x46, 0xbf, 0x8b, 0x90, 0xe5, 0x9e, 0xdb, 0x77, 0x06, 0x2d,
0xac, 0x81, 0xff, 0xdb, 0x81, 0x5e, 0xa5, 0xd6, 0x49, 0x14, 0xf1, 0x39, 0xcb, 0x91, 0x07, 0x7b,
0x61, 0x1c, 0x0b, 0x92, 0x65, 0xa6, 0x88, 0x85, 0x08, 0x41, 0x9d, 0x85, 0x53, 0xa2, 0xf8, 0xf7,
0xb1, 0x7a, 0x47, 0x0f, 0xa0, 0x11, 0xf1, 0x94, 0x0b, 0xd9, 0x93, 0xab, 0xaf, 0x2b, 0xac, 0xfb,
0x21, 0x53, 0xfe, 0x83, 0x7a, 0x75, 0x15, 0xd7, 0x60, 0xd1, 0xe5, 0xce, 0x52, 0x97, 0xfe, 0x5f,
0x07, 0x1e, 0xae, 0x69, 0x4f, 0x53, 0x12, 0xe5, 0x74, 0x92, 0x12, 0x74, 0x08, 0xee, 0xdc, 0x8a,
0x3e, 0xad, 0x79, 0x0e, 0x96, 0x70, 0x8b, 0xe0, 0x63, 0xe8, 0x46, 0x9c, 0xe5, 0x22, 0x8c, 0xf2,
0xc0, 0x0a, 0xd1, 0x9d, 0x75, 0x6c, 0xfc, 0xc4, 0x08, 0xaa, 0x9a, 0x5a, 0x5f, 0x37, 0x55, 0xea,
0xbb, 0x0c, 0x29, 0x93, 0xc7, 0xb2, 0xe3, 0x3a, 0xde, 0x53, 0x58, 0x1f, 0xe5, 0xfc, 0x8a, 0xa8,
0xa3, 0x5d, 0x2d, 0x5d, 0xe1, 0xb3, 0x18, 0x1d, 0x41, 0x27, 0xd4, 0x76, 0x96, 0x2d, 0xec, 0xa9,
0x1b, 0x6d, 0x13, 0x36, 0x1d, 0xf8, 0xe7, 0xf0, 0xa8, 0x22, 0xfb, 0x2b, 0x11, 0x34, 0xa1, 0x24,
0xbe, 0x90, 0x54, 0xa8, 0x07, 0xbb, 0x59, 0x31, 0x9d, 0xf0, 0xd4, 0xcc, 0xc2, 0xa0, 0xcd, 0xd2,
0xfd, 0x3f, 0x0e, 0x3c, 0xae, 0xd0, 0x7d, 0x61, 0xd7, 0x2b, 0x84, 0x9b, 0xdc, 0x71, 0x36, 0xbb,
0xb3, 0xd9, 0xde, 0x65, 0x43, 0xdc, 0x55, 0x43, 0xee, 0xb6, 0xd3, 0xff, 0xe5, 0xae, 0xed, 0xdd,
0x98, 0xe5, 0x82, 0x92, 0x0c, 0xbd, 0x83, 0xf2, 0x26, 0x25, 0xb2, 0x29, 0x77, 0xd0, 0x7c, 0xe5,
0x0f, 0xed, 0xd7, 0x31, 0xdc, 0xf6, 0x69, 0xe0, 0xe5, 0x34, 0xf4, 0x16, 0x1a, 0xc6, 0xe2, 0xcc,
0xab, 0x29, 0x8a, 0xfe, 0x56, 0x0a, 0xb3, 0xf1, 0xb8, 0xcc, 0x40, 0xef, 0xa5, 0x82, 0x72, 0xed,
0xe4, 0xde, 0x48, 0x86, 0x67, 0xb7, 0x34, 0x51, 0x5e, 0xc6, 0x2b, 0x99, 0xe8, 0x23, 0xb4, 0x57,
0x8c, 0xcf, 0xbc, 0xba, 0xe2, 0x7a, 0xbe, 0x95, 0x6b, 0x65, 0xf0, 0xb8, 0x92, 0x8d, 0x2e, 0xa0,
0x3b, 0x67, 0x15, 0xc6, 0x1d, 0xc5, 0x38, 0xd8, 0xca, 0x58, 0x99, 0x3d, 0x5e, 0x63, 0xf0, 0x6f,
0xe0, 0xc9, 0xe6, 0x69, 0x8c, 0x59, 0x24, 0x8a, 0x59, 0x4e, 0x62, 0xf4, 0x02, 0xee, 0x11, 0x0b,
0x02, 0xa2, 0x4f, 0xd5, 0xc6, 0xb4, 0x70, 0xb7, 0x3c, 0xb0, 0x33, 0x3c, 0x82, 0x8e, 0x89, 0x51,
0xce, 0x82, 0x2b, 0x52, 0xe8, 0x21, 0xb4, 0x70, 0x7b, 0x11, 0xfe, 0x40, 0x8a, 0xcc, 0xff, 0x59,
0x83, 0x4e, 0xa5, 0x32, 0x1a, 0x41, 0x2b, 0xe1, 0x22, 0x20, 0xd7, 0x44, 0x14, 0x9c, 0x11, 0x55,
0xe4, 0xb6, 0xf1, 0x99, 0xa2, 0xb8, 0x99, 0x70, 0x31, 0x36, 0x49, 0xe8, 0x5c, 0x93, 0xc8, 0x5d,
0x0e, 0x23, 0xb5, 0x03, 0x92, 0xe4, 0xf8, 0x2e, 0x92, 0x52, 0xaf, 0x62, 0x1b, 0x99, 0x6c, 0x34,
0x01, 0x2f, 0x51, 0xff, 0xb6, 0xc0, 0x1a, 0xb7, 0x60, 0x76, 0xff, 0x97, 0xf9, 0x7e, 0x22, 0x7f,
0x8b, 0x76, 0xcc, 0xb6, 0xc6, 0xe9, 0xc1, 0xb7, 0xe6, 0xf0, 0xe5, 0x1b, 0xcb, 0x32, 0xd9, 0x55,
0x6f, 0xaf, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x88, 0x27, 0x81, 0x43, 0x2f, 0x06, 0x00, 0x00,
}

View File

@ -6,6 +6,7 @@ package protobuf;
message ProfileShowcaseCommunity {
string community_id = 1;
uint32 order = 2;
bytes grant = 3;
}
message ProfileShowcaseAccount {

View File

@ -31,6 +31,7 @@ import (
"github.com/status-im/status-go/protocol/communities/token"
"github.com/status-im/status-go/protocol/discord"
"github.com/status-im/status-go/protocol/encryption/multidevice"
"github.com/status-im/status-go/protocol/identity"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/pushnotificationclient"
"github.com/status-im/status-go/protocol/requests"
@ -1659,22 +1660,22 @@ func (api *PublicAPI) CreateTokenGatedCommunity() (*protocol.MessengerResponse,
}
// Set profile showcase preference for current user
func (api *PublicAPI) SetProfileShowcasePreferences(preferences *protocol.ProfileShowcasePreferences) error {
func (api *PublicAPI) SetProfileShowcasePreferences(preferences *identity.ProfileShowcasePreferences) error {
return api.service.messenger.SetProfileShowcasePreferences(preferences)
}
// Get all profile showcase preferences for current user
func (api *PublicAPI) GetProfileShowcasePreferences() (*protocol.ProfileShowcasePreferences, error) {
func (api *PublicAPI) GetProfileShowcasePreferences() (*identity.ProfileShowcasePreferences, error) {
return api.service.messenger.GetProfileShowcasePreferences()
}
// Get profile showcase for a contact
func (api *PublicAPI) GetProfileShowcaseForContact(contactID string) (*protocol.ProfileShowcase, error) {
func (api *PublicAPI) GetProfileShowcaseForContact(contactID string) (*identity.ProfileShowcase, error) {
return api.service.messenger.GetProfileShowcaseForContact(contactID)
}
// Get profile showcase accounts by address
func (api *PublicAPI) GetProfileShowcaseAccountsByAddress(address string) ([]*protocol.ProfileShowcaseAccount, error) {
func (api *PublicAPI) GetProfileShowcaseAccountsByAddress(address string) ([]*identity.ProfileShowcaseAccount, error) {
return api.service.messenger.GetProfileShowcaseAccountsByAddress(address)
}