2023-05-04 16:17:03 -07:00
|
|
|
package domain
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
sdk "github.com/wormhole-foundation/wormhole/sdk/vaa"
|
|
|
|
)
|
|
|
|
|
2023-05-08 13:51:18 -07:00
|
|
|
// Symbol identifies a publicly traded token (i.e. "ETH" for Ethereum, "ALGO" for Algorand, etc.)
|
|
|
|
type Symbol string
|
|
|
|
|
|
|
|
func (s Symbol) String() string {
|
|
|
|
return string(s)
|
|
|
|
}
|
|
|
|
|
2023-05-04 16:17:03 -07:00
|
|
|
// TokenMetadata contains information about a token supported by Portal Token Bridge.
|
|
|
|
type TokenMetadata struct {
|
2023-05-30 07:14:19 -07:00
|
|
|
TokenChain sdk.ChainID
|
|
|
|
TokenAddress string
|
|
|
|
// Symbol is the name that crypto exchanges use to list the underlying asset represented by this token.
|
2023-05-10 13:39:18 -07:00
|
|
|
// For example, the underlying symbol of the token "USDCso (USDC minted on Solana)" is "USDC".
|
2023-05-30 07:14:19 -07:00
|
|
|
Symbol Symbol
|
|
|
|
CoingeckoID string
|
|
|
|
Decimals int64
|
2023-05-04 16:17:03 -07:00
|
|
|
}
|
|
|
|
|
2023-05-08 13:51:18 -07:00
|
|
|
var (
|
2023-05-30 07:14:19 -07:00
|
|
|
tokenMetadata = generatedMainnetTokenList()
|
|
|
|
tokenMetadataByContractID = make(map[string]*TokenMetadata)
|
|
|
|
tokenMetadataByCoingeckoID = make(map[string]*TokenMetadata)
|
2023-05-08 13:51:18 -07:00
|
|
|
)
|
|
|
|
|
2023-09-22 12:14:02 -07:00
|
|
|
func (t *TokenMetadata) GetTokenID() string {
|
|
|
|
return fmt.Sprintf("%d/%s", t.TokenChain, t.TokenAddress)
|
|
|
|
}
|
|
|
|
|
2023-05-08 13:51:18 -07:00
|
|
|
func init() {
|
|
|
|
|
|
|
|
for i := range tokenMetadata {
|
|
|
|
|
|
|
|
// populate the map `tokenMetadataByCoingeckoID`
|
|
|
|
coingeckoID := tokenMetadata[i].CoingeckoID
|
|
|
|
if coingeckoID != "" {
|
|
|
|
tokenMetadataByCoingeckoID[coingeckoID] = &tokenMetadata[i]
|
|
|
|
}
|
|
|
|
|
|
|
|
// populate the map `tokenMetadataByContractID`
|
|
|
|
contractID := makeContractID(tokenMetadata[i].TokenChain, tokenMetadata[i].TokenAddress)
|
|
|
|
if contractID != "" {
|
|
|
|
tokenMetadataByContractID[contractID] = &tokenMetadata[i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func makeContractID(tokenChain sdk.ChainID, tokenAddress string) string {
|
|
|
|
return fmt.Sprintf("%d-%s", tokenChain, tokenAddress)
|
|
|
|
}
|
|
|
|
|
2023-05-30 07:14:19 -07:00
|
|
|
// GetAllTokens returns a list of all tokens that exist in the database.
|
|
|
|
//
|
|
|
|
// The caller must not modify the `[]TokenMetadata` returned.
|
|
|
|
func GetAllTokens() []TokenMetadata {
|
|
|
|
return tokenMetadata
|
|
|
|
}
|
|
|
|
|
2023-05-08 13:51:18 -07:00
|
|
|
// GetAllCoingeckoIDs returns a list of all coingecko IDs that exist in the database.
|
|
|
|
func GetAllCoingeckoIDs() []string {
|
|
|
|
|
|
|
|
// use a map to remove duplicates
|
|
|
|
uniqueIDs := make(map[string]bool, len(tokenMetadata))
|
|
|
|
for i := range tokenMetadata {
|
|
|
|
uniqueIDs[tokenMetadata[i].CoingeckoID] = true
|
|
|
|
}
|
|
|
|
|
|
|
|
// collect keys into a slice
|
|
|
|
ids := make([]string, 0, len(uniqueIDs))
|
|
|
|
for k := range uniqueIDs {
|
|
|
|
ids = append(ids, k)
|
|
|
|
}
|
|
|
|
|
|
|
|
return ids
|
|
|
|
}
|
2023-05-04 16:17:03 -07:00
|
|
|
|
2023-05-08 13:51:18 -07:00
|
|
|
// GetTokenByCoingeckoID returns information about a token identified by its coingecko ID.
|
|
|
|
//
|
|
|
|
// The caller must not modify the `*TokenMetadata` returned.
|
|
|
|
func GetTokenByCoingeckoID(coingeckoID string) (*TokenMetadata, bool) {
|
2023-05-04 16:17:03 -07:00
|
|
|
|
2023-05-08 13:51:18 -07:00
|
|
|
result, ok := tokenMetadataByCoingeckoID[coingeckoID]
|
2023-05-04 16:17:03 -07:00
|
|
|
if !ok {
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
|
2023-05-08 13:51:18 -07:00
|
|
|
return result, true
|
2023-05-04 16:17:03 -07:00
|
|
|
}
|
|
|
|
|
2023-05-08 13:51:18 -07:00
|
|
|
// GetTokenByAddress returns information about a token identified by its original mint address.
|
2023-05-04 16:17:03 -07:00
|
|
|
//
|
2023-05-08 13:51:18 -07:00
|
|
|
// The caller must not modify the `*TokenMetadata` returned.
|
|
|
|
func GetTokenByAddress(tokenChain sdk.ChainID, tokenAddress string) (*TokenMetadata, bool) {
|
|
|
|
|
|
|
|
key := makeContractID(tokenChain, tokenAddress)
|
|
|
|
|
|
|
|
result, ok := tokenMetadataByContractID[key]
|
|
|
|
if !ok {
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, true
|
|
|
|
}
|