diff --git a/bitcoin.png b/bitcoin.png new file mode 100644 index 000000000..60a2c92fb Binary files /dev/null and b/bitcoin.png differ diff --git a/electrum/currencies.json b/electrum/currencies.json index d9d4fdac7..91fc5bbb8 100644 --- a/electrum/currencies.json +++ b/electrum/currencies.json @@ -1,563 +1,4 @@ { - "BitFlyer": [ - "JPY" - ], - "BitPay": [ - "AED", - "AFN", - "ALL", - "AMD", - "ANG", - "AOA", - "ARS", - "AUD", - "AWG", - "AZN", - "BAM", - "BBD", - "BCH", - "BDT", - "BGN", - "BHD", - "BIF", - "BMD", - "BND", - "BOB", - "BRL", - "BSD", - "BTC", - "BTN", - "BWP", - "BZD", - "CAD", - "CDF", - "CHF", - "CLF", - "CLP", - "CNY", - "COP", - "CRC", - "CUP", - "CVE", - "CZK", - "DJF", - "DKK", - "DOP", - "DZD", - "EGP", - "ETB", - "EUR", - "FJD", - "FKP", - "GBP", - "GEL", - "GHS", - "GIP", - "GMD", - "GNF", - "GTQ", - "GYD", - "HKD", - "HNL", - "HRK", - "HTG", - "HUF", - "IDR", - "ILS", - "INR", - "IQD", - "IRR", - "ISK", - "JEP", - "JMD", - "JOD", - "JPY", - "KES", - "KGS", - "KHR", - "KMF", - "KPW", - "KRW", - "KWD", - "KYD", - "KZT", - "LAK", - "LBP", - "LKR", - "LRD", - "LSL", - "LYD", - "MAD", - "MDL", - "MGA", - "MKD", - "MMK", - "MNT", - "MOP", - "MRU", - "MUR", - "MVR", - "MWK", - "MXN", - "MYR", - "MZN", - "NAD", - "NGN", - "NIO", - "NOK", - "NPR", - "NZD", - "OMR", - "PAB", - "PAX", - "PEN", - "PGK", - "PHP", - "PKR", - "PLN", - "PYG", - "QAR", - "RON", - "RSD", - "RUB", - "RWF", - "SAR", - "SBD", - "SCR", - "SDG", - "SEK", - "SGD", - "SHP", - "SLL", - "SOS", - "SRD", - "STN", - "SVC", - "SYP", - "SZL", - "THB", - "TJS", - "TMT", - "TND", - "TOP", - "TRY", - "TTD", - "TWD", - "TZS", - "UAH", - "UGX", - "USD", - "UYU", - "UZS", - "VEF", - "VES", - "VND", - "VUV", - "WST", - "XAF", - "XAG", - "XAU", - "XCD", - "XOF", - "XPF", - "YER", - "ZAR", - "ZMW", - "ZWL" - ], - "BitStamp": [ - "USD", - "EUR" - ], - "Bitbank": [ - "JPY" - ], - "BitcoinAverage": [ - "AED", - "AFN", - "ALL", - "AMD", - "ANG", - "AOA", - "ARS", - "AUD", - "AWG", - "AZN", - "BAM", - "BBD", - "BDT", - "BGN", - "BHD", - "BIF", - "BMD", - "BND", - "BOB", - "BRL", - "BSD", - "BTN", - "BWP", - "BYN", - "BZD", - "CAD", - "CDF", - "CHF", - "CLF", - "CLP", - "CNH", - "CNY", - "COP", - "CRC", - "CUC", - "CUP", - "CVE", - "CZK", - "DJF", - "DKK", - "DOP", - "DZD", - "EGP", - "ERN", - "ETB", - "EUR", - "FJD", - "FKP", - "GBP", - "GEL", - "GGP", - "GHS", - "GIP", - "GMD", - "GNF", - "GTQ", - "GYD", - "HKD", - "HNL", - "HRK", - "HTG", - "HUF", - "IDR", - "ILS", - "IMP", - "INR", - "IQD", - "IRR", - "ISK", - "JEP", - "JMD", - "JOD", - "JPY", - "KES", - "KGS", - "KHR", - "KMF", - "KPW", - "KRW", - "KWD", - "KYD", - "KZT", - "LAK", - "LBP", - "LKR", - "LRD", - "LSL", - "LYD", - "MAD", - "MDL", - "MGA", - "MKD", - "MMK", - "MNT", - "MOP", - "MRO", - "MUR", - "MVR", - "MWK", - "MXN", - "MYR", - "MZN", - "NAD", - "NGN", - "NIO", - "NOK", - "NPR", - "NZD", - "OMR", - "PAB", - "PEN", - "PGK", - "PHP", - "PKR", - "PLN", - "PYG", - "QAR", - "RON", - "RSD", - "RUB", - "RWF", - "SAR", - "SBD", - "SCR", - "SDG", - "SEK", - "SGD", - "SHP", - "SLL", - "SOS", - "SRD", - "SSP", - "STD", - "SVC", - "SYP", - "SZL", - "THB", - "TJS", - "TMT", - "TND", - "TOP", - "TRY", - "TTD", - "TWD", - "TZS", - "UAH", - "UGX", - "USD", - "UYU", - "UZS", - "VES", - "VND", - "VUV", - "WST", - "XAF", - "XAG", - "XAU", - "XCD", - "XDR", - "XOF", - "XPD", - "XPF", - "XPT", - "YER", - "ZAR", - "ZMW", - "ZWL" - ], - "BitcoinVenezuela": [ - "ARS", - "ETH", - "EUR", - "LTC", - "USD", - "VEF", - "XMR" - ], - "Bitcointoyou": [ - "BRL" - ], - "Bitso": [ - "MXN" - ], - "Bitvalor": [ - "BRL" - ], - "BlockchainInfo": [ - "AUD", - "BRL", - "CAD", - "CHF", - "CLP", - "CNY", - "DKK", - "EUR", - "GBP", - "HKD", - "INR", - "ISK", - "JPY", - "KRW", - "NZD", - "PLN", - "RUB", - "SEK", - "SGD", - "THB", - "TWD", - "USD" - ], - "Bylls": [ - "CAD" - ], - "CoinCap": [ - "USD" - ], - "CoinDesk": [ - "AED", - "AFN", - "ALL", - "AMD", - "ANG", - "AOA", - "ARS", - "AUD", - "AWG", - "AZN", - "BAM", - "BBD", - "BDT", - "BGN", - "BHD", - "BIF", - "BMD", - "BND", - "BOB", - "BRL", - "BSD", - "BTC", - "BTN", - "BWP", - "BYR", - "BZD", - "CAD", - "CDF", - "CHF", - "CLF", - "CLP", - "CNY", - "COP", - "CRC", - "CUP", - "CVE", - "CZK", - "DJF", - "DKK", - "DOP", - "DZD", - "EEK", - "EGP", - "ERN", - "ETB", - "EUR", - "FJD", - "FKP", - "GBP", - "GEL", - "GHS", - "GIP", - "GMD", - "GNF", - "GTQ", - "GYD", - "HKD", - "HNL", - "HRK", - "HTG", - "HUF", - "IDR", - "ILS", - "INR", - "IQD", - "IRR", - "ISK", - "JEP", - "JMD", - "JOD", - "JPY", - "KES", - "KGS", - "KHR", - "KMF", - "KPW", - "KRW", - "KWD", - "KYD", - "KZT", - "LAK", - "LBP", - "LKR", - "LRD", - "LSL", - "LTL", - "LVL", - "LYD", - "MAD", - "MDL", - "MGA", - "MKD", - "MMK", - "MNT", - "MOP", - "MRO", - "MTL", - "MUR", - "MVR", - "MWK", - "MXN", - "MYR", - "MZN", - "NAD", - "NGN", - "NIO", - "NOK", - "NPR", - "NZD", - "OMR", - "PAB", - "PEN", - "PGK", - "PHP", - "PKR", - "PLN", - "PYG", - "QAR", - "RON", - "RSD", - "RUB", - "RWF", - "SAR", - "SBD", - "SCR", - "SDG", - "SEK", - "SGD", - "SHP", - "SLL", - "SOS", - "SRD", - "STD", - "SVC", - "SYP", - "SZL", - "THB", - "TJS", - "TMT", - "TND", - "TOP", - "TRY", - "TTD", - "TWD", - "TZS", - "UAH", - "UGX", - "USD", - "UYU", - "UZS", - "VEF", - "VND", - "VUV", - "WST", - "XAF", - "XAG", - "XAU", - "XBT", - "XCD", - "XDR", - "XOF", - "XPF", - "YER", - "ZAR", - "ZMK", - "ZMW", - "ZWL" - ], "CoinGecko": [ "AED", "ARS", @@ -614,303 +55,7 @@ "XRP", "ZAR" ], - "Coinbase": [ - "AED", - "AFN", - "ALL", - "AMD", - "ANG", - "AOA", - "ARS", - "AUD", - "AWG", - "AZN", - "BAM", - "BAT", - "BBD", - "BCH", - "BDT", - "BGN", - "BHD", - "BIF", - "BMD", - "BND", - "BOB", - "BRL", - "BSD", - "BSV", - "BTC", - "BTN", - "BWP", - "BYN", - "BYR", - "BZD", - "CAD", - "CDF", - "CHF", - "CLF", - "CLP", - "CNH", - "CNY", - "COP", - "CRC", - "CUC", - "CVE", - "CZK", - "DJF", - "DKK", - "DOP", - "DZD", - "EEK", - "EGP", - "ERN", - "ETB", - "ETC", - "ETH", - "EUR", - "FJD", - "FKP", - "GBP", - "GEL", - "GGP", - "GHS", - "GIP", - "GMD", - "GNF", - "GTQ", - "GYD", - "HKD", - "HNL", - "HRK", - "HTG", - "HUF", - "IDR", - "ILS", - "IMP", - "INR", - "IQD", - "ISK", - "JEP", - "JMD", - "JOD", - "JPY", - "KES", - "KGS", - "KHR", - "KMF", - "KRW", - "KWD", - "KYD", - "KZT", - "LAK", - "LBP", - "LKR", - "LRD", - "LSL", - "LTC", - "LTL", - "LVL", - "LYD", - "MAD", - "MDL", - "MGA", - "MKD", - "MMK", - "MNT", - "MOP", - "MRO", - "MTL", - "MUR", - "MVR", - "MWK", - "MXN", - "MYR", - "MZN", - "NAD", - "NGN", - "NIO", - "NOK", - "NPR", - "NZD", - "OMR", - "PAB", - "PEN", - "PGK", - "PHP", - "PKR", - "PLN", - "PYG", - "QAR", - "RON", - "RSD", - "RUB", - "RWF", - "SAR", - "SBD", - "SCR", - "SEK", - "SGD", - "SHP", - "SLL", - "SOS", - "SRD", - "SSP", - "STD", - "SVC", - "SZL", - "THB", - "TJS", - "TMT", - "TND", - "TOP", - "TRY", - "TTD", - "TWD", - "TZS", - "UAH", - "UGX", - "USD", - "UYU", - "UZS", - "VEF", - "VND", - "VUV", - "WST", - "XAF", - "XAG", - "XAU", - "XCD", - "XDR", - "XOF", - "XPD", - "XPF", - "XPT", - "YER", - "ZAR", - "ZEC", - "ZMK", - "ZMW", - "ZRX", - "ZWL" - ], - "CointraderMonitor": [ - "BRL" - ], - "Kraken": [ - "CAD", - "EUR", - "GBP", - "JPY", + "MEXC (must select USD)": [ "USD" - ], - "MercadoBitcoin": [ - "BRL" - ], - "TheRockTrading": [ - "EUR" - ], - "Zaif": [ - "JPY" - ], - "itBit": [], - "Bitragem": [ - "BRL" - ], - "Biscoint": [ - "BRL" - ], - "Walltime": [ - "BRL" - ], - "Yadio": [ - "AED", - "ANG", - "AOA", - "ARS", - "AUD", - "AZN", - "BDT", - "BHD", - "BMD", - "BOB", - "BRL", - "BTC", - "BWP", - "BYN", - "CAD", - "CDF", - "CHF", - "CLP", - "CNY", - "COP", - "CRC", - "CUP", - "CZK", - "DKK", - "DOP", - "DZD", - "EGP", - "ETB", - "EUR", - "GBP", - "GEL", - "GHS", - "GTQ", - "HKD", - "HNL", - "HUF", - "IDR", - "ILS", - "INR", - "JMD", - "JOD", - "JPY", - "KES", - "KGS", - "KRW", - "KZT", - "LBP", - "LKR", - "MAD", - "MLC", - "MXN", - "MYR", - "NAD", - "NGN", - "NOK", - "NPR", - "NZD", - "PAB", - "PEN", - "PHP", - "PKR", - "PLN", - "PYG", - "QAR", - "RON", - "RSD", - "RUB", - "SAR", - "SEK", - "SGD", - "THB", - "TND", - "TRY", - "TTD", - "TWD", - "TZS", - "UAH", - "UGX", - "USD", - "UYU", - "UZS", - "VES", - "VND", - "XAF", - "XAG", - "XAU", - "XOF", - "XPT", - "ZAR" - ] + ] } diff --git a/electrum/exchange_rate.py b/electrum/exchange_rate.py index 0dc78cfec..8e5b9e71a 100644 --- a/electrum/exchange_rate.py +++ b/electrum/exchange_rate.py @@ -32,7 +32,7 @@ 'RWF': 0, 'TND': 3, 'UGX': 0, 'UYI': 0, 'VND': 0, 'VUV': 0, 'XAF': 0, 'XAU': 4, 'XOF': 0, 'XPF': 0, # Cryptocurrencies - 'BTC': 8, 'LTC': 8, 'XRP': 6, 'ETH': 18, + 'BTC': 8, 'LTC': 8, 'XRP': 6, 'ETH': 18, 'FACT': 8, 'FACT0RN': 8 } SPOT_RATE_REFRESH_TARGET = 150 # approx. every 2.5 minutes, try to refresh spot price @@ -179,272 +179,42 @@ def get_cached_spot_quote(self, ccy: str) -> Decimal: return Decimal('NaN') return Decimal(rate) -class Yadio(ExchangeBase): - async def get_currencies(self): - dicts = await self.get_json('api.yadio.io', '/currencies') - return list(dicts.keys()) - - async def get_rates(self, ccy: str) -> Mapping[str, Optional[Decimal]]: - json = await self.get_json('api.yadio.io', '/rate/%s/BTC' % ccy) - return {ccy: to_decimal(json['rate'])} - -class BitcoinAverage(ExchangeBase): - # note: historical rates used to be freely available - # but this is no longer the case. see #5188 - - async def get_rates(self, ccy): - json = await self.get_json('apiv2.bitcoinaverage.com', '/indices/global/ticker/short') - return dict([(r.replace("BTC", ""), to_decimal(json[r]['last'])) - for r in json if r != 'timestamp']) - - -class Bitcointoyou(ExchangeBase): - - async def get_rates(self, ccy): - json = await self.get_json('bitcointoyou.com', "/API/ticker.aspx") - return {'BRL': to_decimal(json['ticker']['last'])} - - -class BitcoinVenezuela(ExchangeBase): - - async def get_rates(self, ccy): - json = await self.get_json('api.bitcoinvenezuela.com', '/') - rates = [(r, to_decimal(json['BTC'][r])) for r in json['BTC'] - if json['BTC'][r] is not None] # Giving NULL for LTC - return dict(rates) - - def history_ccys(self): - return ['ARS', 'EUR', 'USD', 'VEF'] - - async def request_history(self, ccy): - json = await self.get_json('api.bitcoinvenezuela.com', - "/historical/index.php?coin=BTC") - return json[ccy +'_BTC'] - - -class Bitbank(ExchangeBase): - - async def get_rates(self, ccy): - json = await self.get_json('public.bitbank.cc', '/btc_jpy/ticker') - return {'JPY': to_decimal(json['data']['last'])} - - -class BitFlyer(ExchangeBase): - - async def get_rates(self, ccy): - json = await self.get_json('bitflyer.jp', '/api/echo/price') - return {'JPY': to_decimal(json['mid'])} - - -class BitPay(ExchangeBase): +class MEXC(ExchangeBase): + async def get_rates(self, ccy): - json = await self.get_json('bitpay.com', '/api/rates') - return dict([(r['code'], to_decimal(r['rate'])) for r in json]) - - -class Bitso(ExchangeBase): - - async def get_rates(self, ccy): - json = await self.get_json('api.bitso.com', '/v2/ticker') - return {'MXN': to_decimal(json['last'])} - - -class BitStamp(ExchangeBase): - - async def get_currencies(self): - return ['USD', 'EUR'] - - async def get_rates(self, ccy): - if ccy in CURRENCIES[self.name()]: - json = await self.get_json('www.bitstamp.net', f'/api/v2/ticker/btc{ccy.lower()}/') - return {ccy: to_decimal(json['last'])} - return {} - - -class Bitvalor(ExchangeBase): - - async def get_rates(self,ccy): - json = await self.get_json('api.bitvalor.com', '/v1/ticker.json') - return {'BRL': to_decimal(json['ticker_1h']['total']['last'])} - - -class BlockchainInfo(ExchangeBase): - - async def get_rates(self, ccy): - json = await self.get_json('blockchain.info', '/ticker') - return dict([(r, to_decimal(json[r]['15m'])) for r in json]) - - -class Bylls(ExchangeBase): - - async def get_rates(self, ccy): - json = await self.get_json('bylls.com', '/api/price?from_currency=BTC&to_currency=CAD') - return {'CAD': to_decimal(json['public_price']['to_price'])} - - -class Coinbase(ExchangeBase): - - async def get_rates(self, ccy): - json = await self.get_json('api.coinbase.com', - '/v2/exchange-rates?currency=BTC') - return {ccy: to_decimal(rate) for (ccy, rate) in json["data"]["rates"].items()} - - -class CoinCap(ExchangeBase): - - async def get_rates(self, ccy): - json = await self.get_json('api.coincap.io', '/v2/rates/bitcoin/') - return {'USD': to_decimal(json['data']['rateUsd'])} - - def history_ccys(self): - return ['USD'] - - async def request_history(self, ccy): - # Currently 2000 days is the maximum in 1 API call - # (and history starts on 2017-03-23) - history = await self.get_json('api.coincap.io', - '/v2/assets/bitcoin/history?interval=d1&limit=2000') - return dict([(datetime.utcfromtimestamp(h['time']/1000).strftime('%Y-%m-%d'), str(h['priceUsd'])) - for h in history['data']]) - - -class CoinDesk(ExchangeBase): - - async def get_currencies(self): - dicts = await self.get_json('api.coindesk.com', - '/v1/bpi/supported-currencies.json') - return [d['currency'] for d in dicts] - - async def get_rates(self, ccy): - json = await self.get_json('api.coindesk.com', - '/v1/bpi/currentprice/%s.json' % ccy) - result = {ccy: to_decimal(json['bpi'][ccy]['rate_float'])} - return result - - def history_starts(self): - return {'USD': '2012-11-30', 'EUR': '2013-09-01'} - - def history_ccys(self): - return self.history_starts().keys() - - async def request_history(self, ccy): - start = self.history_starts()[ccy] - end = datetime.today().strftime('%Y-%m-%d') - # Note ?currency and ?index don't work as documented. Sigh. - query = ('/v1/bpi/historical/close.json?start=%s&end=%s' - % (start, end)) - json = await self.get_json('api.coindesk.com', query) - return json['bpi'] + json = await self.get_json('api.mexc.com', '/api/v3/ticker/price?symbol=FACTUSDT') + return {'USD': to_decimal(json['price'])} class CoinGecko(ExchangeBase): async def get_rates(self, ccy): - json = await self.get_json('api.coingecko.com', '/api/v3/exchange_rates') - return dict([(ccy.upper(), to_decimal(d['value'])) - for ccy, d in json['rates'].items()]) + json = await self.get_json('api.coingecko.com', '/api/v3/coins/fact0rn?localization=False&sparkline=false') + prices = json["market_data"]["current_price"] + return dict([(a[0].upper(),to_decimal(a[1])) for a in prices.items()]) def history_ccys(self): # CoinGecko seems to have historical data for all ccys it supports - return CURRENCIES[self.name()] + return ['AED', 'ARS', 'AUD', 'BTD', 'BHD', 'BMD', 'BRL', 'BTC', + 'CAD', 'CHF', 'CLP', 'CNY', 'CZK', 'DKK', 'ETH', 'EUR', + 'GBP', 'HKD', 'HUF', 'IDR', 'ILS', 'INR', 'JPY', 'KRW', + 'KWD', 'LKR', 'LTC', 'MMK', 'MXH', 'MYR', 'NOK', 'NZD', + 'PHP', 'PKR', 'PLN', 'RUB', 'SAR', 'SEK', 'SGD', 'THB', + 'TRY', 'TWD', 'USD', 'VEF', 'VND', 'XAG', 'XAU', 'XDR', + 'ZAR'] async def request_history(self, ccy): history = await self.get_json('api.coingecko.com', - '/api/v3/coins/bitcoin/market_chart?vs_currency=%s&days=max' % ccy) + '/api/v3/coins/fact0rn/market_chart?vs_currency=%s&days=max' % ccy) - return dict([(datetime.utcfromtimestamp(h[0]/1000).strftime('%Y-%m-%d'), str(h[1])) + from datetime import datetime as dt + return dict([(dt.utcfromtimestamp(h[0]/1000).strftime('%Y-%m-%d'), h[1]) for h in history['prices']]) -class CointraderMonitor(ExchangeBase): - - async def get_rates(self, ccy): - json = await self.get_json('cointradermonitor.com', '/api/pbb/v1/ticker') - return {'BRL': to_decimal(json['last'])} - - -class itBit(ExchangeBase): - - async def get_rates(self, ccy): - ccys = ['USD', 'EUR', 'SGD'] - json = await self.get_json('api.itbit.com', '/v1/markets/XBT%s/ticker' % ccy) - result = dict.fromkeys(ccys) - if ccy in ccys: - result[ccy] = to_decimal(json['lastPrice']) - return result - - -class Kraken(ExchangeBase): - - async def get_rates(self, ccy): - ccys = ['EUR', 'USD', 'CAD', 'GBP', 'JPY'] - pairs = ['XBT%s' % c for c in ccys] - json = await self.get_json('api.kraken.com', - '/0/public/Ticker?pair=%s' % ','.join(pairs)) - return dict((k[-3:], to_decimal(v['c'][0])) - for k, v in json['result'].items()) - - -class MercadoBitcoin(ExchangeBase): - async def get_rates(self, ccy): - json = await self.get_json('api.bitvalor.com', '/v1/ticker.json') - return {'BRL': to_decimal(json['ticker_1h']['exchanges']['MBT']['last'])} - - -class TheRockTrading(ExchangeBase): - - async def get_rates(self, ccy): - json = await self.get_json('api.therocktrading.com', - '/v1/funds/BTCEUR/ticker') - return {'EUR': to_decimal(json['last'])} - - -class Winkdex(ExchangeBase): - - async def get_rates(self, ccy): - json = await self.get_json('winkdex.com', '/api/v0/price') - return {'USD': to_decimal(json['price']) / 100} - - def history_ccys(self): - return ['USD'] - - async def request_history(self, ccy): - json = await self.get_json('winkdex.com', - "/api/v0/series?start_time=1342915200") - history = json['series'][0]['results'] - return dict([(h['timestamp'][:10], str(to_decimal(h['price']) / 100)) - for h in history]) - - -class Zaif(ExchangeBase): - async def get_rates(self, ccy): - json = await self.get_json('api.zaif.jp', '/api/1/last_price/btc_jpy') - return {'JPY': to_decimal(json['last_price'])} - - -class Bitragem(ExchangeBase): - - async def get_rates(self,ccy): - json = await self.get_json('api.bitragem.com', '/v1/index?asset=BTC&market=BRL') - return {'BRL': to_decimal(json['response']['index'])} - - -class Biscoint(ExchangeBase): - - async def get_rates(self,ccy): - json = await self.get_json('api.biscoint.io', '/v1/ticker?base=BTC"e=BRL') - return {'BRL': to_decimal(json['data']['last'])} - - -class Walltime(ExchangeBase): - - async def get_rates(self, ccy): - json = await self.get_json('s3.amazonaws.com', - '/data-production-walltime-info/production/dynamic/walltime-info.json') - return {'BRL': to_decimal(json['BRL_XBT']['last_inexact'])} def dictinvert(d):