forked from LBRYCommunity/lbry-sdk
converting from USD, BTC to LBC is now done via several exchange rate providers: Bittrex, Cryptonator, CoinEx, hotbit and UPbit
This commit is contained in:
parent
b13a121915
commit
dee494e12f
4 changed files with 105 additions and 45 deletions
|
@ -58,9 +58,12 @@ class MarketFeed:
|
|||
raise NotImplementedError()
|
||||
|
||||
async def get_response(self):
|
||||
async with aiohttp_request('get', self.url, params=self.params, timeout=self.request_timeout) as response:
|
||||
headers = {"User-Agent": "lbrynet"}
|
||||
async with aiohttp_request(
|
||||
'get', self.url, params=self.params, timeout=self.request_timeout, headers=headers
|
||||
) as response:
|
||||
try:
|
||||
self._last_response = await response.json()
|
||||
self._last_response = await response.json(content_type=None)
|
||||
except ContentTypeError as e:
|
||||
self._last_response = {}
|
||||
log.warning("Could not parse exchange rate response from %s: %s", self.name, e.message)
|
||||
|
@ -104,10 +107,10 @@ class MarketFeed:
|
|||
self.event.clear()
|
||||
|
||||
|
||||
class BittrexFeed(MarketFeed):
|
||||
class BaseBittrexFeed(MarketFeed):
|
||||
name = "Bittrex"
|
||||
market = "BTCLBC"
|
||||
url = "https://api.bittrex.com/v3/markets/LBC-BTC/ticker"
|
||||
market = None
|
||||
url = None
|
||||
fee = 0.0025
|
||||
|
||||
def get_rate_from_response(self, json_response):
|
||||
|
@ -116,49 +119,103 @@ class BittrexFeed(MarketFeed):
|
|||
return 1.0 / float(json_response['lastTradeRate'])
|
||||
|
||||
|
||||
class LBRYFeed(MarketFeed):
|
||||
name = "lbry.com"
|
||||
class BittrexBTCFeed(BaseBittrexFeed):
|
||||
market = "BTCLBC"
|
||||
url = "https://api.lbry.com/lbc/exchange_rate"
|
||||
url = "https://api.bittrex.com/v3/markets/LBC-BTC/ticker"
|
||||
|
||||
|
||||
class BittrexUSDFeed(BaseBittrexFeed):
|
||||
market = "USDLBC"
|
||||
url = "https://api.bittrex.com/v3/markets/LBC-USD/ticker"
|
||||
|
||||
|
||||
class BaseCryptonatorFeed(MarketFeed):
|
||||
name = "Cryptonator"
|
||||
market = None
|
||||
url = None
|
||||
|
||||
def get_rate_from_response(self, json_response):
|
||||
if 'data' not in json_response:
|
||||
raise InvalidExchangeRateResponseError(self.name, 'result not found')
|
||||
return 1.0 / json_response['data']['lbc_btc']
|
||||
|
||||
|
||||
class LBRYBTCFeed(LBRYFeed):
|
||||
market = "USDBTC"
|
||||
|
||||
def get_rate_from_response(self, json_response):
|
||||
if 'data' not in json_response:
|
||||
raise InvalidExchangeRateResponseError(self.name, 'result not found')
|
||||
return 1.0 / json_response['data']['btc_usd']
|
||||
|
||||
|
||||
class CryptonatorFeed(MarketFeed):
|
||||
name = "cryptonator.com"
|
||||
market = "BTCLBC"
|
||||
url = "https://api.cryptonator.com/api/ticker/btc-lbc"
|
||||
|
||||
def get_rate_from_response(self, json_response):
|
||||
if 'ticker' not in json_response or len(json_response['ticker']) == 0 or \
|
||||
'success' not in json_response or json_response['success'] is not True:
|
||||
if 'ticker' not in json_response or 'price' not in json_response['ticker']:
|
||||
raise InvalidExchangeRateResponseError(self.name, 'result not found')
|
||||
return float(json_response['ticker']['price'])
|
||||
|
||||
|
||||
class CryptonatorBTCFeed(CryptonatorFeed):
|
||||
market = "USDBTC"
|
||||
url = "https://api.cryptonator.com/api/ticker/usd-btc"
|
||||
class CryptonatorBTCFeed(BaseCryptonatorFeed):
|
||||
market = "BTCLBC"
|
||||
url = "https://api.cryptonator.com/api/ticker/btc-lbc"
|
||||
|
||||
|
||||
class CryptonatorUSDFeed(BaseCryptonatorFeed):
|
||||
market = "USDLBC"
|
||||
url = "https://api.cryptonator.com/api/ticker/usd-lbc"
|
||||
|
||||
|
||||
class BaseCoinExFeed(MarketFeed):
|
||||
name = "CoinEx"
|
||||
market = None
|
||||
url = None
|
||||
|
||||
def get_rate_from_response(self, json_response):
|
||||
if 'data' not in json_response or \
|
||||
'ticker' not in json_response['data'] or \
|
||||
'last' not in json_response['data']['ticker']:
|
||||
raise InvalidExchangeRateResponseError(self.name, 'result not found')
|
||||
return 1.0 / float(json_response['data']['ticker']['last'])
|
||||
|
||||
|
||||
class CoinExBTCFeed(BaseCoinExFeed):
|
||||
market = "BTCLBC"
|
||||
url = "https://api.coinex.com/v1/market/ticker?market=LBCBTC"
|
||||
|
||||
|
||||
class CoinExUSDFeed(BaseCoinExFeed):
|
||||
market = "USDLBC"
|
||||
url = "https://api.coinex.com/v1/market/ticker?market=LBCUSDT"
|
||||
|
||||
|
||||
class BaseHotbitFeed(MarketFeed):
|
||||
name = "hotbit"
|
||||
market = None
|
||||
url = "https://api.hotbit.io/api/v1/market.last"
|
||||
|
||||
def get_rate_from_response(self, json_response):
|
||||
if 'result' not in json_response:
|
||||
raise InvalidExchangeRateResponseError(self.name, 'result not found')
|
||||
return 1.0 / float(json_response['result'])
|
||||
|
||||
|
||||
class HotbitBTCFeed(BaseHotbitFeed):
|
||||
market = "BTCLBC"
|
||||
params = {"market": "LBC/BTC"}
|
||||
|
||||
|
||||
class HotbitUSDFeed(BaseHotbitFeed):
|
||||
market = "USDLBC"
|
||||
params = {"market": "LBC/USDT"}
|
||||
|
||||
|
||||
class UPbitBTCFeed(MarketFeed):
|
||||
name = "UPbit"
|
||||
market = "BTCLBC"
|
||||
url = "https://api.upbit.com/v1/ticker"
|
||||
params = {"markets": "BTC-LBC"}
|
||||
|
||||
def get_rate_from_response(self, json_response):
|
||||
if len(json_response) != 1 or 'trade_price' not in json_response[0]:
|
||||
raise InvalidExchangeRateResponseError(self.name, 'result not found')
|
||||
return 1.0 / float(json_response[0]['trade_price'])
|
||||
|
||||
|
||||
FEEDS: Iterable[Type[MarketFeed]] = (
|
||||
LBRYFeed,
|
||||
LBRYBTCFeed,
|
||||
BittrexFeed,
|
||||
# CryptonatorFeed,
|
||||
# CryptonatorBTCFeed,
|
||||
BittrexBTCFeed,
|
||||
BittrexUSDFeed,
|
||||
CryptonatorBTCFeed,
|
||||
CryptonatorUSDFeed,
|
||||
CoinExBTCFeed,
|
||||
CoinExUSDFeed,
|
||||
HotbitBTCFeed,
|
||||
HotbitUSDFeed,
|
||||
UPbitBTCFeed,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ from lbry.extras.daemon.components import (
|
|||
)
|
||||
from lbry.extras.daemon.componentmanager import ComponentManager
|
||||
from lbry.extras.daemon.exchange_rate_manager import (
|
||||
ExchangeRateManager, ExchangeRate, LBRYFeed, LBRYBTCFeed
|
||||
ExchangeRateManager, ExchangeRate, BittrexBTCFeed, BittrexUSDFeed
|
||||
)
|
||||
from lbry.extras.daemon.storage import SQLiteStorage
|
||||
from lbry.blob.blob_manager import BlobManager
|
||||
|
@ -282,8 +282,8 @@ class FakeExchangeRateManager(ExchangeRateManager):
|
|||
|
||||
def get_fake_exchange_rate_manager(rates=None):
|
||||
return FakeExchangeRateManager(
|
||||
[LBRYFeed(), LBRYBTCFeed()],
|
||||
rates or {'BTCLBC': 3.0, 'USDBTC': 2.0}
|
||||
[BittrexBTCFeed(), BittrexUSDFeed()],
|
||||
rates or {'BTCLBC': 3.0, 'USDLBC': 2.0}
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -375,7 +375,7 @@ def get_ssl_context() -> ssl.SSLContext:
|
|||
@contextlib.asynccontextmanager
|
||||
async def aiohttp_request(method, url, **kwargs) -> typing.AsyncContextManager[aiohttp.ClientResponse]:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.request(method, url, ssl=get_ssl_context(), **kwargs) as response:
|
||||
async with session.request(method, url, **kwargs) as response:
|
||||
yield response
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ from lbry.extras.daemon.exchange_rate_manager import ExchangeRate, ExchangeRateM
|
|||
|
||||
class TestExchangeRateManager(AsyncioTestCase):
|
||||
async def test_exchange_rate_manager(self):
|
||||
# TODO: re-enable cryptonator.com
|
||||
manager = ExchangeRateManager(FEEDS)
|
||||
manager.start()
|
||||
self.addCleanup(manager.stop)
|
||||
|
@ -16,6 +15,10 @@ class TestExchangeRateManager(AsyncioTestCase):
|
|||
for feed in manager.market_feeds:
|
||||
self.assertTrue(feed.is_online)
|
||||
self.assertIsInstance(feed.rate, ExchangeRate)
|
||||
lbc = manager.convert_currency('USD', 'LBC', Decimal('0.01'))
|
||||
self.assertGreaterEqual(lbc, 0.01)
|
||||
# print(f'{feed.name} - {feed.market} - {feed.rate.spot}')
|
||||
lbc = manager.convert_currency('USD', 'LBC', Decimal('1.0'))
|
||||
self.assertGreaterEqual(lbc, 2.0)
|
||||
self.assertLessEqual(lbc, 10.0)
|
||||
lbc = manager.convert_currency('BTC', 'LBC', Decimal('0.01'))
|
||||
self.assertGreaterEqual(lbc, 1_000)
|
||||
self.assertLessEqual(lbc, 4_000)
|
||||
|
|
Loading…
Add table
Reference in a new issue