Closed hboon closed 3 years ago
That is epic. Works perfectly.
https://api.coingecko.com/api/v3/coins/dai/market_chart?days=1&vs_currency=USD
For ERC20 did you have to use a lookup table to match token address to api 'coins' name? Or does the symbol work?
We have this. The platform string mapping is generated emprically:
if platformMatches() {
if contract == "" { //because some don't specify contracts, only ""
return symbol matches case-insenstively
} else if contract matches {
return true
} else {
return false
}
} else {
return symbol + name matches case-insenstively //need a name match because there are false positives otherwise
}
Mapping table for platforms:
private func platformMatches(_ platform: String, server: RPCServer) -> Bool {
switch server {
case .main: return platform == "ethereum"
case .classic: return platform == "ethereum-classic"
case .xDai: return platform == "xdai"
case .binance_smart_chain: return platform == "binance-smart-chain"
case .avalanche: return platform == "Avalanche"
case .polygon: return platform == "polygon-pos"
case .poa, .kovan, .sokol, .callisto, .goerli, .artis_sigma1, .artis_tau1, .binance_smart_chain_testnet, .ropsten, .rinkeby, .heco, .heco_testnet, .fantom, .fantom_testnet, .avalanche_testnet, .mumbai_testnet, .custom:
return false
}
}
^ This can be used to build a token contract + server <-> CoinGecko token ID mapping from the results of the /api/v3/coins/list
endpoint
^ This can be used to build a token contract + server <-> CoinGecko token ID mapping from the results of the
/api/v3/coins/list
endpoint
So you use that mapping to find a symbol match then use the corresponding 'id' in the api/v3/coins/ route?
EG {"id":"aave-dai","symbol":"adai","name":"Aave DAI"}
Do you need to disambiguate clashing symbols using the full name?
So you use that mapping to find a symbol match then use the corresponding 'id' in the api/v3/coins/ route?
Do you mean api/v3/coins/ethereum/market_chart
? Yes. But only if contract matching fails. Didn't check if name matching would give good matches.
Contract matching? There's no address in the results I saw. Is there a way to get the addresses? I can only see symbol and name.
It’s in the platforms dictionary. Oh. Maybe you need to set a query parameter to include it when fetching the list of supported tokens. See how it the pseudo code above we compare it.
It’s in the platforms dictionary. Oh. Maybe you need to set a query parameter to include it when fetching the list of supported tokens. See how it the pseudo code above we compare it.
What's the actual route to get the addresses? I looked at the pseudo code but couldn't get where you form the route. I tried adding the platform name in but couldn't get any correct response. I can only ever get symbol/name for the tokens from the /api/v3/coins/list
mapping.
There are 3 endpoints involved:
A. Fetch CoinGecko token IDs for supported tokens: curl 'https://api.coingecko.com/api/v3/coins/list?include_platform=true'
B. Fetch token prices given a list of token IDs: curl 'https://api.coingecko.com/api/v3/coins/markets?ids=ethereum%2Cweth%2Csai%2Cuniswap%2Camber%2Ctether%2Ckickico%2Cusd-coin%2Cdai%2Cwaifu-token%2Chuobi-token%2Cscatter-cx%2Cnest%2Cntoken0031%2C0x&page=1&per_page=250&price_change_percentage=24h&vs_currency=USD'
C. Fetch chart history given 1 token ID: curl 'https://api.coingecko.com/api/v3/coins/ethereum/market_chart?days=7&vs_currency=USD'
(A) Would get you something like this with contracts for their respective chains (the pseudo code above includes the platform mapping table):
{
"id": "dai",
"symbol": "dai",
"name": "Dai",
"platforms": {
"ethereum": "0x6b175474e89094c44da98b954eedeac495271d0f",
"binance-smart-chain": "0x1af3f329e8be154074d8769d1ffa4ee058b1dbc3",
"polygon-pos": "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063"
}
}
The contracts are sometimes empty strings (refer to pseduo code above):
{
"id": "gooddollar",
"symbol": "$G",
"name": "GoodDollar",
"platforms": {
"ethereum": ""
}
}
Sometimes the platforms dictionary is empty too:
{
"id": "01coin",
"symbol": "zoc",
"name": "01coin",
"platforms": {}
}
Use this to build the token in Realm to CoinGecko token ID mapping.
(B) Pass in the list of token IDs from the mapping table built from calling (A). Note that this paginates. On iOS, we just page through until there are no results
On iOS, we call (A) and (B) once only no matter which/how many chains are enabled. Cache (A), call (B) again for fresh data.
(C) Call this for all the periods (1, 7, etc) only when the token screen needs to be displayed. Currently caching the data for days=1
for a 1 hour and caching the rest (7, 30, etc) until app restarts. Might tweak it when we build the UI.
Thanks :), include_platform=true is the key add-on I needed, once you add that then you get all the token addresses. The platform listing is quite useful.
I was considering a similar caching pattern, will only load it when user click on the token.
Updated mapping for platforms at https://github.com/AlphaWallet/alpha-wallet-ios/blob/02a2541c41b705b79c5c8b889de9f1a91bf9a9f3/AlphaWallet/Core/CoinTicker/CoinTickersFetcher.swift#L318
Notably, Fantom is supported and there was a typo in "avalanche" earlier (it was uppercase).
Presumably already WIP for other Samoa issues like #1770. Closing for now.
To get the historical data, just do (where "ethereum" is CoinGecko's token id for Ether):
You can substitute
days
for 1, 7, 30, 90, 360 which should match what we need