diff --git a/blockchains/ethereum/tokenlist_base.json b/blockchains/ethereum/tokenlist_base.json new file mode 100644 index 000000000..45bf653c8 --- /dev/null +++ b/blockchains/ethereum/tokenlist_base.json @@ -0,0 +1,655 @@ +{ + "name": "Trust Wallet: Ethereum", + "logoURI": "https://trustwallet.com/assets/images/favicon.png", + "keywords": [], + "timestamp": "2020-10-03T12:37:57.000+00:00", + "tokens": [ + { + "chainId": 1, + "asset": "c60_t0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "type": "ERC20", + "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "name": "Wrapped Ethereum", + "symbol": "WETH", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png", + "pairs": [ + { + "base": "c60_t0x0000000000085d4780B73119b644AE5ecd22b376" + }, + { + "base": "c60_t0x0Ae055097C6d159879521C384F1D2123D1f195e6" + }, + { + "base": "c60_t0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e" + }, + { + "base": "c60_t0x0D8775F648430679A709E98d2b0Cb6250d2887EF" + }, + { + "base": "c60_t0x0F5D2fB29fb7d3CFeE444a200298f468908cC942" + }, + { + "base": "c60_t0x111111111117dC0aa78b770fA6A738034120C302" + }, + { + "base": "c60_t0x1985365e9f78359a9B6AD760e32412f4a445E862" + }, + { + "base": "c60_t0x1cEB5cB57C4D4E2b2433641b95Dd330A33185A44" + }, + { + "base": "c60_t0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984" + }, + { + "base": "c60_t0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599" + }, + { + "base": "c60_t0x2b591e99afE9f32eAA6214f7B7629768c40Eeb39" + }, + { + "base": "c60_t0x2ba592F78dB6436527729929AAf6c908497cB200" + }, + { + "base": "c60_t0x37236CD05b34Cc79d3715AF2383E96dd7443dCF1" + }, + { + "base": "c60_t0x408e41876cCCDC0F92210600ef50372656052a38" + }, + { + "base": "c60_t0x40FD72257597aA14C7231A7B1aaa29Fce868F677" + }, + { + "base": "c60_t0x4Fabb145d64652a948d72533023f6E7A623C7C53" + }, + { + "base": "c60_t0x514910771AF9Ca656af840dff83E8264EcF986CA" + }, + { + "base": "c60_t0x57Ab1ec28D129707052df4dF418D58a2D46d5f51" + }, + { + "base": "c60_t0x584bC13c7D411c00c01A62e8019472dE68768430" + }, + { + "base": "c60_t0x607F4C5BB672230e8672085532f7e901544a7375" + }, + { + "base": "c60_t0x6B175474E89094C44Da98b954EedeAC495271d0F" + }, + { + "base": "c60_t0x6B3595068778DD592e39A122f4f5a5cF09C90fE2" + }, + { + "base": "c60_t0x6BFf2fE249601ed0Db3a87424a2E923118BB0312" + }, + { + "base": "c60_t0x740623d2c797b7D8D1EcB98e9b4Afcf99Ec31E14" + }, + { + "base": "c60_t0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9" + }, + { + "base": "c60_t0x80fB784B7eD66730e8b1DBd9820aFD29931aab03" + }, + { + "base": "c60_t0x8400D94A5cb0fa0D041a3788e395285d61c9ee5e" + }, + { + "base": "c60_t0x84cA8bc7997272c7CfB4D0Cd3D55cd942B3c9419" + }, + { + "base": "c60_t0x8762db106B2c2A0bccB3A80d1Ed41273552616E8" + }, + { + "base": "c60_t0x8CE9137d39326AD0cD6491fb5CC0CbA0e089b6A9" + }, + { + "base": "c60_t0x967da4048cD07aB37855c090aAF366e4ce1b9F48" + }, + { + "base": "c60_t0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2" + }, + { + "base": "c60_t0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" + }, + { + "base": "c60_t0xaaAEBE6Fe48E54f431b0C390CfaF0b017d09D42d" + }, + { + "base": "c60_t0xba100000625a3754423978a60c9317c58a424e3D" + }, + { + "base": "c60_t0xBA11D00c5f74255f56a5E366F4F77f5A186d7f55" + }, + { + "base": "c60_t0xc00e94Cb662C3520282E6f5717214004A7f26888" + }, + { + "base": "c60_t0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F" + }, + { + "base": "c60_t0xd26114cd6EE289AccF82350c8d8487fedB8A0C07" + }, + { + "base": "c60_t0xD46bA6D942050d489DBd938a2C909A5d5039A161" + }, + { + "base": "c60_t0xdAC17F958D2ee523a2206206994597C13D831ec7" + }, + { + "base": "c60_t0xdd974D5C2e2928deA5F71b9825b8b646686BD200" + }, + { + "base": "c60_t0xE41d2489571d322189246DaFA5ebDe1F4699F498" + }, + { + "base": "c60_t0xF5D669627376EBd411E34b98F19C868c8ABA5ADA" + }, + { + "base": "c60_t0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c" + } + ] + }, + { + "chainId": 1, + "asset": "c60_t0x0000000000085d4780B73119b644AE5ecd22b376", + "type": "ERC20", + "address": "0x0000000000085d4780B73119b644AE5ecd22b376", + "name": "TrueUSD", + "symbol": "TUSD", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x0000000000085d4780B73119b644AE5ecd22b376/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x0Ae055097C6d159879521C384F1D2123D1f195e6", + "type": "ERC20", + "address": "0x0Ae055097C6d159879521C384F1D2123D1f195e6", + "name": "xDai", + "symbol": "STAKE", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x0Ae055097C6d159879521C384F1D2123D1f195e6/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e", + "type": "ERC20", + "address": "0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e", + "name": "Yearn.Finance", + "symbol": "YFI", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x0D8775F648430679A709E98d2b0Cb6250d2887EF", + "type": "ERC20", + "address": "0x0D8775F648430679A709E98d2b0Cb6250d2887EF", + "name": "Basic Attention Token", + "symbol": "BAT", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x0D8775F648430679A709E98d2b0Cb6250d2887EF/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x0F5D2fB29fb7d3CFeE444a200298f468908cC942", + "type": "ERC20", + "address": "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942", + "name": "Decentraland MANA", + "symbol": "MANA", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x0F5D2fB29fb7d3CFeE444a200298f468908cC942/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x111111111117dC0aa78b770fA6A738034120C302", + "type": "ERC20", + "address": "0x111111111117dC0aa78b770fA6A738034120C302", + "name": "1INCH Token", + "symbol": "1INCH", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x111111111117dC0aa78b770fA6A738034120C302/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x1985365e9f78359a9B6AD760e32412f4a445E862", + "type": "ERC20", + "address": "0x1985365e9f78359a9B6AD760e32412f4a445E862", + "name": "Reputation", + "symbol": "REP", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x1985365e9f78359a9B6AD760e32412f4a445E862/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x1cEB5cB57C4D4E2b2433641b95Dd330A33185A44", + "type": "ERC20", + "address": "0x1cEB5cB57C4D4E2b2433641b95Dd330A33185A44", + "name": "Keep3rV1", + "symbol": "KP3R", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x1cEB5cB57C4D4E2b2433641b95Dd330A33185A44/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984", + "type": "ERC20", + "address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984", + "name": "Uniswap", + "symbol": "UNI", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", + "type": "ERC20", + "address": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", + "name": "Wrapped BTC", + "symbol": "WBTC", + "decimals": 8, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x2b591e99afE9f32eAA6214f7B7629768c40Eeb39", + "type": "ERC20", + "address": "0x2b591e99afE9f32eAA6214f7B7629768c40Eeb39", + "name": "HEX", + "symbol": "HEX", + "decimals": 8, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x2b591e99afE9f32eAA6214f7B7629768c40Eeb39/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x2ba592F78dB6436527729929AAf6c908497cB200", + "type": "ERC20", + "address": "0x2ba592F78dB6436527729929AAf6c908497cB200", + "name": "Cream", + "symbol": "CREAM", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x2ba592F78dB6436527729929AAf6c908497cB200/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x37236CD05b34Cc79d3715AF2383E96dd7443dCF1", + "type": "ERC20", + "address": "0x37236CD05b34Cc79d3715AF2383E96dd7443dCF1", + "name": "Small Love Potion", + "symbol": "SLP", + "decimals": 0, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x37236CD05b34Cc79d3715AF2383E96dd7443dCF1/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x408e41876cCCDC0F92210600ef50372656052a38", + "type": "ERC20", + "address": "0x408e41876cCCDC0F92210600ef50372656052a38", + "name": "Republic Token", + "symbol": "REN", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x408e41876cCCDC0F92210600ef50372656052a38/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x40FD72257597aA14C7231A7B1aaa29Fce868F677", + "type": "ERC20", + "address": "0x40FD72257597aA14C7231A7B1aaa29Fce868F677", + "name": "Sora", + "symbol": "XOR", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x40FD72257597aA14C7231A7B1aaa29Fce868F677/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x4Fabb145d64652a948d72533023f6E7A623C7C53", + "type": "ERC20", + "address": "0x4Fabb145d64652a948d72533023f6E7A623C7C53", + "name": "Binance USD", + "symbol": "BUSD", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x4Fabb145d64652a948d72533023f6E7A623C7C53/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x514910771AF9Ca656af840dff83E8264EcF986CA", + "type": "ERC20", + "address": "0x514910771AF9Ca656af840dff83E8264EcF986CA", + "name": "ChainLink", + "symbol": "Link", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x514910771AF9Ca656af840dff83E8264EcF986CA/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x57Ab1ec28D129707052df4dF418D58a2D46d5f51", + "type": "ERC20", + "address": "0x57Ab1ec28D129707052df4dF418D58a2D46d5f51", + "name": "Synth sUSD", + "symbol": "sUSD", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x57Ab1ec28D129707052df4dF418D58a2D46d5f51/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x584bC13c7D411c00c01A62e8019472dE68768430", + "type": "ERC20", + "address": "0x584bC13c7D411c00c01A62e8019472dE68768430", + "name": "Hegic", + "symbol": "HEGIC", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x584bC13c7D411c00c01A62e8019472dE68768430/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x607F4C5BB672230e8672085532f7e901544a7375", + "type": "ERC20", + "address": "0x607F4C5BB672230e8672085532f7e901544a7375", + "name": "iExec RLC", + "symbol": "RLC", + "decimals": 9, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x607F4C5BB672230e8672085532f7e901544a7375/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x6B175474E89094C44Da98b954EedeAC495271d0F", + "type": "ERC20", + "address": "0x6B175474E89094C44Da98b954EedeAC495271d0F", + "name": "Dai Stablecoin", + "symbol": "DAI", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x6B175474E89094C44Da98b954EedeAC495271d0F/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x6B3595068778DD592e39A122f4f5a5cF09C90fE2", + "type": "ERC20", + "address": "0x6B3595068778DD592e39A122f4f5a5cF09C90fE2", + "name": "SushiSwap", + "symbol": "SUSHI", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x6B3595068778DD592e39A122f4f5a5cF09C90fE2/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x6BFf2fE249601ed0Db3a87424a2E923118BB0312", + "type": "ERC20", + "address": "0x6BFf2fE249601ed0Db3a87424a2E923118BB0312", + "name": "Fyooz", + "symbol": "FYZ", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x6BFf2fE249601ed0Db3a87424a2E923118BB0312/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x740623d2c797b7D8D1EcB98e9b4Afcf99Ec31E14", + "type": "ERC20", + "address": "0x740623d2c797b7D8D1EcB98e9b4Afcf99Ec31E14", + "name": "DoYourTip", + "symbol": "DYT", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x740623d2c797b7D8D1EcB98e9b4Afcf99Ec31E14/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9", + "type": "ERC20", + "address": "0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9", + "name": "Aave Token", + "symbol": "AAVE", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x80fB784B7eD66730e8b1DBd9820aFD29931aab03", + "type": "ERC20", + "address": "0x80fB784B7eD66730e8b1DBd9820aFD29931aab03", + "name": "Lend", + "symbol": "LEND", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x80fB784B7eD66730e8b1DBd9820aFD29931aab03/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x8400D94A5cb0fa0D041a3788e395285d61c9ee5e", + "type": "ERC20", + "address": "0x8400D94A5cb0fa0D041a3788e395285d61c9ee5e", + "name": "Unibright", + "symbol": "UBT", + "decimals": 8, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x8400D94A5cb0fa0D041a3788e395285d61c9ee5e/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x84cA8bc7997272c7CfB4D0Cd3D55cd942B3c9419", + "type": "ERC20", + "address": "0x84cA8bc7997272c7CfB4D0Cd3D55cd942B3c9419", + "name": "DIA", + "symbol": "DIA", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x84cA8bc7997272c7CfB4D0Cd3D55cd942B3c9419/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x8762db106B2c2A0bccB3A80d1Ed41273552616E8", + "type": "ERC20", + "address": "0x8762db106B2c2A0bccB3A80d1Ed41273552616E8", + "name": "Reserve Rights", + "symbol": "RSR", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x8762db106B2c2A0bccB3A80d1Ed41273552616E8/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x8CE9137d39326AD0cD6491fb5CC0CbA0e089b6A9", + "type": "ERC20", + "address": "0x8CE9137d39326AD0cD6491fb5CC0CbA0e089b6A9", + "name": "Swipe", + "symbol": "SXP", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x8CE9137d39326AD0cD6491fb5CC0CbA0e089b6A9/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x967da4048cD07aB37855c090aAF366e4ce1b9F48", + "type": "ERC20", + "address": "0x967da4048cD07aB37855c090aAF366e4ce1b9F48", + "name": "Ocean Protocol", + "symbol": "OCEAN", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x967da4048cD07aB37855c090aAF366e4ce1b9F48/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2", + "type": "ERC20", + "address": "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2", + "name": "MakerDAO", + "symbol": "MKR", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + "type": "ERC20", + "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + "name": "USDC", + "symbol": "USDC", + "decimals": 6, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0xaaAEBE6Fe48E54f431b0C390CfaF0b017d09D42d", + "type": "ERC20", + "address": "0xaaAEBE6Fe48E54f431b0C390CfaF0b017d09D42d", + "name": "Celsius", + "symbol": "CEL", + "decimals": 4, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xaaAEBE6Fe48E54f431b0C390CfaF0b017d09D42d/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0xba100000625a3754423978a60c9317c58a424e3D", + "type": "ERC20", + "address": "0xba100000625a3754423978a60c9317c58a424e3D", + "name": "Balancer", + "symbol": "BAL", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xba100000625a3754423978a60c9317c58a424e3D/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0xBA11D00c5f74255f56a5E366F4F77f5A186d7f55", + "type": "ERC20", + "address": "0xBA11D00c5f74255f56a5E366F4F77f5A186d7f55", + "name": "BandToken", + "symbol": "BAND", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xBA11D00c5f74255f56a5E366F4F77f5A186d7f55/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0xc00e94Cb662C3520282E6f5717214004A7f26888", + "type": "ERC20", + "address": "0xc00e94Cb662C3520282E6f5717214004A7f26888", + "name": "Compound", + "symbol": "COMP", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xc00e94Cb662C3520282E6f5717214004A7f26888/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F", + "type": "ERC20", + "address": "0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F", + "name": "Synthetix Network Token", + "symbol": "SNX", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets//logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0xd26114cd6EE289AccF82350c8d8487fedB8A0C07", + "type": "ERC20", + "address": "0xd26114cd6EE289AccF82350c8d8487fedB8A0C07", + "name": "OMG Network", + "symbol": "OMG", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets//logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0xD46bA6D942050d489DBd938a2C909A5d5039A161", + "type": "ERC20", + "address": "0xD46bA6D942050d489DBd938a2C909A5d5039A161", + "name": "Ampleforth", + "symbol": "AMPL", + "decimals": 9, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets//logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0xdAC17F958D2ee523a2206206994597C13D831ec7", + "type": "ERC20", + "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7", + "name": "Tether USD", + "symbol": "USDT", + "decimals": 6, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xdAC17F958D2ee523a2206206994597C13D831ec7/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0xdd974D5C2e2928deA5F71b9825b8b646686BD200", + "type": "ERC20", + "address": "0xdd974D5C2e2928deA5F71b9825b8b646686BD200", + "name": "Kyber Network Crystal", + "symbol": "KNC", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xdd974D5C2e2928deA5F71b9825b8b646686BD200/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0xE41d2489571d322189246DaFA5ebDe1F4699F498", + "type": "ERC20", + "address": "0xE41d2489571d322189246DaFA5ebDe1F4699F498", + "name": "0x Protocol Token", + "symbol": "ZRX", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xE41d2489571d322189246DaFA5ebDe1F4699F498/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0xF5D669627376EBd411E34b98F19C868c8ABA5ADA", + "type": "ERC20", + "address": "0xF5D669627376EBd411E34b98F19C868c8ABA5ADA", + "name": "Axie Infinity", + "symbol": "AXS", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xF5D669627376EBd411E34b98F19C868c8ABA5ADA/logo.png", + "pairs": [] + }, + { + "chainId": 1, + "asset": "c60_t0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c", + "type": "ERC20", + "address": "0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c", + "name": "Enjin Coin", + "symbol": "ENJ", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xF629cBd94d3791C9250152BD8dfBDF380E2a3B9c/logo.png", + "pairs": [] + } + ], + "version": { + "major": 0, + "minor": 2, + "patch": 0 + } +} \ No newline at end of file diff --git a/blockchains/smartchain/tokenlist_base.json b/blockchains/smartchain/tokenlist_base.json new file mode 100644 index 000000000..e14a44659 --- /dev/null +++ b/blockchains/smartchain/tokenlist_base.json @@ -0,0 +1,232 @@ +{ + "name": "Trust Wallet: Smart Chain", + "logoURI": "https://trustwallet.com/assets/images/favicon.png", + "keywords": [], + "timestamp": "2020-10-03T12:37:57.000+00:00", + "tokens": [ + { + "chainId": 56, + "asset": "c20000714_t0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + "type": "BEP20", + "address": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + "name": "Wrapped BNB", + "symbol": "WBNB", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c/logo.png", + "pairs": [ + { + "base": "c20000714_t0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82" + }, + { + "base": "c20000714_t0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3" + }, + { + "base": "c20000714_t0x2170Ed0880ac9A755fd29B2688956BD959F933F8" + }, + { + "base": "c20000714_t0x4B0F1812e5Df2A09796481Ff14017e6005508003" + }, + { + "base": "c20000714_t0x4BD17003473389A42DAF6a0a729f6Fdb328BbBd7" + }, + { + "base": "c20000714_t0x55d398326f99059fF775485246999027B3197955" + }, + { + "base": "c20000714_t0x63870A18B6e42b01Ef1Ad8A2302ef50B7132054F" + }, + { + "base": "c20000714_t0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c" + }, + { + "base": "c20000714_t0xa1faa113cbE53436Df28FF0aEe54275c13B40975" + }, + { + "base": "c20000714_t0xa2B726B1145A4773F68593CF171187d8EBe4d495" + }, + { + "base": "c20000714_t0xBf5140A22578168FD562DCcF235E5D43A02ce9B1" + }, + { + "base": "c20000714_t0xcF6BB5389c92Bdda8a3747Ddb454cB7a64626C63" + }, + { + "base": "c20000714_t0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56" + }, + { + "base": "c20000714_t0xf79037F6f6bE66832DE4E7516be52826BC3cBcc4" + } + ] + }, + { + "chainId": 56, + "asset": "c20000714_t0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82", + "type": "BEP20", + "address": "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82", + "name": "PancakeSwap Token", + "symbol": "Cake", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82/logo.png", + "pairs": [] + }, + { + "chainId": 56, + "asset": "c20000714_t0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3", + "type": "BEP20", + "address": "0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3", + "name": "Binance-Peg Dai Token", + "symbol": "DAI", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3/logo.png", + "pairs": [] + }, + { + "chainId": 56, + "asset": "c20000714_t0x2170Ed0880ac9A755fd29B2688956BD959F933F8", + "type": "BEP20", + "address": "0x2170Ed0880ac9A755fd29B2688956BD959F933F8", + "name": "Ethereum Token", + "symbol": "ETH", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0x2170Ed0880ac9A755fd29B2688956BD959F933F8/logo.png", + "pairs": [] + }, + { + "chainId": 56, + "asset": "c20000714_t0x4B0F1812e5Df2A09796481Ff14017e6005508003", + "type": "BEP20", + "address": "0x4B0F1812e5Df2A09796481Ff14017e6005508003", + "name": "Trust Wallet", + "symbol": "TWT", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0x4B0F1812e5Df2A09796481Ff14017e6005508003/logo.png", + "pairs": [] + }, + { + "chainId": 56, + "asset": "c20000714_t0x4BD17003473389A42DAF6a0a729f6Fdb328BbBd7", + "type": "BEP20", + "address": "0x4BD17003473389A42DAF6a0a729f6Fdb328BbBd7", + "name": "VAI Stablecoin", + "symbol": "VAI", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0x4BD17003473389A42DAF6a0a729f6Fdb328BbBd7/logo.png", + "pairs": [] + }, + { + "chainId": 56, + "asset": "c20000714_t0x55d398326f99059fF775485246999027B3197955", + "type": "BEP20", + "address": "0x55d398326f99059fF775485246999027B3197955", + "name": "Binance-Peg Tether USD", + "symbol": "USDT", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0x55d398326f99059fF775485246999027B3197955/logo.png", + "pairs": [] + }, + { + "chainId": 56, + "asset": "c20000714_t0x63870A18B6e42b01Ef1Ad8A2302ef50B7132054F", + "type": "BEP20", + "address": "0x63870A18B6e42b01Ef1Ad8A2302ef50B7132054F", + "name": "BLink Token", + "symbol": "BLINK", + "decimals": 6, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0x63870A18B6e42b01Ef1Ad8A2302ef50B7132054F/logo.png", + "pairs": [] + }, + { + "chainId": 56, + "asset": "c20000714_t0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c", + "type": "BEP20", + "address": "0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c", + "name": "Binance-Peg BTCB Token", + "symbol": "BTCB", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c/logo.png", + "pairs": [] + }, + { + "chainId": 56, + "asset": "c20000714_t0xa1faa113cbE53436Df28FF0aEe54275c13B40975", + "type": "BEP20", + "address": "0xa1faa113cbE53436Df28FF0aEe54275c13B40975", + "name": "Alpha Token", + "symbol": "ALPHA", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0xa1faa113cbE53436Df28FF0aEe54275c13B40975/logo.png", + "pairs": [] + }, + { + "chainId": 56, + "asset": "c20000714_t0xa2B726B1145A4773F68593CF171187d8EBe4d495", + "type": "BEP20", + "address": "0xa2B726B1145A4773F68593CF171187d8EBe4d495", + "name": "Injective Protocol", + "symbol": "INJ", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0xa2B726B1145A4773F68593CF171187d8EBe4d495/logo.png", + "pairs": [] + }, + { + "chainId": 56, + "asset": "c20000714_t0xA8c2B8eec3d368C0253ad3dae65a5F2BBB89c929", + "type": "BEP20", + "address": "0xA8c2B8eec3d368C0253ad3dae65a5F2BBB89c929", + "name": "CertiK Token", + "symbol": "CTK", + "decimals": 6, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0xA8c2B8eec3d368C0253ad3dae65a5F2BBB89c929/logo.png", + "pairs": [] + }, + { + "chainId": 56, + "asset": "c20000714_t0xBf5140A22578168FD562DCcF235E5D43A02ce9B1", + "type": "BEP20", + "address": "0xBf5140A22578168FD562DCcF235E5D43A02ce9B1", + "name": "Binance-Peg Uniswap", + "symbol": "UNI", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0xBf5140A22578168FD562DCcF235E5D43A02ce9B1/logo.png", + "pairs": [] + }, + { + "chainId": 56, + "asset": "c20000714_t0xcF6BB5389c92Bdda8a3747Ddb454cB7a64626C63", + "type": "BEP20", + "address": "0xcF6BB5389c92Bdda8a3747Ddb454cB7a64626C63", + "name": "Venus", + "symbol": "XVS", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0xcF6BB5389c92Bdda8a3747Ddb454cB7a64626C63/logo.png", + "pairs": [] + }, + { + "chainId": 56, + "asset": "c20000714_t0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56", + "type": "BEP20", + "address": "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56", + "name": "BUSD", + "symbol": "BUSD", + "decimals": 18, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56/logo.png", + "pairs": [] + }, + { + "chainId": 56, + "asset": "c20000714_t0xf79037F6f6bE66832DE4E7516be52826BC3cBcc4", + "type": "BEP20", + "address": "0xf79037F6f6bE66832DE4E7516be52826BC3cBcc4", + "name": "Hard Protocol", + "symbol": "HARD", + "decimals": 6, + "logoURI": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/smartchain/assets/0xf79037F6f6bE66832DE4E7516be52826BC3cBcc4/logo.png", + "pairs": [] + } + ], + "version": { + "major": 0, + "minor": 1, + "patch": 0 + } +} \ No newline at end of file diff --git a/script/blockchain/binance.ts b/script/blockchain/binance.ts index ea5dbbbfe..5f22fea2a 100644 --- a/script/blockchain/binance.ts +++ b/script/blockchain/binance.ts @@ -8,7 +8,7 @@ import { ActionInterface, CheckStepInterface } from "../generic/interface"; import { Binance } from "../generic/blockchains"; import { readDirSync } from "../generic/filesystem"; import { readJsonFile } from "../generic/json"; -import { TokenItem, Pair, generateTokensList, writeToFileWithUpdate } from "../generic/tokenlists"; +import { TokenItem, Pair, createTokensList, writeToFileWithUpdate } from "../generic/tokenlists"; import { getChainAssetLogoPath, getChainAssetsPath, @@ -140,7 +140,7 @@ export class BinanceAction implements ActionInterface { // binance chain list const tokenList = await generateBinanceTokensList(); - const list = generateTokensList("BNB", tokenList, + const list = createTokensList("BNB", tokenList, "2020-10-03T12:37:57.000+00:00", // use constants here to prevent changing time every time 0, 1, 0); writeToFileWithUpdate(getChainTokenlistPath(Binance), list); diff --git a/script/blockchain/ethereum.ts b/script/blockchain/ethereum.ts new file mode 100644 index 000000000..06a021045 --- /dev/null +++ b/script/blockchain/ethereum.ts @@ -0,0 +1,90 @@ +import { ActionInterface, CheckStepInterface } from "../generic/interface"; +import { + checkTradingPair, + getTradingPairs, + PairInfo, + primaryTokenIndex, + TokenInfo +} from "../generic/subgraph"; +import { getChainAllowlistPath } from "../generic/repo-structure"; +import { Ethereum } from "../generic/blockchains"; +import { readJsonFile } from "../generic/json"; +import { + rebuildTokenlist, + TokenItem +} from "../generic/tokenlists"; +import { toChecksum } from "../generic/eth-address"; +import { assetID, logoURI } from "../generic/asset"; +import * as config from "../config" + +const PrimaryTokens: string[] = ["WETH", "ETH"]; + +// Retrieve trading pairs from Uniswap +async function retrieveUniswapPairs(): Promise { + console.log(`Retrieving pairs from Uniswap, limit liquidity USD ${config.Uniswap_MinLiquidity} volume ${config.Uniswap_MinVol24} txcount ${config.Uniswap_MinTxCount24}`); + + // prepare phase, read allowlist + const allowlist: string[] = readJsonFile(getChainAllowlistPath(Ethereum)) as string[]; + + const pairs = await getTradingPairs(config.Uniswap_TradingPairsUrl, config.Uniswap_TradingPairsQuery); + const filtered: PairInfo[] = []; + pairs.forEach(x => { + try { + if (typeof(x) === "object") { + const pairInfo = x as PairInfo; + if (pairInfo) { + if (checkTradingPair(pairInfo, Ethereum, config.Uniswap_MinLiquidity, config.Uniswap_MinVol24, config.Uniswap_MinTxCount24, allowlist, PrimaryTokens)) { + filtered.push(pairInfo); + } + } + } + } catch (err) { + console.log("Exception:", err); + } + }); + + console.log("Retrieved & filtered", filtered.length, "pairs:"); + filtered.forEach(p => { + console.log(`pair: ${p.token0.symbol} -- ${p.token1.symbol} \t USD ${Math.round(p.reserveUSD)} ${Math.round(p.volumeUSD)} ${p.txCount}`); + }); + + return filtered; +} + +function tokenInfoFromSubgraphToken(token: TokenInfo): TokenItem { + const idChecksum = toChecksum(token.id); + return new TokenItem( + assetID(60, idChecksum), + "ERC20", + idChecksum, token.name, token.symbol, parseInt(token.decimals.toString()), + logoURI(idChecksum, "ethereum", "--"), + []); +} + +// Retrieve trading pairs from PancakeSwap +async function generateTokenlist(): Promise { + // note: if [] is returned here for some reason, all pairs will be *removed*. In case of error (e.g. timeout) it should throw + const tradingPairs = await retrieveUniswapPairs(); + // convert + const pairs2: [TokenItem, TokenItem][] = []; + tradingPairs.forEach(p => { + let tokenItem0 = tokenInfoFromSubgraphToken(p.token0); + let tokenItem1 = tokenInfoFromSubgraphToken(p.token1); + if (primaryTokenIndex(p, PrimaryTokens) == 2) { + // reverse + const tmp = tokenItem1; tokenItem1 = tokenItem0; tokenItem0 = tmp; + } + pairs2.push([tokenItem0, tokenItem1]); + }); + await rebuildTokenlist(Ethereum, pairs2, "Ethereum"); +} + +export class EthereumAction implements ActionInterface { + getName(): string { return "Ethereum"; } + + getSanityChecks(): CheckStepInterface[] { return []; } + + async update(): Promise { + await generateTokenlist(); + } +} diff --git a/script/blockchain/smartchain.ts b/script/blockchain/smartchain.ts new file mode 100644 index 000000000..74186a5c4 --- /dev/null +++ b/script/blockchain/smartchain.ts @@ -0,0 +1,89 @@ +import { ActionInterface, CheckStepInterface } from "../generic/interface"; +import { + checkTradingPair, + getTradingPairs, + PairInfo, + primaryTokenIndex, + TokenInfo +} from "../generic/subgraph"; +import { getChainAllowlistPath } from "../generic/repo-structure"; +import { SmartChain } from "../generic/blockchains"; +import { + rebuildTokenlist, + TokenItem +} from "../generic/tokenlists"; +import { readJsonFile } from "../generic/json"; +import { toChecksum } from "../generic/eth-address"; +import { assetID, logoURI } from "../generic/asset"; +import * as config from "../config" + +const PrimaryTokens: string[] = ["WBNB", "BNB"]; + +async function retrievePancakeSwapPairs(): Promise { + console.log(`Retrieving pairs from PancakeSwap, limit liquidity USD ${config.PancakeSwap_MinLiquidity} volume ${config.PancakeSwap_MinVol24} txcount ${config.PancakeSwap_MinTxCount24}`); + + // prepare phase, read allowlist + const allowlist: string[] = readJsonFile(getChainAllowlistPath(SmartChain)) as string[]; + + const pairs = await getTradingPairs(config.PancakeSwap_TradingPairsUrl, config.PancakeSwap_TradingPairsQuery); + const filtered: PairInfo[] = []; + pairs.forEach(x => { + try { + if (typeof(x) === "object") { + const pairInfo = x as PairInfo; + if (pairInfo) { + if (checkTradingPair(pairInfo, SmartChain, config.PancakeSwap_MinLiquidity, config.PancakeSwap_MinVol24, config.PancakeSwap_MinTxCount24, allowlist, PrimaryTokens)) { + filtered.push(pairInfo); + } + } + } + } catch (err) { + console.log("Exception:", err); + } + }); + + console.log("Retrieved & filtered", filtered.length, "pairs:"); + filtered.forEach(p => { + console.log(`pair: ${p.token0.symbol} -- ${p.token1.symbol} \t USD ${Math.round(p.reserveUSD)} ${Math.round(p.volumeUSD)} ${p.txCount}`); + }); + + return filtered; +} + +function tokenInfoFromSubgraphToken(token: TokenInfo): TokenItem { + const idChecksum = toChecksum(token.id); + return new TokenItem( + assetID(20000714, idChecksum), + "BEP20", + idChecksum, token.name, token.symbol, parseInt(token.decimals.toString()), + logoURI(idChecksum, "smartchain", "--"), + []); +} + +// Retrieve trading pairs from PancakeSwap +async function generateTokenlist(): Promise { + // note: if [] is returned here for some reason, all pairs will be *removed*. In case of error (e.g. timeout) it should throw + const tradingPairs = await retrievePancakeSwapPairs(); + // convert + const pairs2: [TokenItem, TokenItem][] = []; + tradingPairs.forEach(p => { + let tokenItem0 = tokenInfoFromSubgraphToken(p.token0); + let tokenItem1 = tokenInfoFromSubgraphToken(p.token1); + if (primaryTokenIndex(p, PrimaryTokens) == 2) { + // reverse + const tmp = tokenItem1; tokenItem1 = tokenItem0; tokenItem0 = tmp; + } + pairs2.push([tokenItem0, tokenItem1]); + }); + await rebuildTokenlist(SmartChain, pairs2, "Smart Chain"); +} + +export class SmartchainAction implements ActionInterface { + getName(): string { return "Binance Smartchain"; } + + getSanityChecks(): CheckStepInterface[] { return []; } + + async update(): Promise { + await generateTokenlist(); + } +} diff --git a/script/config.ts b/script/config.ts index 379c7b0ce..f591db62b 100644 --- a/script/config.ts +++ b/script/config.ts @@ -6,4 +6,39 @@ export const imageMaxLogoSizeKb = 100; export const foldersRootdirAllowedFiles: string[] = [".github", "blockchains", "dapps", "media", "node_modules", "script-old", "script", "test", ".gitignore", "azure-pipelines.yml", "jest.config.js", "LICENSE", "package-lock.json", "package.json", "README.md", ".git", "dangerfile.ts", "Gemfile", "Gemfile.lock", ".eslintignore", ".eslintrc.js"]; export const binanceUrlTokenAssets = "https://explorer.binance.org/api/v1/assets?page=1&rows=1000"; export const binanceDexURL = 'https://dex-atlantic.binance.org/api' -export const assetsURL = 'https://raw.githubusercontent.com/trustwallet/assets/master' \ No newline at end of file +export const assetsURL = 'https://raw.githubusercontent.com/trustwallet/assets/master' + +export const PancakeSwap_TradingPairsUrl = "https://api.bscgraph.org/subgraphs/name/wowswap"; +export const PancakeSwap_TradingPairsQuery = ` + query pairs { + pairs(first: 200, orderBy: reserveUSD, orderDirection: desc) { + id reserveUSD trackedReserveETH volumeUSD txCount untrackedVolumeUSD __typename + token0 { + id symbol name decimals __typename + } + token1 { + id symbol name decimals __typename + } + } + } +`; +export const PancakeSwap_MinLiquidity = 1000000; +export const PancakeSwap_MinVol24 = 500000; +export const PancakeSwap_MinTxCount24 = 288; +export const Uniswap_TradingPairsUrl = "https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v2"; // see https://thegraph.com/explorer/subgraph/uniswap/uniswap-v2 +export const Uniswap_TradingPairsQuery = ` + query pairs { + pairs(first: 400, orderBy: reserveUSD, orderDirection: desc) { + id reserveUSD trackedReserveETH volumeUSD txCount untrackedVolumeUSD __typename + token0 { + id symbol name decimals __typename + } + token1 { + id symbol name decimals __typename + } + } + } +`; +export const Uniswap_MinLiquidity = 2000000; +export const Uniswap_MinVol24 = 1000000; +export const Uniswap_MinTxCount24 = 480; diff --git a/script/generic/asset.ts b/script/generic/asset.ts index 51b1c4fc2..617981584 100644 --- a/script/generic/asset.ts +++ b/script/generic/asset.ts @@ -1,3 +1,4 @@ +import axios from "axios"; import { TokenType } from "../generic/tokentype"; import * as config from "../config"; @@ -32,3 +33,29 @@ export function logoURI(id: string, githubChainFolder: string, nativeCoinSymbol: } return `${config.assetsURL}/blockchains/${githubChainFolder}/assets/${id}/logo.png` } + +// Token info from TW api +// e.g. {"name":"Binance-Peg Cosmos","symbol":"ATOM","type":"BEP20","decimals":18,"asset_id":"c20000714_t0x0Eb3..."} +export class TokenTwInfo { + name: string; + symbol: string; + type: string; + decimals: number; + asset_id: string; +} + +export async function tokenInfoFromTwApi(assetID: string): Promise { + try { + const apiUrl = `https://api.trustwallet.com/v1/assets/${assetID}`; + const result = await axios.get(apiUrl).then(r => r.data); + if (!result || !result.asset_id) { + console.log("Unexpected result", result); + return undefined; + } + const info = result as TokenTwInfo; + return info; + } catch (err) { + console.log("Exception:", err); + return undefined; + } +} diff --git a/script/generic/repo-structure.ts b/script/generic/repo-structure.ts index 7481fc31f..473819c9f 100644 --- a/script/generic/repo-structure.ts +++ b/script/generic/repo-structure.ts @@ -15,6 +15,7 @@ export const infoFullName = `${infoName}.${jsonExtension}`; const allowList = `allowlist.${jsonExtension}`; const denyList = `denylist.${jsonExtension}`; const tokenList = `tokenlist.${jsonExtension}`; +const tokenListBase = `tokenlist_base.${jsonExtension}`; export const validatorsList = `${listName}.${jsonExtension}` export const assetFolderAllowedFiles = [logoFullName, infoFullName]; @@ -23,6 +24,7 @@ export const chainFolderAllowedFiles = [ allowList, denyList, tokenList, + tokenListBase, "validators", infoName ] @@ -37,6 +39,7 @@ export const getChainAssetInfoPath = (chain: string, asset: string): string => ` export const getChainAllowlistPath = (chain: string): string => `${getChainPath(chain)}/${allowList}`; export const getChainDenylistPath = (chain: string): string => `${getChainPath(chain)}/${denyList}`; export const getChainTokenlistPath = (chain: string): string => `${getChainPath(chain)}/${tokenList}`; +export const getChainTokenlistBasePath = (chain: string): string => `${getChainPath(chain)}/${tokenListBase}`; export const pricingFolderPath = path.join(process.cwd(), '/pricing'); export const getChainValidatorsPath = (chain: string): string => `${getChainPath(chain)}/validators`; diff --git a/script/generic/subgraph.ts b/script/generic/subgraph.ts new file mode 100644 index 000000000..79e7bde5f --- /dev/null +++ b/script/generic/subgraph.ts @@ -0,0 +1,104 @@ +// Interfacing with TheGraph subgraph APIs + +import axios from "axios"; +import { getChainAssetLogoPath } from "../generic/repo-structure"; +import { isPathExistsSync } from "../generic/filesystem"; + +export interface TokenInfo { + id: string; + symbol: string; + name: string; + decimals: number; +} + +export interface PairInfo { + id: string; + reserveUSD: number; + volumeUSD: number; + txCount: number; + token0: TokenInfo; + token1: TokenInfo; +} + +export async function getTradingPairs(apiUrl: string, subgraphQuery: string): Promise { + // compact the query string + const compactQuery = subgraphQuery.replace(/(?:\r\n|\r|\n)/g, ' ').replace(/\s[\s]+/g, ' '); + const postData = '{"operationName":"pairs", "variables":{}, "query":"' + compactQuery + '"}'; + + console.log(`Retrieving trading pair infos from: ${apiUrl}`); + try { + const result = await axios.post(apiUrl, postData).then(r => r.data); + if (!result || !result.data || !result.data.pairs) { + throw `Unexpected result: ${result}`; + } + const pairs = result.data.pairs; + console.log(`Retrieved ${pairs.length} trading pair infos`); + return pairs; + } catch (err) { + console.log("Exception from graph api:", err, apiUrl, JSON.stringify(postData)); + throw err; + } +} + +function checkBSCTokenExists(id: string, chainName: string, tokenAllowlist: string[]): boolean { + const logoPath = getChainAssetLogoPath(chainName, id); + if (!isPathExistsSync(logoPath)) { + return false; + } + if (tokenAllowlist.find(t => (id.toLowerCase() === t.toLowerCase())) === undefined) { + //console.log(`Token not found in allowlist, ${id}`); + return false; + } + return true; +} + +function isTokenPrimary(token: TokenInfo, primaryTokens: string[]): boolean { + return (primaryTokens.find(t => (t === token.symbol.toUpperCase())) != undefined); +} + +// check which token of the pair is the primary token, 1st, or 2nd, or 0 for none +export function primaryTokenIndex(pair: PairInfo, primaryTokens: string[]): number { + if (isTokenPrimary(pair.token0, primaryTokens)) { + return 1; + } + if (isTokenPrimary(pair.token1, primaryTokens)) { + return 2; + } + return 0; +} + +// Verify a trading pair, whether we support the tokens, has enough liquidity, etc. +export function checkTradingPair(pair: PairInfo, chainName: string, + minLiquidity: number, minVol24: number, minTxCount24: number, + tokenAllowlist: string[], primaryTokens: string[] +): boolean { + if (!pair.id || !pair.reserveUSD || !pair.volumeUSD || !pair.txCount || !pair.token0 || !pair.token1) { + return false; + } + if (pair.reserveUSD < minLiquidity) { + console.log("pair with low liquidity:", pair.token0.symbol, "--", pair.token1.symbol, " ", Math.round(pair.reserveUSD)); + return false; + } + if (pair.volumeUSD < minVol24) { + console.log("pair with low volume:", pair.token0.symbol, "--", pair.token1.symbol, " ", Math.round(pair.volumeUSD)); + return false; + } + if (pair.txCount < minTxCount24) { + console.log("pair with low tx count:", pair.token0.symbol, "--", pair.token1.symbol, " ", pair.txCount); + return false; + } + if (!checkBSCTokenExists(pair.token0.id, chainName, tokenAllowlist)) { + console.log("pair with unsupported 1st coin:", pair.token0.symbol, "--", pair.token1.symbol); + return false; + } + if (!checkBSCTokenExists(pair.token1.id, chainName, tokenAllowlist)) { + console.log("pair with unsupported 2nd coin:", pair.token0.symbol, "--", pair.token1.symbol); + return false; + } + if (primaryTokenIndex(pair, primaryTokens) == 0) { + console.log("pair with no primary coin:", pair.token0.symbol, "--", pair.token1.symbol); + return false; + } + //console.log("pair:", pair.token0.symbol, "--", pair.token1.symbol, " ", pair.reserveUSD); + return true; +} diff --git a/script/generic/tokenlists.ts b/script/generic/tokenlists.ts index 8cd1a7bec..131c8a0b9 100644 --- a/script/generic/tokenlists.ts +++ b/script/generic/tokenlists.ts @@ -1,5 +1,13 @@ +// Tokenlist.json handling + import { readJsonFile, writeJsonFile } from "../generic/json"; import { diff } from "jsondiffpatch"; +import { tokenInfoFromTwApi, TokenTwInfo } from "../generic/asset"; +import { + getChainTokenlistBasePath, + getChainTokenlistPath +} from "../generic/repo-structure"; +import * as bluebird from "bluebird"; class Version { major: number @@ -64,7 +72,7 @@ export class Pair { } } -export function generateTokensList(titleCoin: string, tokens: TokenItem[], time: string, versionMajor: number, versionMinor = 1, versionPatch = 0): List { +export function createTokensList(titleCoin: string, tokens: TokenItem[], time: string, versionMajor: number, versionMinor = 1, versionPatch = 0): List { if (!time) { time = (new Date()).toISOString(); } @@ -98,26 +106,69 @@ export function writeToFileWithUpdate(filename: string, list: List): void { } catch (err) { listOld = undefined; } - let changed = false; - if (listOld === undefined) { - changed = true; - } else { + if (listOld !== undefined) { list.version = listOld.version; // take over + list.timestamp = listOld.timestamp; // take over const diffs = diffTokenlist(list, listOld); if (diffs != undefined) { //console.log("List has Changed", JSON.stringify(diffs)); - changed = true; list.version = new Version(list.version.major + 1, 0, 0); + list.timestamp = (new Date()).toISOString(); + console.log(`Version and timestamp updated, ${list.version.major}.${list.version.minor}.${list.version.patch} timestamp ${list.timestamp}`); } } - if (changed) { - // update timestqamp - list.timestamp = (new Date()).toISOString(); - console.log(`Version and timestamp updated, ${list.version.major}.${list.version.minor}.${list.version.patch} timestamp ${list.timestamp}`); - } writeToFile(filename, list); } +async function addTokenIfNeeded(token: TokenItem, list: List): Promise { + if (list.tokens.map(t => t.address.toLowerCase()).includes(token.address.toLowerCase())) { + return; + } + token = await updateTokenInfo(token); + list.tokens.push(token); +} + +// Update/fix token info, with properties retrieved from TW API +async function updateTokenInfo(token: TokenItem): Promise { + const tokenInfo: TokenTwInfo = await tokenInfoFromTwApi(token.asset); + if (tokenInfo) { + if (token.name && token.name != tokenInfo.name) { + console.log(`Token name adjusted: '${token.name}' -> '${tokenInfo.name}'`); + token.name = tokenInfo.name; + } + if (token.symbol && token.symbol != tokenInfo.symbol) { + console.log(`Token symbol adjusted: '${token.symbol}' -> '${tokenInfo.symbol}'`); + token.symbol = tokenInfo.symbol; + } + if (token.decimals && token.decimals != tokenInfo.decimals) { + console.log(`Token decimals adjusted: '${token.decimals}' -> '${tokenInfo.decimals}'`); + token.decimals = parseInt(tokenInfo.decimals.toString()); + } + } + return token; +} + +function addPairToToken(pairToken: TokenItem, token: TokenItem, list: List): void { + const tokenInList = list.tokens.find(t => t.address === token.address); + if (!tokenInList) { + return; + } + if (!tokenInList.pairs) { + tokenInList.pairs = []; + } + if (tokenInList.pairs.map(p => p.base).includes(pairToken.asset)) { + return; + } + tokenInList.pairs.push(new Pair(pairToken.asset)); +} + +export async function addPairIfNeeded(token0: TokenItem, token1: TokenItem, list: List): Promise { + await addTokenIfNeeded(token0, list); + await addTokenIfNeeded(token1, list); + addPairToToken(token1, token0, list); + // reverse direction not needed addPairToToken(token0, token1, list); +} + function sort(list: List) { list.tokens.sort((t1, t2) => { const t1pairs = (t1.pairs || []).length; @@ -147,3 +198,33 @@ export function diffTokenlist(listOrig1: List, listOrig2: List): unknown { const diffs = diff(list1, list2); return diffs; } + +export async function rebuildTokenlist(chainName: string, pairs: [TokenItem, TokenItem][], listName: string): Promise { + // sanity check, prevent deletion of many pairs + if (!pairs || pairs.length < 5) { + console.log(`Warning: Only ${pairs.length} pairs returned, ignoring`); + return; + } + + const tokenlistFile = getChainTokenlistPath(chainName); + { + // show current size + const json = readJsonFile(tokenlistFile); + const list: List = json as List; + console.log(`Tokenlist original: ${list.tokens.length} tokens`); + } + const tokenlistBaseFile = getChainTokenlistBasePath(chainName); + const json = readJsonFile(tokenlistBaseFile); + const list: List = json as List; + console.log(`Tokenlist base: ${list.tokens.length} tokens`); + + await bluebird.each(pairs, async (p) => { + await addPairIfNeeded(p[0], p[1], list); + }); + console.log(`Tokenlist updated: ${list.tokens.length} tokens`); + + const newList = createTokensList(listName, list.tokens, + "2021-01-29T01:02:03.000+00:00", // use constant here to prevent changing time every time + 0, 1, 0); + writeToFileWithUpdate(tokenlistFile, newList); +} diff --git a/script/generic/update-all.ts b/script/generic/update-all.ts index e9c2dd599..3eea7f667 100644 --- a/script/generic/update-all.ts +++ b/script/generic/update-all.ts @@ -1,4 +1,6 @@ import { BinanceAction } from "../blockchain/binance"; +import { SmartchainAction } from "../blockchain/smartchain"; +import { EthereumAction } from "../blockchain/ethereum"; import { CosmosAction } from "../blockchain/cosmos"; import { AssetInfos } from "../generic/asset-infos"; import { EthForks } from "../generic/eth-forks"; @@ -26,6 +28,8 @@ const actionList: ActionInterface[] = [ new JsonAction(), // chains: new BinanceAction(), + new SmartchainAction(), + new EthereumAction(), new CosmosAction(), new KavaAction(), new TerraAction(),