github.com/wormhole-foundation/wormhole-explorer/common@v0.0.0-20240604151348-09585b5b97c5/domain/tokens.go (about) 1 package domain 2 3 import ( 4 "fmt" 5 6 sdk "github.com/wormhole-foundation/wormhole/sdk/vaa" 7 ) 8 9 // Symbol identifies a publicly traded token (i.e. "ETH" for Ethereum, "ALGO" for Algorand, etc.) 10 type Symbol string 11 12 func (s Symbol) String() string { 13 return string(s) 14 } 15 16 // TokenMetadata contains information about a token supported by Portal Token Bridge. 17 type TokenMetadata struct { 18 TokenChain sdk.ChainID 19 TokenAddress string 20 // Symbol is the name that crypto exchanges use to list the underlying asset represented by this token. 21 // For example, the underlying symbol of the token "USDCso (USDC minted on Solana)" is "USDC". 22 Symbol Symbol 23 CoingeckoID string 24 Decimals int64 25 } 26 27 type TokenProvider struct { 28 p2pNetwork string 29 tokenMetadata []TokenMetadata 30 tokenMetadataByContractID map[string]*TokenMetadata 31 tokenMetadataByCoingeckoID map[string]*TokenMetadata 32 } 33 34 func (t *TokenMetadata) GetTokenID() string { 35 return fmt.Sprintf("%d/%s", t.TokenChain, t.TokenAddress) 36 } 37 38 func makeContractID(tokenChain sdk.ChainID, tokenAddress string) string { 39 return fmt.Sprintf("%d-%s", tokenChain, tokenAddress) 40 } 41 42 func NewTokenProvider(p2pNetwork string) *TokenProvider { 43 var tokenMetadata []TokenMetadata 44 45 switch p2pNetwork { 46 case P2pMainNet: 47 tokenMetadata = mainnetTokenList() 48 case P2pTestNet: 49 tokenMetadata = manualTestnetTokenList() 50 default: 51 panic(fmt.Sprintf("unknown p2p network: %s", p2pNetwork)) 52 } 53 54 tokenMetadataByContractID := make(map[string]*TokenMetadata) 55 tokenMetadataByCoingeckoID := make(map[string]*TokenMetadata) 56 57 for i := range tokenMetadata { 58 // populate the map `tokenMetadataByCoingeckoID` 59 coingeckoID := tokenMetadata[i].CoingeckoID 60 if coingeckoID != "" { 61 tokenMetadataByCoingeckoID[coingeckoID] = &tokenMetadata[i] 62 } 63 64 // populate the map `tokenMetadataByContractID` 65 contractID := makeContractID(tokenMetadata[i].TokenChain, tokenMetadata[i].TokenAddress) 66 if contractID != "" { 67 tokenMetadataByContractID[contractID] = &tokenMetadata[i] 68 } 69 } 70 return &TokenProvider{ 71 p2pNetwork: p2pNetwork, 72 tokenMetadata: tokenMetadata, 73 tokenMetadataByContractID: tokenMetadataByContractID, 74 tokenMetadataByCoingeckoID: tokenMetadataByCoingeckoID, 75 } 76 } 77 78 // GetAllTokens returns a list of all tokens that exist in the database. 79 // 80 // The caller must not modify the `[]TokenMetadata` returned. 81 func (t *TokenProvider) GetAllTokens() []TokenMetadata { 82 return t.tokenMetadata 83 } 84 85 // GetAllCoingeckoIDs returns a list of all coingecko IDs that exist in the database. 86 func (t *TokenProvider) GetAllCoingeckoIDs() []string { 87 88 // use a map to remove duplicates 89 uniqueIDs := make(map[string]bool, len(t.tokenMetadata)) 90 for i := range t.tokenMetadata { 91 uniqueIDs[t.tokenMetadata[i].CoingeckoID] = true 92 } 93 94 // collect keys into a slice 95 ids := make([]string, 0, len(uniqueIDs)) 96 for k := range uniqueIDs { 97 ids = append(ids, k) 98 } 99 100 return ids 101 } 102 103 // GetTokenByCoingeckoID returns information about a token identified by its coingecko ID. 104 // 105 // The caller must not modify the `*TokenMetadata` returned. 106 func (t *TokenProvider) GetTokenByCoingeckoID(coingeckoID string) (*TokenMetadata, bool) { 107 108 result, ok := t.tokenMetadataByCoingeckoID[coingeckoID] 109 if !ok { 110 return nil, false 111 } 112 113 return result, true 114 } 115 116 // GetTokenByAddress returns information about a token identified by its original mint address. 117 // 118 // The caller must not modify the `*TokenMetadata` returned. 119 func (t *TokenProvider) GetTokenByAddress(tokenChain sdk.ChainID, tokenAddress string) (*TokenMetadata, bool) { 120 121 key := makeContractID(tokenChain, tokenAddress) 122 123 result, ok := t.tokenMetadataByContractID[key] 124 if !ok { 125 return nil, false 126 } 127 128 return result, true 129 } 130 131 func (t *TokenProvider) GetP2pNewtork() string { 132 return t.p2pNetwork 133 }