feat: new endpoint added which returns accounts of all contacts that match the passed address

This commit is contained in:
Sale Djenic 2024-01-25 14:29:29 +01:00 committed by saledjenic
parent ab641c0c78
commit 6403a7413b
5 changed files with 189 additions and 30 deletions

View File

@ -380,9 +380,12 @@ func buildContact(publicKeyString string, publicKey *ecdsa.PublicKey) (*Contact,
return nil, err return nil, err
} }
address := crypto.PubkeyToAddress(*publicKey)
contact := &Contact{ contact := &Contact{
ID: publicKeyString, ID: publicKeyString,
Alias: getShortenedCompressedKey(compressedKey), Alias: getShortenedCompressedKey(compressedKey),
Address: types.EncodeHex(address[:]),
} }
return contact, nil return contact, nil

View File

@ -217,6 +217,10 @@ func (m *Messenger) GetProfileShowcaseForContact(contactID string) (*ProfileShow
return m.persistence.GetProfileShowcaseForContact(contactID) return m.persistence.GetProfileShowcaseForContact(contactID)
} }
func (m *Messenger) GetProfileShowcaseAccountsByAddress(address string) ([]*ProfileShowcaseAccount, error) {
return m.persistence.GetProfileShowcaseAccountsByAddress(address)
}
func (m *Messenger) EncryptProfileShowcaseEntriesWithContactPubKeys(entries *protobuf.ProfileShowcaseEntries, contacts []*Contact) (*protobuf.ProfileShowcaseEntriesEncrypted, error) { func (m *Messenger) EncryptProfileShowcaseEntriesWithContactPubKeys(entries *protobuf.ProfileShowcaseEntries, contacts []*Contact) (*protobuf.ProfileShowcaseEntriesEncrypted, error) {
// Make AES key // Make AES key
AESKey := make([]byte, 32) AESKey := make([]byte, 32)

View File

@ -3,6 +3,7 @@ package protocol
import ( import (
"context" "context"
"database/sql" "database/sql"
"errors"
) )
type ProfileShowcaseVisibility int type ProfileShowcaseVisibility int
@ -34,8 +35,8 @@ const selectContactProfileShowcaseCommunityQuery = "SELECT community_id, sort_or
const removeContactProfileShowcaseCommunityQuery = "DELETE FROM profile_showcase_communities_contacts WHERE contact_id = ?" // #nosec G101 const removeContactProfileShowcaseCommunityQuery = "DELETE FROM profile_showcase_communities_contacts WHERE contact_id = ?" // #nosec G101
const upsertContactProfileShowcaseAccountQuery = "INSERT OR REPLACE INTO profile_showcase_accounts_contacts(contact_id, address, name, color_id, emoji, sort_order) VALUES (?, ?, ?, ?, ?, ?)" // #nosec G101 const upsertContactProfileShowcaseAccountQuery = "INSERT OR REPLACE INTO profile_showcase_accounts_contacts(contact_id, address, name, color_id, emoji, sort_order) VALUES (?, ?, ?, ?, ?, ?)" // #nosec G101
const selectContactProfileShowcaseAccountQuery = "SELECT address, name, color_id, emoji, sort_order FROM profile_showcase_accounts_contacts WHERE contact_id = ?" // #nosec G101 const selectContactProfileShowcaseAccountQuery = "SELECT * FROM profile_showcase_accounts_contacts WHERE contact_id = ?" // #nosec G101
const removeContactProfileShowcaseAccountQuery = "DELETE FROM profile_showcase_accounts_contacts WHERE contact_id = ?" const removeContactProfileShowcaseAccountQuery = "DELETE FROM profile_showcase_accounts_contacts WHERE contact_id = ?" // #nosec G101
const upsertContactProfileShowcaseCollectibleQuery = "INSERT OR REPLACE INTO profile_showcase_collectibles_contacts(contact_id, contract_address, chain_id, token_id, community_id, account_address, sort_order) VALUES (?, ?, ?, ?, ?, ?, ?)" // #nosec G101 const upsertContactProfileShowcaseCollectibleQuery = "INSERT OR REPLACE INTO profile_showcase_collectibles_contacts(contact_id, contract_address, chain_id, token_id, community_id, account_address, sort_order) VALUES (?, ?, ?, ?, ?, ?, ?)" // #nosec G101
const selectContactProfileShowcaseCollectibleQuery = "SELECT contract_address, chain_id, token_id, community_id, account_address, sort_order FROM profile_showcase_collectibles_contacts WHERE contact_id = ?" // #nosec G101 const selectContactProfileShowcaseCollectibleQuery = "SELECT contract_address, chain_id, token_id, community_id, account_address, sort_order FROM profile_showcase_collectibles_contacts WHERE contact_id = ?" // #nosec G101
@ -49,6 +50,18 @@ const upsertContactProfileShowcaseUnverifiedTokenQuery = "INSERT OR REPLACE INTO
const selectContactProfileShowcaseUnverifiedTokenQuery = "SELECT contract_address, chain_id, community_id, sort_order FROM profile_showcase_unverified_tokens_contacts WHERE contact_id = ?" // #nosec G101 const selectContactProfileShowcaseUnverifiedTokenQuery = "SELECT contract_address, chain_id, community_id, sort_order FROM profile_showcase_unverified_tokens_contacts WHERE contact_id = ?" // #nosec G101
const removeContactProfileShowcaseUnverifiedTokenQuery = "DELETE FROM profile_showcase_unverified_tokens_contacts WHERE contact_id = ?" // #nosec G101 const removeContactProfileShowcaseUnverifiedTokenQuery = "DELETE FROM profile_showcase_unverified_tokens_contacts WHERE contact_id = ?" // #nosec G101
const selectProfileShowcaseAccountsWhichMatchTheAddress = `
SELECT psa.*
FROM
contacts c
LEFT JOIN
profile_showcase_accounts_contacts psa
ON
c.id = psa.contact_id
WHERE
psa.address = ?
`
type ProfileShowcaseCommunityPreference struct { type ProfileShowcaseCommunityPreference struct {
CommunityID string `json:"communityId"` CommunityID string `json:"communityId"`
ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"` ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"`
@ -102,11 +115,12 @@ type ProfileShowcaseCommunity struct {
} }
type ProfileShowcaseAccount struct { type ProfileShowcaseAccount struct {
Address string `json:"address"` ContactID string `json:"contactId"`
Name string `json:"name"` Address string `json:"address"`
ColorID string `json:"colorId"` Name string `json:"name"`
Emoji string `json:"emoji"` ColorID string `json:"colorId"`
Order int `json:"order"` Emoji string `json:"emoji"`
Order int `json:"order"`
} }
type ProfileShowcaseCollectible struct { type ProfileShowcaseCollectible struct {
@ -392,25 +406,42 @@ func (db sqlitePersistence) saveProfileShowcaseAccountContact(tx *sql.Tx, contac
return err return err
} }
func (db sqlitePersistence) processProfileShowcaseAccounts(rows *sql.Rows) (result []*ProfileShowcaseAccount, err error) {
if rows == nil {
return nil, errors.New("rows is nil")
}
for rows.Next() {
account := &ProfileShowcaseAccount{}
err = rows.Scan(&account.Address, &account.Name, &account.ColorID, &account.Emoji, &account.Order, &account.ContactID)
if err != nil {
return
}
result = append(result, account)
}
err = rows.Err()
return
}
func (db sqlitePersistence) getProfileShowcaseAccountsContact(tx *sql.Tx, contactID string) ([]*ProfileShowcaseAccount, error) { func (db sqlitePersistence) getProfileShowcaseAccountsContact(tx *sql.Tx, contactID string) ([]*ProfileShowcaseAccount, error) {
rows, err := tx.Query(selectContactProfileShowcaseAccountQuery, contactID) rows, err := tx.Query(selectContactProfileShowcaseAccountQuery, contactID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
accounts := []*ProfileShowcaseAccount{} return db.processProfileShowcaseAccounts(rows)
}
for rows.Next() { func (db sqlitePersistence) GetProfileShowcaseAccountsByAddress(address string) ([]*ProfileShowcaseAccount, error) {
account := &ProfileShowcaseAccount{} rows, err := db.db.Query(selectProfileShowcaseAccountsWhichMatchTheAddress, address)
if err != nil {
err := rows.Scan(&account.Address, &account.Name, &account.ColorID, &account.Emoji, &account.Order) return nil, err
if err != nil {
return nil, err
}
accounts = append(accounts, account)
} }
return accounts, nil
return db.processProfileShowcaseAccounts(rows)
} }
func (db sqlitePersistence) clearProfileShowcaseAccountsContact(tx *sql.Tx, contactID string) error { func (db sqlitePersistence) clearProfileShowcaseAccountsContact(tx *sql.Tx, contactID string) error {

View File

@ -142,18 +142,20 @@ func (s *TestProfileShowcasePersistence) TestProfileShowcaseContacts() {
}, },
Accounts: []*ProfileShowcaseAccount{ Accounts: []*ProfileShowcaseAccount{
&ProfileShowcaseAccount{ &ProfileShowcaseAccount{
Address: "0x32433445133424", ContactID: "contact_1",
Name: "Status Account", Address: "0x32433445133424",
ColorID: "blue", Name: "Status Account",
Emoji: "-_-", ColorID: "blue",
Order: 0, Emoji: "-_-",
Order: 0,
}, },
&ProfileShowcaseAccount{ &ProfileShowcaseAccount{
Address: "0x3845354643324", ContactID: "contact_1",
Name: "Money Box", Address: "0x3845354643324",
ColorID: "red", Name: "Money Box",
Emoji: ":o)", ColorID: "red",
Order: 1, Emoji: ":o)",
Order: 1,
}, },
}, },
Collectibles: []*ProfileShowcaseCollectible{ Collectibles: []*ProfileShowcaseCollectible{
@ -258,3 +260,117 @@ func (s *TestProfileShowcasePersistence) TestProfileShowcaseContacts() {
s.Require().Equal(0, len(showcase2Back.VerifiedTokens)) s.Require().Equal(0, len(showcase2Back.VerifiedTokens))
s.Require().Equal(0, len(showcase2Back.UnverifiedTokens)) s.Require().Equal(0, len(showcase2Back.UnverifiedTokens))
} }
func (s *TestProfileShowcasePersistence) TestFetchingProfileShowcaseAccountsByAddress() {
db, err := openTestDB()
s.Require().NoError(err)
persistence := newSQLitePersistence(db)
conatacts := []*Contact{
&Contact{
ID: "contact_1",
},
&Contact{
ID: "contact_2",
},
&Contact{
ID: "contact_3",
},
}
err = persistence.SaveContacts(conatacts)
s.Require().NoError(err)
showcase1 := &ProfileShowcase{
ContactID: "contact_1",
Accounts: []*ProfileShowcaseAccount{
&ProfileShowcaseAccount{
ContactID: "contact_1",
Address: "0x0000000000000000000000000000000000000001",
Name: "Contact1-Account1",
ColorID: "blue",
Emoji: "-_-",
Order: 0,
},
&ProfileShowcaseAccount{
ContactID: "contact_1",
Address: "0x0000000000000000000000000000000000000002",
Name: "Contact1-Account2",
ColorID: "blue",
Emoji: "-_-",
Order: 1,
},
},
}
showcase2 := &ProfileShowcase{
ContactID: "contact_2",
Accounts: []*ProfileShowcaseAccount{
&ProfileShowcaseAccount{
ContactID: "contact_2",
Address: "0x0000000000000000000000000000000000000001",
Name: "Contact2-Account1",
ColorID: "blue",
Emoji: "-_-",
Order: 0,
},
&ProfileShowcaseAccount{
ContactID: "contact_2",
Address: "0x0000000000000000000000000000000000000002",
Name: "Contact2-Account2",
ColorID: "blue",
Emoji: "-_-",
Order: 1,
},
},
}
showcase3 := &ProfileShowcase{
ContactID: "contact_3",
Accounts: []*ProfileShowcaseAccount{
&ProfileShowcaseAccount{
ContactID: "contact_3",
Address: "0x0000000000000000000000000000000000000001",
Name: "Contact3-Account1",
ColorID: "blue",
Emoji: "-_-",
Order: 0,
},
},
}
err = persistence.SaveProfileShowcaseForContact(showcase1)
s.Require().NoError(err)
err = persistence.SaveProfileShowcaseForContact(showcase2)
s.Require().NoError(err)
err = persistence.SaveProfileShowcaseForContact(showcase3)
s.Require().NoError(err)
showcaseAccounts, err := persistence.GetProfileShowcaseAccountsByAddress(showcase1.Accounts[0].Address)
s.Require().NoError(err)
s.Require().Equal(3, len(showcaseAccounts))
for i := 0; i < len(showcaseAccounts); i++ {
if showcaseAccounts[i].ContactID == showcase1.ContactID {
s.Require().Equal(showcase1.Accounts[0].Address, showcase1.Accounts[0].Address)
} else if showcaseAccounts[i].ContactID == showcase2.ContactID {
s.Require().Equal(showcase2.Accounts[0].Address, showcase2.Accounts[0].Address)
} else if showcaseAccounts[i].ContactID == showcase3.ContactID {
s.Require().Equal(showcase3.Accounts[0].Address, showcase3.Accounts[0].Address)
} else {
s.Require().Fail("unexpected contact id")
}
}
showcaseAccounts, err = persistence.GetProfileShowcaseAccountsByAddress(showcase1.Accounts[1].Address)
s.Require().NoError(err)
s.Require().Equal(2, len(showcaseAccounts))
for i := 0; i < len(showcaseAccounts); i++ {
if showcaseAccounts[i].ContactID == showcase1.ContactID {
s.Require().Equal(showcase1.Accounts[0].Address, showcase1.Accounts[0].Address)
} else if showcaseAccounts[i].ContactID == showcase2.ContactID {
s.Require().Equal(showcase2.Accounts[0].Address, showcase2.Accounts[0].Address)
} else {
s.Require().Fail("unexpected contact id")
}
}
}

View File

@ -1668,6 +1668,11 @@ func (api *PublicAPI) GetProfileShowcaseForContact(contactID string) (*protocol.
return api.service.messenger.GetProfileShowcaseForContact(contactID) return api.service.messenger.GetProfileShowcaseForContact(contactID)
} }
// Get profile showcase accounts by address
func (api *PublicAPI) GetProfileShowcaseAccountsByAddress(address string) ([]*protocol.ProfileShowcaseAccount, error) {
return api.service.messenger.GetProfileShowcaseAccountsByAddress(address)
}
// Returns response with AC notification when owner token is received // Returns response with AC notification when owner token is received
func (api *PublicAPI) RegisterOwnerTokenReceivedNotification(communityID string) (*protocol.MessengerResponse, error) { func (api *PublicAPI) RegisterOwnerTokenReceivedNotification(communityID string) (*protocol.MessengerResponse, error) {
return api.service.messenger.CreateResponseWithACNotification(communityID, protocol.ActivityCenterNotificationTypeOwnerTokenReceived, false) return api.service.messenger.CreateResponseWithACNotification(communityID, protocol.ActivityCenterNotificationTypeOwnerTokenReceived, false)