feat: Added ERC20 community id (#4189)

This commit is contained in:
Cuteivist 2023-10-25 18:49:18 +02:00 committed by GitHub
parent 8ae6e3035b
commit debf3b6e4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 186 additions and 101 deletions

View File

@ -4,5 +4,5 @@
"github.com/ethereum/go-ethereum,github.com/status-im/status-go", "github.com/ethereum/go-ethereum,github.com/status-im/status-go",
"-w" "-w"
], ],
"go.testTags": "gowaku_skip_migrations", "go.testTags": "gowaku_skip_migrations,gowaku_no_rln",
} }

View File

@ -15,6 +15,7 @@ import (
"github.com/status-im/status-go/protocol/protobuf" "github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/requests" "github.com/status-im/status-go/protocol/requests"
"github.com/status-im/status-go/protocol/urls" "github.com/status-im/status-go/protocol/urls"
"github.com/status-im/status-go/services/utils"
) )
type CommunityURLData struct { type CommunityURLData struct {
@ -68,20 +69,7 @@ func (m *Messenger) SerializePublicKey(compressedKey types.HexBytes) (string, er
} }
func (m *Messenger) DeserializePublicKey(compressedKey string) (types.HexBytes, error) { func (m *Messenger) DeserializePublicKey(compressedKey string) (types.HexBytes, error) {
rawKey, err := multiformat.DeserializePublicKey(compressedKey, "f") return utils.DeserializePublicKey(compressedKey)
if err != nil {
return nil, err
}
secp256k1Code := "fe701"
pubKeyBytes := "0x" + strings.TrimPrefix(rawKey, secp256k1Code)
pubKey, err := common.HexToPubkey(pubKeyBytes)
if err != nil {
return nil, err
}
return crypto.CompressPubkey(pubKey), nil
} }
func (m *Messenger) ShareCommunityURLWithChatKey(communityID types.HexBytes) (string, error) { func (m *Messenger) ShareCommunityURLWithChatKey(communityID types.HexBytes) (string, error) {

View File

@ -2,12 +2,16 @@ package utils
import ( import (
"math/big" "math/big"
"strings"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
ethTypes "github.com/ethereum/go-ethereum/core/types" ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/status-im/status-go/account" "github.com/status-im/status-go/account"
"github.com/status-im/status-go/api/multiformat"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
prot_common "github.com/status-im/status-go/protocol/common"
) )
func GetSigner(chainID uint64, accountsManager *account.GethManager, keyStoreDir string, from types.Address, password string) bind.SignerFn { func GetSigner(chainID uint64, accountsManager *account.GethManager, keyStoreDir string, from types.Address, password string) bind.SignerFn {
@ -20,3 +24,20 @@ func GetSigner(chainID uint64, accountsManager *account.GethManager, keyStoreDir
return ethTypes.SignTx(tx, s, selectedAccount.PrivateKey) return ethTypes.SignTx(tx, s, selectedAccount.PrivateKey)
} }
} }
func DeserializePublicKey(compressedKey string) (types.HexBytes, error) {
rawKey, err := multiformat.DeserializePublicKey(compressedKey, "f")
if err != nil {
return nil, err
}
secp256k1Code := "fe701"
pubKeyBytes := "0x" + strings.TrimPrefix(rawKey, secp256k1Code)
pubKey, err := prot_common.HexToPubkey(pubKeyBytes)
if err != nil {
return nil, err
}
return crypto.CompressPubkey(pubKey), nil
}

View File

@ -6,6 +6,7 @@ import (
"errors" "errors"
"math/big" "math/big"
"strconv" "strconv"
"strings"
"sync" "sync"
"time" "time"
@ -14,12 +15,15 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/contracts" "github.com/status-im/status-go/contracts"
"github.com/status-im/status-go/contracts/community-tokens/assets"
"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"
eth_node_types "github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/params" "github.com/status-im/status-go/params"
"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/services/utils"
"github.com/status-im/status-go/services/wallet/async" "github.com/status-im/status-go/services/wallet/async"
) )
@ -42,6 +46,7 @@ type Token struct {
PegSymbol string `json:"pegSymbol"` PegSymbol string `json:"pegSymbol"`
Verified bool `json:"verified"` Verified bool `json:"verified"`
CommunityID *string `json:"communityId,omitempty"`
} }
func (t *Token) IsNative() bool { func (t *Token) IsNative() bool {
@ -274,6 +279,7 @@ func (tm *Manager) FindOrCreateTokenByAddress(ctx context.Context, chainID uint6
allTokens := tm.getFullTokenList(chainID) allTokens := tm.getFullTokenList(chainID)
for _, token := range allTokens { for _, token := range allTokens {
if token.Address == address { if token.Address == address {
tm.discoverTokenCommunityID(context.Background(), token, address)
return token return token
} }
} }
@ -288,9 +294,58 @@ func (tm *Manager) FindOrCreateTokenByAddress(ctx context.Context, chainID uint6
return nil return nil
} }
tm.discoverTokenCommunityID(context.Background(), token, address)
return token return token
} }
func (tm *Manager) discoverTokenCommunityID(ctx context.Context, token *Token, address common.Address) {
if token != nil && token.CommunityID == nil {
// Token is invalid or is alrady discovered. Nothing to do here.
return
}
backend, err := tm.RPCClient.EthClient(token.ChainID)
if err != nil {
return
}
caller, err := assets.NewAssetsCaller(address, backend)
if err != nil {
return
}
uri, err := caller.BaseTokenURI(&bind.CallOpts{
Context: ctx,
})
if err != nil {
return
}
update, err := tm.db.Prepare("UPDATE tokens SET community_id=? WHERE network_id=? AND address=?")
if err != nil {
log.Error("Cannot prepare token update query", err)
return
}
if uri == "" {
// Update token community ID to prevent further checks
_, err := update.Exec("", token.ChainID, token.Address)
if err != nil {
log.Error("Cannot update community id", err)
}
return
}
uri = strings.TrimSuffix(uri, "/")
communityIDHex, err := utils.DeserializePublicKey(uri)
if err != nil {
return
}
communityID := eth_node_types.EncodeHex(communityIDHex)
_, err = update.Exec(communityID, token.ChainID, token.Address)
if err != nil {
log.Error("Cannot update community id", err)
}
}
func (tm *Manager) FindSNT(chainID uint64) *Token { func (tm *Manager) FindSNT(chainID uint64) *Token {
tokens, err := tm.GetTokens(chainID) tokens, err := tm.GetTokens(chainID)
if err != nil { if err != nil {
@ -413,8 +468,8 @@ func (tm *Manager) DiscoverToken(ctx context.Context, chainID uint64, address co
}, nil }, nil
} }
func (tm *Manager) GetCustoms() ([]*Token, error) { func (tm *Manager) getTokens(query string, args ...any) ([]*Token, error) {
rows, err := tm.db.Query("SELECT address, name, symbol, decimals, color, network_id FROM tokens") rows, err := tm.db.Query(query, args...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -423,36 +478,28 @@ func (tm *Manager) GetCustoms() ([]*Token, error) {
var rst []*Token var rst []*Token
for rows.Next() { for rows.Next() {
token := &Token{} token := &Token{}
err := rows.Scan(&token.Address, &token.Name, &token.Symbol, &token.Decimals, &token.Color, &token.ChainID) var communityIDDB sql.NullString
err := rows.Scan(&token.Address, &token.Name, &token.Symbol, &token.Decimals, &token.Color, &token.ChainID, &communityIDDB)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if communityIDDB.Valid {
token.CommunityID = &communityIDDB.String
}
rst = append(rst, token) rst = append(rst, token)
} }
return rst, nil return rst, nil
} }
func (tm *Manager) GetCustoms() ([]*Token, error) {
return tm.getTokens("SELECT address, name, symbol, decimals, color, network_id, community_id FROM tokens")
}
func (tm *Manager) GetCustomsByChainID(chainID uint64) ([]*Token, error) { func (tm *Manager) GetCustomsByChainID(chainID uint64) ([]*Token, error) {
rows, err := tm.db.Query("SELECT address, name, symbol, decimals, color, network_id FROM tokens where network_id=?", chainID) return tm.getTokens("SELECT address, name, symbol, decimals, color, network_id, community_id FROM tokens where network_id=?", chainID)
if err != nil {
return nil, err
}
defer rows.Close()
var rst []*Token
for rows.Next() {
token := &Token{}
err := rows.Scan(&token.Address, &token.Name, &token.Symbol, &token.Decimals, &token.Color, &token.ChainID)
if err != nil {
return nil, err
}
rst = append(rst, token)
}
return rst, nil
} }
func (tm *Manager) IsTokenVisible(chainID uint64, address common.Address) (bool, error) { func (tm *Manager) IsTokenVisible(chainID uint64, address common.Address) (bool, error) {

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
ALTER TABLE tokens ADD COLUMN community_id TEXT DEFAULT NULL;