From 2e2210371376f480b6093cd66e6b3474a46c29b7 Mon Sep 17 00:00:00 2001 From: Gui Heise Date: Thu, 13 Jan 2022 01:26:53 -0500 Subject: [PATCH] Add coingecko api --- cli.py | 4 +-- mev_inspect/prices.py | 60 +++++++++++---------------------- mev_inspect/schemas/coinbase.py | 20 ----------- mev_inspect/schemas/prices.py | 33 +++++++++++++++++- poetry.lock | 17 +++++++++- pyproject.toml | 1 + 6 files changed, 71 insertions(+), 64 deletions(-) delete mode 100644 mev_inspect/schemas/coinbase.py diff --git a/cli.py b/cli.py index c9c815f..4cbaeb0 100644 --- a/cli.py +++ b/cli.py @@ -8,7 +8,7 @@ from mev_inspect.concurrency import coro from mev_inspect.crud.prices import write_prices from mev_inspect.db import get_inspect_session, get_trace_session from mev_inspect.inspector import MEVInspector -from mev_inspect.prices import fetch_all_supported_prices +from mev_inspect.prices import fetch_prices RPC_URL_ENV = "RPC_URL" @@ -112,7 +112,7 @@ async def fetch_all_prices(): inspect_db_session = get_inspect_session() logger.info("Fetching prices") - prices = await fetch_all_supported_prices() + prices = fetch_prices() logger.info("Writing prices") write_prices(inspect_db_session, prices) diff --git a/mev_inspect/prices.py b/mev_inspect/prices.py index 812bfa3..94816c6 100644 --- a/mev_inspect/prices.py +++ b/mev_inspect/prices.py @@ -1,50 +1,30 @@ +from datetime import datetime as dt from typing import List -from mev_inspect.classifiers.specs.weth import WETH_ADDRESS -from mev_inspect.coinbase import fetch_coinbase_prices -from mev_inspect.schemas.prices import ( - AAVE_TOKEN_ADDRESS, - CDAI_TOKEN_ADDRESS, - CUSDC_TOKEN_ADDRESS, - DAI_TOKEN_ADDRESS, - LINK_TOKEN_ADDRESS, - REN_TOKEN_ADDRESS, - UNI_TOKEN_ADDRESS, - USDC_TOKEN_ADDRESS, - WBTC_TOKEN_ADDRESS, - YEARN_TOKEN_ADDRESS, - Price, -) -from mev_inspect.schemas.transfers import ETH_TOKEN_ADDRESS +from pycoingecko import CoinGeckoAPI -SUPPORTED_TOKENS = [ - AAVE_TOKEN_ADDRESS, - CDAI_TOKEN_ADDRESS, - CUSDC_TOKEN_ADDRESS, - DAI_TOKEN_ADDRESS, - ETH_TOKEN_ADDRESS, - LINK_TOKEN_ADDRESS, - REN_TOKEN_ADDRESS, - UNI_TOKEN_ADDRESS, - USDC_TOKEN_ADDRESS, - WBTC_TOKEN_ADDRESS, - WETH_ADDRESS, - YEARN_TOKEN_ADDRESS, -] +from mev_inspect.schemas.prices import TOKEN_ADDRESSES, TOKEN_NAME_BY_ADDRESS, Price -async def fetch_all_supported_prices() -> List[Price]: +def fetch_prices() -> List[Price]: + cg = CoinGeckoAPI() prices = [] - for token_address in SUPPORTED_TOKENS: - coinbase_prices = await fetch_coinbase_prices(token_address) - for usd_price, timestamp_seconds in coinbase_prices.all.prices: - price = Price( - token_address=token_address, - usd_price=usd_price, - timestamp=timestamp_seconds, + for token_address in TOKEN_ADDRESSES: + price_data = cg.get_coin_market_chart_by_id( + id=TOKEN_NAME_BY_ADDRESS[token_address], vs_currency="usd", days="max" + ) + price_time_series = price_data["prices"] + + for entry in price_time_series: + timestamp = dt.fromtimestamp(entry[0] / 100) + token_price = entry[1] + prices.append( + Price( + timestamp=timestamp, + usd_price=token_price, + token_address=token_address, + ) ) - prices.append(price) - return prices diff --git a/mev_inspect/schemas/coinbase.py b/mev_inspect/schemas/coinbase.py deleted file mode 100644 index fca7bab..0000000 --- a/mev_inspect/schemas/coinbase.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import List, Tuple - -from pydantic import BaseModel - - -class CoinbasePricesEntry(BaseModel): - # tuple of price and timestamp - prices: List[Tuple[float, int]] - - -class CoinbasePrices(BaseModel): - all: CoinbasePricesEntry - - -class CoinbasePricesDataResponse(BaseModel): - prices: CoinbasePrices - - -class CoinbasePricesResponse(BaseModel): - data: CoinbasePricesDataResponse diff --git a/mev_inspect/schemas/prices.py b/mev_inspect/schemas/prices.py index 3c7f5fd..9227f93 100644 --- a/mev_inspect/schemas/prices.py +++ b/mev_inspect/schemas/prices.py @@ -2,6 +2,9 @@ from datetime import datetime from pydantic import BaseModel, validator +from mev_inspect.classifiers.specs.weth import WETH_ADDRESS +from mev_inspect.schemas.transfers import ETH_TOKEN_ADDRESS + WBTC_TOKEN_ADDRESS = "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599" LINK_TOKEN_ADDRESS = "0x514910771af9ca656af840dff83e8264ecf986ca" YEARN_TOKEN_ADDRESS = "0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e" @@ -13,11 +16,39 @@ REN_TOKEN_ADDRESS = "0x408e41876cccdc0f92210600ef50372656052a38" CUSDC_TOKEN_ADDRESS = "0x39aa39c021dfbae8fac545936693ac917d5e7563" CDAI_TOKEN_ADDRESS = "0x5d3a536e4d6dbd6114cc1ead35777bab948e3643" +TOKEN_ADDRESSES = [ + WBTC_TOKEN_ADDRESS, + LINK_TOKEN_ADDRESS, + YEARN_TOKEN_ADDRESS, + AAVE_TOKEN_ADDRESS, + UNI_TOKEN_ADDRESS, + USDC_TOKEN_ADDRESS, + DAI_TOKEN_ADDRESS, + REN_TOKEN_ADDRESS, + CUSDC_TOKEN_ADDRESS, + CDAI_TOKEN_ADDRESS, +] + +TOKEN_NAME_BY_ADDRESS = { + WETH_ADDRESS: "weth", + ETH_TOKEN_ADDRESS: "ethereum", + WBTC_TOKEN_ADDRESS: "wrapped-bitcoin", + LINK_TOKEN_ADDRESS: "chainlink", + YEARN_TOKEN_ADDRESS: "yearn-finance", + AAVE_TOKEN_ADDRESS: "aave", + UNI_TOKEN_ADDRESS: "uniswap", + USDC_TOKEN_ADDRESS: "usd-coin", + DAI_TOKEN_ADDRESS: "dai", + REN_TOKEN_ADDRESS: "republic-protocol", + CUSDC_TOKEN_ADDRESS: "compound-usd-coin", + CDAI_TOKEN_ADDRESS: "cdai", +} + class Price(BaseModel): token_address: str + usd_price: int timestamp: datetime - usd_price: float @validator("token_address") def lower_token_address(cls, v: str) -> str: diff --git a/poetry.lock b/poetry.lock index 38c29fd..fc708b4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -730,6 +730,17 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "pycoingecko" +version = "2.2.0" +description = "Python wrapper around the CoinGecko API" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +requests = "*" + [[package]] name = "pycryptodome" version = "3.10.1" @@ -1116,7 +1127,7 @@ multidict = ">=4.0" [metadata] lock-version = "1.1" python-versions = "^3.9" -content-hash = "2ce3bdeb2d8bd31210026e5054a54c67fc766cdf22dc83485eca425643cdf760" +content-hash = "955c3df01b275e9b4807190e468a2df4d3d18b6a45a7c1659599ef476b35be51" [metadata.files] aiohttp = [ @@ -1775,6 +1786,10 @@ py = [ {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, ] +pycoingecko = [ + {file = "pycoingecko-2.2.0-py3-none-any.whl", hash = "sha256:3646968c8c6936ca4e94b5f562328a763c12a0e9644141cb0215089dda59fe01"}, + {file = "pycoingecko-2.2.0.tar.gz", hash = "sha256:9add73085729b1f10f93c7948490b09e8cd47c29bebe47dccb319e8b49502d0c"}, +] pycryptodome = [ {file = "pycryptodome-3.10.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1c5e1ca507de2ad93474be5cfe2bfa76b7cf039a1a32fc196f40935944871a06"}, {file = "pycryptodome-3.10.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:6260e24d41149268122dd39d4ebd5941e9d107f49463f7e071fd397e29923b0c"}, diff --git a/pyproject.toml b/pyproject.toml index 3c4be4d..f2f9f17 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,6 +13,7 @@ click = "^8.0.1" psycopg2 = "^2.9.1" aiohttp = "^3.8.0" dramatiq = {extras = ["redis"], version = "^1.12.1"} +pycoingecko = "^2.2.0" [tool.poetry.dev-dependencies] pre-commit = "^2.13.0"