Files
routstr-core/router/price.py
T

58 lines
1.7 KiB
Python

import asyncio
import logging
import os
import httpx
# artifical spread to cover conversion fees
EXCHANGE_FEE = float(os.environ.get("EXCHANGE_FEE", "1.005")) # 0.5% default
async def kraken_btc_usd(client: httpx.AsyncClient) -> float | None:
api = "https://api.kraken.com/0/public/Ticker?pair=XBTUSD"
try:
return float((await client.get(api)).json()["result"]["XXBTZUSD"]["c"][0])
except (httpx.RequestError, KeyError) as e:
logging.warning(f"Kraken API error: {e}")
return None
async def coinbase_btc_usd(client: httpx.AsyncClient) -> float | None:
api = "https://api.coinbase.com/v2/prices/BTC-USD/spot"
try:
return float((await client.get(api)).json()["data"]["amount"])
except (httpx.RequestError, KeyError) as e:
logging.warning(f"Coinbase API error: {e}")
return None
async def binance_btc_usdt(client: httpx.AsyncClient) -> float | None:
api = "https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT"
try:
return float((await client.get(api)).json()["price"])
except (httpx.RequestError, KeyError) as e:
logging.warning(f"Binance API error: {e}")
return None
async def btc_usd_ask_price() -> float:
async with httpx.AsyncClient() as client:
return (
max(
[
price
for price in await asyncio.gather(
kraken_btc_usd(client),
coinbase_btc_usd(client),
binance_btc_usdt(client),
)
if price is not None
]
)
* EXCHANGE_FEE
)
async def sats_usd_ask_price() -> float:
return (await btc_usd_ask_price()) / 100_000_000