feat: Added ERC20 community id (#4189)
This commit is contained in:
parent
8ae6e3035b
commit
debf3b6e4d
|
@ -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",
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE tokens ADD COLUMN community_id TEXT DEFAULT NULL;
|
Loading…
Reference in New Issue