625 lines
18 KiB
Go
625 lines
18 KiB
Go
package protocol
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
)
|
|
|
|
type ProfileShowcaseVisibility int
|
|
|
|
const (
|
|
ProfileShowcaseVisibilityNoOne ProfileShowcaseVisibility = iota
|
|
ProfileShowcaseVisibilityIDVerifiedContacts
|
|
ProfileShowcaseVisibilityContacts
|
|
ProfileShowcaseVisibilityEveryone
|
|
)
|
|
|
|
const upsertProfileShowcaseCommunityPreferenceQuery = "INSERT OR REPLACE INTO profile_showcase_communities_preferences(community_id, visibility, sort_order) VALUES (?, ?, ?)"
|
|
const selectProfileShowcaseCommunityPreferenceQuery = "SELECT community_id, visibility, sort_order FROM profile_showcase_communities_preferences"
|
|
|
|
const upsertProfileShowcaseAccountPreferenceQuery = "INSERT OR REPLACE INTO profile_showcase_accounts_preferences(address, name, color_id, emoji, visibility, sort_order) VALUES (?, ?, ?, ?, ?, ?)"
|
|
const selectProfileShowcaseAccountPreferenceQuery = "SELECT address, name, color_id, emoji, visibility, sort_order FROM profile_showcase_accounts_preferences"
|
|
|
|
const upsertProfileShowcaseCollectiblePreferenceQuery = "INSERT OR REPLACE INTO profile_showcase_collectibles_preferences(uid, visibility, sort_order) VALUES (?, ?, ?)"
|
|
const selectProfileShowcaseCollectiblePreferenceQuery = "SELECT uid, visibility, sort_order FROM profile_showcase_collectibles_preferences"
|
|
|
|
const upsertProfileShowcaseAssetPreferenceQuery = "INSERT OR REPLACE INTO profile_showcase_assets_preferences(symbol, visibility, sort_order) VALUES (?, ?, ?)"
|
|
const selectProfileShowcaseAssetPreferenceQuery = "SELECT symbol, visibility, sort_order FROM profile_showcase_assets_preferences"
|
|
|
|
const upsertContactProfileShowcaseCommunityQuery = "INSERT OR REPLACE INTO profile_showcase_communities_contacts(contact_id, community_id, sort_order) VALUES (?, ?, ?)"
|
|
const selectContactProfileShowcaseCommunityQuery = "SELECT community_id, sort_order FROM profile_showcase_communities_contacts WHERE contact_id = ?"
|
|
const removeContactProfileShowcaseCommunityQuery = "DELETE FROM profile_showcase_communities_contacts WHERE contact_id = ?"
|
|
|
|
const upsertContactProfileShowcaseAccountQuery = "INSERT OR REPLACE INTO profile_showcase_accounts_contacts(contact_id, address, name, color_id, emoji, sort_order) VALUES (?, ?, ?, ?, ?, ?)"
|
|
const selectContactProfileShowcaseAccountQuery = "SELECT address, name, color_id, emoji, sort_order FROM profile_showcase_accounts_contacts WHERE contact_id = ?"
|
|
const removeContactProfileShowcaseAccountQuery = "DELETE FROM profile_showcase_accounts_contacts WHERE contact_id = ?"
|
|
|
|
const upsertContactProfileShowcaseCollectibleQuery = "INSERT OR REPLACE INTO profile_showcase_collectibles_contacts(contact_id, uid, sort_order) VALUES (?, ?, ?)"
|
|
const selectContactProfileShowcaseCollectibleQuery = "SELECT uid, sort_order FROM profile_showcase_collectibles_contacts WHERE contact_id = ?"
|
|
const removeContactProfileShowcaseCollectibleQuery = "DELETE FROM profile_showcase_collectibles_contacts WHERE contact_id = ?"
|
|
|
|
const upsertContactProfileShowcaseAssetQuery = "INSERT OR REPLACE INTO profile_showcase_assets_contacts(contact_id, symbol, sort_order) VALUES (?, ?, ?)"
|
|
const selectContactProfileShowcaseAssetQuery = "SELECT symbol, sort_order FROM profile_showcase_assets_contacts WHERE contact_id = ?"
|
|
const removeContactProfileShowcaseAssetQuery = "DELETE FROM profile_showcase_assets_contacts WHERE contact_id = ?"
|
|
|
|
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 {
|
|
UID string `json:"uid"`
|
|
ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"`
|
|
Order int `json:"order"`
|
|
}
|
|
|
|
type ProfileShowcaseAssetPreference struct {
|
|
Symbol string `json:"symbol"`
|
|
ShowcaseVisibility ProfileShowcaseVisibility `json:"showcaseVisibility"`
|
|
Order int `json:"order"`
|
|
}
|
|
|
|
type ProfileShowcasePreferences struct {
|
|
Communities []*ProfileShowcaseCommunityPreference `json:"communities"`
|
|
Accounts []*ProfileShowcaseAccountPreference `json:"accounts"`
|
|
Collectibles []*ProfileShowcaseCollectiblePreference `json:"collectibles"`
|
|
Assets []*ProfileShowcaseAssetPreference `json:"assets"`
|
|
}
|
|
|
|
type ProfileShowcaseCommunity struct {
|
|
CommunityID string `json:"communityId"`
|
|
Order int `json:"order"`
|
|
}
|
|
|
|
type ProfileShowcaseAccount struct {
|
|
Address string `json:"address"`
|
|
Name string `json:"name"`
|
|
ColorID string `json:"colorId"`
|
|
Emoji string `json:"emoji"`
|
|
Order int `json:"order"`
|
|
}
|
|
|
|
type ProfileShowcaseCollectible struct {
|
|
UID string `json:"uid"`
|
|
Order int `json:"order"`
|
|
}
|
|
|
|
type ProfileShowcaseAsset struct {
|
|
Symbol string `json:"symbol"`
|
|
Order int `json:"order"`
|
|
}
|
|
|
|
type ProfileShowcase struct {
|
|
ContactID string `json:"contactId"`
|
|
Communities []*ProfileShowcaseCommunity `json:"communities"`
|
|
Accounts []*ProfileShowcaseAccount `json:"accounts"`
|
|
Collectibles []*ProfileShowcaseCollectible `json:"collectibles"`
|
|
Assets []*ProfileShowcaseAsset `json:"assets"`
|
|
}
|
|
|
|
// Queries for showcase preferences
|
|
func (db sqlitePersistence) saveProfileShowcaseCommunityPreference(tx *sql.Tx, community *ProfileShowcaseCommunityPreference) error {
|
|
_, err := tx.Exec(upsertProfileShowcaseCommunityPreferenceQuery,
|
|
community.CommunityID,
|
|
community.ShowcaseVisibility,
|
|
community.Order,
|
|
)
|
|
|
|
return err
|
|
}
|
|
|
|
func (db sqlitePersistence) getProfileShowcaseCommunitiesPreferences(tx *sql.Tx) ([]*ProfileShowcaseCommunityPreference, error) {
|
|
rows, err := tx.Query(selectProfileShowcaseCommunityPreferenceQuery)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
communities := []*ProfileShowcaseCommunityPreference{}
|
|
|
|
for rows.Next() {
|
|
community := &ProfileShowcaseCommunityPreference{}
|
|
|
|
err := rows.Scan(
|
|
&community.CommunityID,
|
|
&community.ShowcaseVisibility,
|
|
&community.Order,
|
|
)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
communities = append(communities, community)
|
|
}
|
|
return communities, nil
|
|
}
|
|
|
|
func (db sqlitePersistence) saveProfileShowcaseAccountPreference(tx *sql.Tx, account *ProfileShowcaseAccountPreference) error {
|
|
_, err := tx.Exec(upsertProfileShowcaseAccountPreferenceQuery,
|
|
account.Address,
|
|
account.Name,
|
|
account.ColorID,
|
|
account.Emoji,
|
|
account.ShowcaseVisibility,
|
|
account.Order,
|
|
)
|
|
|
|
return err
|
|
}
|
|
|
|
func (db sqlitePersistence) getProfileShowcaseAccountsPreferences(tx *sql.Tx) ([]*ProfileShowcaseAccountPreference, error) {
|
|
rows, err := tx.Query(selectProfileShowcaseAccountPreferenceQuery)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
accounts := []*ProfileShowcaseAccountPreference{}
|
|
|
|
for rows.Next() {
|
|
account := &ProfileShowcaseAccountPreference{}
|
|
|
|
err := rows.Scan(
|
|
&account.Address,
|
|
&account.Name,
|
|
&account.ColorID,
|
|
&account.Emoji,
|
|
&account.ShowcaseVisibility,
|
|
&account.Order,
|
|
)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
accounts = append(accounts, account)
|
|
}
|
|
return accounts, nil
|
|
}
|
|
|
|
func (db sqlitePersistence) saveProfileShowcaseCollectiblePreference(tx *sql.Tx, collectible *ProfileShowcaseCollectiblePreference) error {
|
|
_, err := tx.Exec(upsertProfileShowcaseCollectiblePreferenceQuery,
|
|
collectible.UID,
|
|
collectible.ShowcaseVisibility,
|
|
collectible.Order,
|
|
)
|
|
|
|
return err
|
|
}
|
|
|
|
func (db sqlitePersistence) getProfileShowcaseCollectiblesPreferences(tx *sql.Tx) ([]*ProfileShowcaseCollectiblePreference, error) {
|
|
rows, err := tx.Query(selectProfileShowcaseCollectiblePreferenceQuery)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
collectibles := []*ProfileShowcaseCollectiblePreference{}
|
|
|
|
for rows.Next() {
|
|
collectible := &ProfileShowcaseCollectiblePreference{}
|
|
|
|
err := rows.Scan(
|
|
&collectible.UID,
|
|
&collectible.ShowcaseVisibility,
|
|
&collectible.Order,
|
|
)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
collectibles = append(collectibles, collectible)
|
|
}
|
|
return collectibles, nil
|
|
}
|
|
|
|
func (db sqlitePersistence) saveProfileShowcaseAssetPreference(tx *sql.Tx, asset *ProfileShowcaseAssetPreference) error {
|
|
_, err := tx.Exec(upsertProfileShowcaseAssetPreferenceQuery,
|
|
asset.Symbol,
|
|
asset.ShowcaseVisibility,
|
|
asset.Order,
|
|
)
|
|
|
|
return err
|
|
}
|
|
|
|
func (db sqlitePersistence) getProfileShowcaseAssetsPreferences(tx *sql.Tx) ([]*ProfileShowcaseAssetPreference, error) {
|
|
rows, err := tx.Query(selectProfileShowcaseAssetPreferenceQuery)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
assets := []*ProfileShowcaseAssetPreference{}
|
|
|
|
for rows.Next() {
|
|
asset := &ProfileShowcaseAssetPreference{}
|
|
|
|
err := rows.Scan(
|
|
&asset.Symbol,
|
|
&asset.ShowcaseVisibility,
|
|
&asset.Order,
|
|
)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
assets = append(assets, asset)
|
|
}
|
|
return assets, nil
|
|
}
|
|
|
|
// Queries for contacts showcase
|
|
func (db sqlitePersistence) saveProfileShowcaseCommunityContact(tx *sql.Tx, contactID string, community *ProfileShowcaseCommunity) error {
|
|
_, err := tx.Exec(upsertContactProfileShowcaseCommunityQuery,
|
|
contactID,
|
|
community.CommunityID,
|
|
community.Order,
|
|
)
|
|
|
|
return err
|
|
}
|
|
|
|
func (db sqlitePersistence) getProfileShowcaseCommunitiesContact(tx *sql.Tx, contactID string) ([]*ProfileShowcaseCommunity, error) {
|
|
rows, err := tx.Query(selectContactProfileShowcaseCommunityQuery, contactID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
communities := []*ProfileShowcaseCommunity{}
|
|
|
|
for rows.Next() {
|
|
community := &ProfileShowcaseCommunity{}
|
|
|
|
err := rows.Scan(&community.CommunityID, &community.Order)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
communities = append(communities, community)
|
|
}
|
|
return communities, nil
|
|
}
|
|
|
|
func (db sqlitePersistence) clearProfileShowcaseCommunityContact(tx *sql.Tx, contactID string) error {
|
|
_, err := tx.Exec(removeContactProfileShowcaseCommunityQuery, contactID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (db sqlitePersistence) saveProfileShowcaseAccountContact(tx *sql.Tx, contactID string, account *ProfileShowcaseAccount) error {
|
|
_, err := tx.Exec(upsertContactProfileShowcaseAccountQuery,
|
|
contactID,
|
|
account.Address,
|
|
account.Name,
|
|
account.ColorID,
|
|
account.Emoji,
|
|
account.Order,
|
|
)
|
|
|
|
return err
|
|
}
|
|
|
|
func (db sqlitePersistence) getProfileShowcaseAccountsContact(tx *sql.Tx, contactID string) ([]*ProfileShowcaseAccount, error) {
|
|
rows, err := tx.Query(selectContactProfileShowcaseAccountQuery, contactID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
accounts := []*ProfileShowcaseAccount{}
|
|
|
|
for rows.Next() {
|
|
account := &ProfileShowcaseAccount{}
|
|
|
|
err := rows.Scan(&account.Address, &account.Name, &account.ColorID, &account.Emoji, &account.Order)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
accounts = append(accounts, account)
|
|
}
|
|
return accounts, nil
|
|
}
|
|
|
|
func (db sqlitePersistence) clearProfileShowcaseAccountsContact(tx *sql.Tx, contactID string) error {
|
|
_, err := tx.Exec(removeContactProfileShowcaseAccountQuery, contactID)
|
|
return err
|
|
}
|
|
|
|
func (db sqlitePersistence) saveProfileShowcaseCollectibleContact(tx *sql.Tx, contactID string, community *ProfileShowcaseCollectible) error {
|
|
_, err := tx.Exec(upsertContactProfileShowcaseCollectibleQuery,
|
|
contactID,
|
|
community.UID,
|
|
community.Order,
|
|
)
|
|
|
|
return err
|
|
}
|
|
|
|
func (db sqlitePersistence) getProfileShowcaseCollectiblesContact(tx *sql.Tx, contactID string) ([]*ProfileShowcaseCollectible, error) {
|
|
rows, err := tx.Query(selectContactProfileShowcaseCollectibleQuery, contactID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
collectibles := []*ProfileShowcaseCollectible{}
|
|
|
|
for rows.Next() {
|
|
collectible := &ProfileShowcaseCollectible{}
|
|
|
|
err := rows.Scan(&collectible.UID, &collectible.Order)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
collectibles = append(collectibles, collectible)
|
|
}
|
|
return collectibles, nil
|
|
}
|
|
|
|
func (db sqlitePersistence) clearProfileShowcaseCollectiblesContact(tx *sql.Tx, contactID string) error {
|
|
_, err := tx.Exec(removeContactProfileShowcaseCollectibleQuery, contactID)
|
|
return err
|
|
}
|
|
|
|
func (db sqlitePersistence) saveProfileShowcaseAssetContact(tx *sql.Tx, contactID string, asset *ProfileShowcaseAsset) error {
|
|
_, err := tx.Exec(upsertContactProfileShowcaseAssetQuery,
|
|
contactID,
|
|
asset.Symbol,
|
|
asset.Order,
|
|
)
|
|
|
|
return err
|
|
}
|
|
|
|
func (db sqlitePersistence) getProfileShowcaseAssetsContact(tx *sql.Tx, contactID string) ([]*ProfileShowcaseAsset, error) {
|
|
rows, err := tx.Query(selectContactProfileShowcaseAssetQuery, contactID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
assets := []*ProfileShowcaseAsset{}
|
|
|
|
for rows.Next() {
|
|
asset := &ProfileShowcaseAsset{}
|
|
|
|
err := rows.Scan(&asset.Symbol, &asset.Order)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
assets = append(assets, asset)
|
|
}
|
|
return assets, nil
|
|
}
|
|
|
|
func (db sqlitePersistence) clearProfileShowcaseAssetsContact(tx *sql.Tx, contactID string) error {
|
|
_, err := tx.Exec(removeContactProfileShowcaseAssetQuery, contactID)
|
|
return err
|
|
}
|
|
|
|
// public functions
|
|
func (db sqlitePersistence) SaveProfileShowcasePreferences(preferences *ProfileShowcasePreferences) error {
|
|
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func() {
|
|
if err == nil {
|
|
err = tx.Commit()
|
|
return
|
|
}
|
|
// don't shadow original error
|
|
_ = tx.Rollback()
|
|
}()
|
|
|
|
for _, community := range preferences.Communities {
|
|
err = db.saveProfileShowcaseCommunityPreference(tx, community)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
for _, account := range preferences.Accounts {
|
|
err = db.saveProfileShowcaseAccountPreference(tx, account)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
for _, collectible := range preferences.Collectibles {
|
|
err = db.saveProfileShowcaseCollectiblePreference(tx, collectible)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
for _, asset := range preferences.Assets {
|
|
err = db.saveProfileShowcaseAssetPreference(tx, asset)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (db sqlitePersistence) GetProfileShowcasePreferences() (*ProfileShowcasePreferences, error) {
|
|
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer func() {
|
|
if err == nil {
|
|
err = tx.Commit()
|
|
return
|
|
}
|
|
// don't shadow original error
|
|
_ = tx.Rollback()
|
|
}()
|
|
|
|
communities, err := db.getProfileShowcaseCommunitiesPreferences(tx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
accounts, err := db.getProfileShowcaseAccountsPreferences(tx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
collectibles, err := db.getProfileShowcaseCollectiblesPreferences(tx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
assets, err := db.getProfileShowcaseAssetsPreferences(tx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &ProfileShowcasePreferences{
|
|
Communities: communities,
|
|
Accounts: accounts,
|
|
Collectibles: collectibles,
|
|
Assets: assets,
|
|
}, nil
|
|
}
|
|
|
|
func (db sqlitePersistence) SaveProfileShowcaseForContact(showcase *ProfileShowcase) error {
|
|
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func() {
|
|
if err == nil {
|
|
err = tx.Commit()
|
|
return
|
|
}
|
|
// don't shadow original error
|
|
_ = tx.Rollback()
|
|
}()
|
|
|
|
for _, community := range showcase.Communities {
|
|
err = db.saveProfileShowcaseCommunityContact(tx, showcase.ContactID, community)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
for _, account := range showcase.Accounts {
|
|
err = db.saveProfileShowcaseAccountContact(tx, showcase.ContactID, account)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
for _, collectible := range showcase.Collectibles {
|
|
err = db.saveProfileShowcaseCollectibleContact(tx, showcase.ContactID, collectible)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
for _, asset := range showcase.Assets {
|
|
err = db.saveProfileShowcaseAssetContact(tx, showcase.ContactID, asset)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (db sqlitePersistence) GetProfileShowcaseForContact(contactID string) (*ProfileShowcase, error) {
|
|
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer func() {
|
|
if err == nil {
|
|
err = tx.Commit()
|
|
return
|
|
}
|
|
// don't shadow original error
|
|
_ = tx.Rollback()
|
|
}()
|
|
|
|
communities, err := db.getProfileShowcaseCommunitiesContact(tx, contactID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
accounts, err := db.getProfileShowcaseAccountsContact(tx, contactID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
collectibles, err := db.getProfileShowcaseCollectiblesContact(tx, contactID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
assets, err := db.getProfileShowcaseAssetsContact(tx, contactID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &ProfileShowcase{
|
|
ContactID: contactID,
|
|
Communities: communities,
|
|
Accounts: accounts,
|
|
Collectibles: collectibles,
|
|
Assets: assets,
|
|
}, nil
|
|
}
|
|
|
|
func (db sqlitePersistence) ClearProfileShowcaseForContact(contactID string) error {
|
|
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func() {
|
|
if err == nil {
|
|
err = tx.Commit()
|
|
return
|
|
}
|
|
// don't shadow original error
|
|
_ = tx.Rollback()
|
|
}()
|
|
|
|
err = db.clearProfileShowcaseCommunityContact(tx, contactID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = db.clearProfileShowcaseAccountsContact(tx, contactID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = db.clearProfileShowcaseCollectiblesContact(tx, contactID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = db.clearProfileShowcaseAssetsContact(tx, contactID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|