feat: Use media server for community token images (#4493)

This commit is contained in:
Cuteivist 2023-12-21 16:05:29 +01:00 committed by GitHub
parent 313375e215
commit 6bfe626558
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 99 additions and 10 deletions

View File

@ -455,7 +455,7 @@ func NewMessenger(
if c.tokenManager != nil { if c.tokenManager != nil {
managerOptions = append(managerOptions, communities.WithTokenManager(c.tokenManager)) managerOptions = append(managerOptions, communities.WithTokenManager(c.tokenManager))
} else if c.rpcClient != nil { } else if c.rpcClient != nil {
tokenManager := token.NewTokenManager(c.walletDb, c.rpcClient, community.NewManager(database, c.httpServer), c.rpcClient.NetworkManager, database) tokenManager := token.NewTokenManager(c.walletDb, c.rpcClient, community.NewManager(database, c.httpServer), c.rpcClient.NetworkManager, database, c.httpServer)
managerOptions = append(managerOptions, communities.WithTokenManager(communities.NewDefaultTokenManager(tokenManager))) managerOptions = append(managerOptions, communities.WithTokenManager(communities.NewDefaultTokenManager(tokenManager)))
} }

View File

@ -35,6 +35,7 @@ const (
discordAttachmentsPath = basePath + "/discord/attachments" discordAttachmentsPath = basePath + "/discord/attachments"
LinkPreviewThumbnailPath = "/link-preview/thumbnail" LinkPreviewThumbnailPath = "/link-preview/thumbnail"
StatusLinkPreviewThumbnailPath = "/status-link-preview/thumbnail" StatusLinkPreviewThumbnailPath = "/status-link-preview/thumbnail"
communityTokenImagesPath = "/communityTokenImages"
walletBasePath = "/wallet" walletBasePath = "/wallet"
walletCommunityImagesPath = walletBasePath + "/communityImages" walletCommunityImagesPath = walletBasePath + "/communityImages"
@ -930,6 +931,63 @@ func handleQRCodeGeneration(multiaccountsDB *multiaccounts.Database, logger *zap
} }
} }
func handleCommunityTokenImages(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
if db == nil {
return handleRequestDBMissing(logger)
}
return func(w http.ResponseWriter, r *http.Request) {
params := r.URL.Query()
if len(params["communityID"]) == 0 {
logger.Error("no communityID")
return
}
if len(params["chainID"]) == 0 {
logger.Error("no chainID")
return
}
if len(params["symbol"]) == 0 {
logger.Error("no symbol")
return
}
chainID, err := strconv.ParseUint(params["chainID"][0], 10, 64)
if err != nil {
logger.Error("invalid chainID in community token image", zap.Error(err))
return
}
var base64Image string
err = db.QueryRow("SELECT image_base64 FROM community_tokens WHERE community_id = ? AND chain_id = ? AND symbol = ?", params["communityID"][0], chainID, params["symbol"][0]).Scan(&base64Image)
if err != nil {
logger.Error("failed to find community token image", zap.Error(err))
return
}
if len(base64Image) == 0 {
logger.Error("empty community token image")
return
}
imagePayload, err := images.GetPayloadFromURI(base64Image)
if err != nil {
logger.Error("failed to get community token image payload", zap.Error(err))
return
}
mime, err := images.GetProtobufImageMime(imagePayload)
if err != nil {
logger.Error("failed to get community token image mime", zap.Error(err))
}
w.Header().Set("Content-Type", mime)
w.Header().Set("Cache-Control", "no-store")
_, err = w.Write(imagePayload)
if err != nil {
logger.Error("failed to write community token image", zap.Error(err))
}
}
}
func handleWalletCommunityImages(db *sql.DB, logger *zap.Logger) http.HandlerFunc { func handleWalletCommunityImages(db *sql.DB, logger *zap.Logger) http.HandlerFunc {
if db == nil { if db == nil {
return handleRequestDBMissing(logger) return handleRequestDBMissing(logger)

View File

@ -3,6 +3,7 @@ package server
import ( import (
"database/sql" "database/sql"
"net/url" "net/url"
"strconv"
"github.com/status-im/status-go/ipfs" "github.com/status-im/status-go/ipfs"
"github.com/status-im/status-go/logutils" "github.com/status-im/status-go/logutils"
@ -52,6 +53,7 @@ func NewMediaServer(db *sql.DB, downloader *ipfs.Downloader, multiaccountsDB *mu
ipfsPath: handleIPFS(s.downloader, s.logger), ipfsPath: handleIPFS(s.downloader, s.logger),
LinkPreviewThumbnailPath: handleLinkPreviewThumbnail(s.db, s.logger), LinkPreviewThumbnailPath: handleLinkPreviewThumbnail(s.db, s.logger),
StatusLinkPreviewThumbnailPath: handleStatusLinkPreviewThumbnail(s.db, s.logger), StatusLinkPreviewThumbnailPath: handleStatusLinkPreviewThumbnail(s.db, s.logger),
communityTokenImagesPath: handleCommunityTokenImages(s.db, s.logger),
walletCommunityImagesPath: handleWalletCommunityImages(s.walletDB, s.logger), walletCommunityImagesPath: handleWalletCommunityImages(s.walletDB, s.logger),
walletCollectionImagesPath: handleWalletCollectionImages(s.walletDB, s.logger), walletCollectionImagesPath: handleWalletCollectionImages(s.walletDB, s.logger),
walletCollectibleImagesPath: handleWalletCollectibleImages(s.walletDB, s.logger), walletCollectibleImagesPath: handleWalletCollectibleImages(s.walletDB, s.logger),
@ -146,6 +148,18 @@ func (s *MediaServer) MakeContactImageURL(publicKey string, imageType string) st
return u.String() return u.String()
} }
func (s *MediaServer) MakeCommunityTokenImagesURL(communityID string, chainID uint64, symbol string) string {
u := s.MakeBaseURL()
u.Path = communityTokenImagesPath
u.RawQuery = url.Values{
"communityID": {communityID},
"chainID": {strconv.FormatUint(chainID, 10)},
"symbol": {symbol},
}.Encode()
return u.String()
}
func (s *MediaServer) MakeWalletCommunityImagesURL(communityID string) string { func (s *MediaServer) MakeWalletCommunityImagesURL(communityID string) string {
u := s.MakeBaseURL() u := s.MakeBaseURL()
u.Path = walletCommunityImagesPath u.Path = walletCommunityImagesPath

View File

@ -47,7 +47,7 @@ func (db *Database) GetTokenPrivilegesLevel(chainID uint64, contractAddress stri
} }
func (db *Database) GetCommunityERC20Metadata() ([]*token.CommunityToken, error) { func (db *Database) GetCommunityERC20Metadata() ([]*token.CommunityToken, error) {
rows, err := db.db.Query(`SELECT community_id, address, name, symbol, chain_id, image_base64 FROM community_tokens WHERE type = ?`, protobuf.CommunityTokenType_ERC20) rows, err := db.db.Query(`SELECT community_id, address, name, symbol, chain_id FROM community_tokens WHERE type = ?`, protobuf.CommunityTokenType_ERC20)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -56,7 +56,7 @@ func (db *Database) GetCommunityERC20Metadata() ([]*token.CommunityToken, error)
var result []*token.CommunityToken var result []*token.CommunityToken
for rows.Next() { for rows.Next() {
token := token.CommunityToken{} token := token.CommunityToken{}
err := rows.Scan(&token.CommunityID, &token.Address, &token.Name, &token.Symbol, &token.ChainID, &token.Base64Image) err := rows.Scan(&token.CommunityID, &token.Address, &token.Name, &token.Symbol, &token.ChainID)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -101,7 +101,7 @@ func NewService(
communityManager := community.NewManager(db, mediaServer) communityManager := community.NewManager(db, mediaServer)
balanceCacher := balance.NewCacherWithTTL(5 * time.Minute) balanceCacher := balance.NewCacherWithTTL(5 * time.Minute)
tokenManager := token.NewTokenManager(db, rpcClient, communityManager, rpcClient.NetworkManager, appDB) tokenManager := token.NewTokenManager(db, rpcClient, communityManager, rpcClient.NetworkManager, appDB, mediaServer)
savedAddressesManager := &SavedAddressesManager{db: db} savedAddressesManager := &SavedAddressesManager{db: db}
transactionManager := transfer.NewTransactionManager(db, gethManager, transactor, config, accountsDB, pendingTxManager, feed) transactionManager := transfer.NewTransactionManager(db, gethManager, transactor, config, accountsDB, pendingTxManager, feed)
transferController := transfer.NewTransferController(db, accountsDB, rpcClient, accountFeed, feed, transactionManager, pendingTxManager, transferController := transfer.NewTransferController(db, accountsDB, rpcClient, accountFeed, feed, transactionManager, pendingTxManager,

View File

@ -24,6 +24,7 @@ import (
"github.com/status-im/status-go/rpc" "github.com/status-im/status-go/rpc"
"github.com/status-im/status-go/rpc/chain" "github.com/status-im/status-go/rpc/chain"
"github.com/status-im/status-go/rpc/network" "github.com/status-im/status-go/rpc/network"
"github.com/status-im/status-go/server"
"github.com/status-im/status-go/services/communitytokens" "github.com/status-im/status-go/services/communitytokens"
"github.com/status-im/status-go/services/utils" "github.com/status-im/status-go/services/utils"
"github.com/status-im/status-go/services/wallet/async" "github.com/status-im/status-go/services/wallet/async"
@ -89,6 +90,7 @@ type Manager struct {
stores []store // Set on init, not changed afterwards stores []store // Set on init, not changed afterwards
communityTokensDB *communitytokens.Database communityTokensDB *communitytokens.Database
communityManager *community.Manager communityManager *community.Manager
mediaServer *server.MediaServer
tokens []*Token tokens []*Token
@ -116,6 +118,7 @@ func NewTokenManager(
communityManager *community.Manager, communityManager *community.Manager,
networkManager *network.Manager, networkManager *network.Manager,
appDB *sql.DB, appDB *sql.DB,
mediaServer *server.MediaServer,
) *Manager { ) *Manager {
maker, _ := contracts.NewContractMaker(RPCClient) maker, _ := contracts.NewContractMaker(RPCClient)
stores := []store{newUniswapStore(), newDefaultStore()} stores := []store{newUniswapStore(), newDefaultStore()}
@ -151,6 +154,7 @@ func NewTokenManager(
stores: stores, stores: stores,
communityTokensDB: communitytokens.NewCommunityTokensDatabase(appDB), communityTokensDB: communitytokens.NewCommunityTokensDatabase(appDB),
tokens: tokens, tokens: tokens,
mediaServer: mediaServer,
} }
} }
@ -516,7 +520,6 @@ func (tm *Manager) DiscoverToken(ctx context.Context, chainID uint64, address co
} }
func (tm *Manager) getTokensFromDB(query string, args ...any) ([]*Token, error) { func (tm *Manager) getTokensFromDB(query string, args ...any) ([]*Token, error) {
communityTokens := []*token.CommunityToken{} communityTokens := []*token.CommunityToken{}
if tm.communityTokensDB != nil { if tm.communityTokensDB != nil {
// Error is skipped because it's only returning optional metadata // Error is skipped because it's only returning optional metadata
@ -544,7 +547,7 @@ func (tm *Manager) getTokensFromDB(query string, args ...any) ([]*Token, error)
if communityToken.CommunityID != communityID || uint64(communityToken.ChainID) != token.ChainID || communityToken.Symbol != token.Symbol { if communityToken.CommunityID != communityID || uint64(communityToken.ChainID) != token.ChainID || communityToken.Symbol != token.Symbol {
continue continue
} }
token.Image = communityToken.Base64Image token.Image = tm.mediaServer.MakeCommunityTokenImagesURL(communityID, token.ChainID, token.Symbol)
break break
} }

View File

@ -27,6 +27,7 @@ import (
"github.com/status-im/status-go/contracts/ethscan" "github.com/status-im/status-go/contracts/ethscan"
"github.com/status-im/status-go/contracts/ierc20" "github.com/status-im/status-go/contracts/ierc20"
"github.com/status-im/status-go/rpc/chain" "github.com/status-im/status-go/rpc/chain"
"github.com/status-im/status-go/server"
"github.com/status-im/status-go/services/wallet/async" "github.com/status-im/status-go/services/wallet/async"
"github.com/status-im/status-go/services/wallet/balance" "github.com/status-im/status-go/services/wallet/balance"
"github.com/status-im/status-go/services/wallet/community" "github.com/status-im/status-go/services/wallet/community"
@ -912,6 +913,9 @@ func TestFindBlocksCommand(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
tm := &TransactionManager{db, nil, nil, nil, nil, nil, nil, nil, nil, nil} tm := &TransactionManager{db, nil, nil, nil, nil, nil, nil, nil, nil, nil}
mediaServer, err := server.NewMediaServer(appdb, nil, nil, db)
require.NoError(t, err)
wdb := NewDB(db) wdb := NewDB(db)
tc := &TestClient{ tc := &TestClient{
t: t, t: t,
@ -933,7 +937,7 @@ func TestFindBlocksCommand(t *testing.T) {
} }
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db) client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
client.SetClient(tc.NetworkID(), tc) client.SetClient(tc.NetworkID(), tc)
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil), network.NewManager(appdb), appdb) tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil), network.NewManager(appdb), appdb, mediaServer)
tokenManager.SetTokens([]*token.Token{ tokenManager.SetTokens([]*token.Token{
{ {
Address: tokenTXXAddress, Address: tokenTXXAddress,
@ -1041,6 +1045,9 @@ func TestFetchTransfersForLoadedBlocks(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
tm := &TransactionManager{db, nil, nil, nil, nil, nil, nil, nil, nil, nil} tm := &TransactionManager{db, nil, nil, nil, nil, nil, nil, nil, nil, nil}
mediaServer, err := server.NewMediaServer(appdb, nil, nil, db)
require.NoError(t, err)
wdb := NewDB(db) wdb := NewDB(db)
blockChannel := make(chan []*DBHeader, 100) blockChannel := make(chan []*DBHeader, 100)
@ -1055,7 +1062,7 @@ func TestFetchTransfersForLoadedBlocks(t *testing.T) {
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db) client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
client.SetClient(tc.NetworkID(), tc) client.SetClient(tc.NetworkID(), tc)
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil), network.NewManager(appdb), appdb) tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil), network.NewManager(appdb), appdb, mediaServer)
tokenManager.SetTokens([]*token.Token{ tokenManager.SetTokens([]*token.Token{
{ {
@ -1152,6 +1159,9 @@ func TestFetchNewBlocksCommand_findBlocksWithEthTransfers(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
tm := &TransactionManager{db, nil, nil, nil, nil, nil, nil, nil, nil, nil} tm := &TransactionManager{db, nil, nil, nil, nil, nil, nil, nil, nil, nil}
mediaServer, err := server.NewMediaServer(appdb, nil, nil, db)
require.NoError(t, err)
wdb := NewDB(db) wdb := NewDB(db)
blockChannel := make(chan []*DBHeader, 10) blockChannel := make(chan []*DBHeader, 10)
@ -1172,7 +1182,7 @@ func TestFetchNewBlocksCommand_findBlocksWithEthTransfers(t *testing.T) {
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db) client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
client.SetClient(tc.NetworkID(), tc) client.SetClient(tc.NetworkID(), tc)
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil), network.NewManager(appdb), appdb) tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil), network.NewManager(appdb), appdb, mediaServer)
tokenManager.SetTokens([]*token.Token{ tokenManager.SetTokens([]*token.Token{
{ {
@ -1227,6 +1237,9 @@ func TestFetchNewBlocksCommand(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
tm := &TransactionManager{db, nil, nil, nil, nil, nil, nil, nil, nil, nil} tm := &TransactionManager{db, nil, nil, nil, nil, nil, nil, nil, nil, nil}
mediaServer, err := server.NewMediaServer(appdb, nil, nil, db)
require.NoError(t, err)
wdb := NewDB(db) wdb := NewDB(db)
blockChannel := make(chan []*DBHeader, 10) blockChannel := make(chan []*DBHeader, 10)
@ -1246,7 +1259,8 @@ func TestFetchNewBlocksCommand(t *testing.T) {
client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db) client, _ := statusRpc.NewClient(nil, 1, params.UpstreamRPCConfig{Enabled: false, URL: ""}, []params.Network{}, db)
client.SetClient(tc.NetworkID(), tc) client.SetClient(tc.NetworkID(), tc)
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil), network.NewManager(appdb), appdb)
tokenManager := token.NewTokenManager(db, client, community.NewManager(appdb, nil), network.NewManager(appdb), appdb, mediaServer)
tokenManager.SetTokens([]*token.Token{ tokenManager.SetTokens([]*token.Token{
{ {