def value_str(self, satoshis, rate, default_prec=2, is_diff=False): if satoshis is None: # Can happen with incomplete history return _("Unknown") if rate: value = PyDecimal(satoshis) / COIN * PyDecimal(rate) return "%s" % (self.ccy_amount_str(value, True, default_prec, is_diff=is_diff)) return _("No data")
def print_balance(self): if not self.network: msg = _("Offline") elif self.network.is_connected(): if not self.wallet.up_to_date: msg = _("Synchronizing...") else: c, u, x = self.wallet.get_balance() msg = _("Balance") + ": %f " % (PyDecimal(c) / COIN) if u: msg += " [%f unconfirmed]" % (PyDecimal(u) / COIN) if x: msg += " [%f unmatured]" % (PyDecimal(x) / COIN) else: msg = _("Not connected") self.stdscr.addstr(self.maxy - 1, 3, msg) for i in range(self.num_tabs): self.stdscr.addstr(0, 2 + 2 * i + len(''.join(self.tab_names[0:i])), ' ' + self.tab_names[i] + ' ', curses.A_BOLD if self.tab == i else 0) self.stdscr.addstr(self.maxy - 1, self.maxx - 30, ' '.join([_("Settings"), _("Network"), _("Quit")]))
def get_bad(self, days: int = 502): rows = list(self.wb['Bad'])[1:] h = [] i = 1 for row in rows: h.append( Quote( # Quoto.date cannot be null. row[3].value or datetime.now(), # Keep micro values. '{:f}'.format(PyDecimal(row[4].value)) if row[4].value is not None else None, '{:f}'.format(PyDecimal(row[5].value)) if row[5].value is not None else None, '{:f}'.format(PyDecimal(row[6].value)) if row[6].value is not None else None, '{:f}'.format(PyDecimal(row[7].value)) if row[7].value is not None else None, '{:f}'.format(PyDecimal(row[8].value)) if row[8].value is not None else None, )) h.reverse() return h[:days]
def get_rates(self, ccy): json_usd = self.get_json('www.bitstamp.net', '/api/v2/ticker/bchusd') json_eur = self.get_json('www.bitstamp.net', '/api/v2/ticker/bcheur') json_btc = self.get_json('www.bitstamp.net', '/api/v2/ticker/bchbtc') return { 'USD': PyDecimal(json_usd['last']), 'EUR': PyDecimal(json_eur['last']), 'BTC': PyDecimal(json_btc['last'])}
def getaddressbalance(self, address): """Return the balance of any address. Note: This is a walletless server query, results are not checked by SPV. """ sh = Address.from_string(address).to_scripthash_hex() out = self.network.synchronous_get(('blockchain.scripthash.get_balance', [sh])) out["confirmed"] = str(PyDecimal(out["confirmed"])/CASH) out["unconfirmed"] = str(PyDecimal(out["unconfirmed"])/CASH) return out
def getbalance(self): """Return the balance of your wallet. """ c, u, x = self.wallet.get_balance() out = {"confirmed": str(PyDecimal(c) / COIN)} if u: out["unconfirmed"] = str(PyDecimal(u) / COIN) if x: out["unmatured"] = str(PyDecimal(x) / COIN) return out
def settings_dialog(self): fee = str(PyDecimal(self.config.fee_per_kb()) / COIN) out = self.run_dialog('Settings', [{ 'label': 'Default fee', 'type': 'satoshis', 'value': fee }], buttons=1) if out: if out.get('Default fee'): fee = int(PyDecimal(out['Default fee']) * COIN) self.config.set_key('fee_per_kb', fee, True)
def get_balance(self): if self.wallet.network.is_connected(): if not self.wallet.up_to_date: msg = _( "Synchronizing..." ) else: c, u, x = self.wallet.get_balance() msg = _("Balance")+": %f "%(PyDecimal(c) / COIN) if u: msg += " [%f unconfirmed]"%(PyDecimal(u) / COIN) if x: msg += " [%f unmatured]"%(PyDecimal(x) / COIN) else: msg = _( "Not connected" ) return(msg)
def get_rates(self, ccy): ccys = ['EUR', 'USD'] pairs = ['BCH%s' % c for c in ccys] json = self.get_json('api.kraken.com', '/0/public/Ticker?pair=%s' % ','.join(pairs)) return dict((k[-3:], PyDecimal(float(v['c'][0]))) for k, v in json['result'].items())
def get_rates(self, ccy): json_data = self.get_json( 'api.coingecko.com', '/api/v3/coins/bitcoin-cash-abc-2?localization=False&sparkline=false' ) prices = json_data["market_data"]["current_price"] return dict([(a[0].upper(), PyDecimal(a[1])) for a in prices.items()])
def format_satoshis_plain(x, decimal_point=8): """Display a satoshi amount scaled. Always uses a '.' as a decimal point and has no thousands separator""" if x is None: return _('Unknown') scale_factor = pow(10, decimal_point) return "{:.8f}".format(PyDecimal(x) / scale_factor).rstrip('0').rstrip('.')
def get_amount(self): try: x = PyDecimal(str(self.text())) except: return None p = pow(10, self.decimal_point()) return int( p * x )
def parse(self, value): try: value = PyDecimal(value) except ValueError: self.error('Decimal value required', value) value = super().parse(value) return value
def get_rates(self, ccy): json = self.get_json('api.coinbase.com', '/v2/exchange-rates?currency=BCH') return { ccy: PyDecimal(rate) for (ccy, rate) in json["data"]["rates"].items() }
def test_setconfig_non_auth_number(self): self.assertEqual( 7777, Commands._setconfig_normalize_value('rpcport', "7777")) self.assertEqual( 7777, Commands._setconfig_normalize_value('rpcport', '7777')) self.assertAlmostEqual( PyDecimal(2.3), Commands._setconfig_normalize_value('somekey', '2.3'))
def do_send(self): if not Address.is_valid(self.str_recipient): print(_('Invalid Bitcoin address')) return try: amount = int(PyDecimal(self.str_amount) * COIN) except Exception: print(_('Invalid Amount')) return try: fee = int(PyDecimal(self.str_fee) * COIN) except Exception: print(_('Invalid Fee')) return if self.wallet.has_password(): password = self.password_dialog() if not password: return else: password = None c = "" while c != "y": c = input("ok to send (y/n)?") if c == "n": return try: tx = self.wallet.mktx([(TYPE_ADDRESS, self.str_recipient, amount)], password, self.config, fee) except Exception as e: print(str(e)) return if self.str_description: self.wallet.labels[tx.txid()] = self.str_description print(_("Please wait...")) status, msg = self.network.broadcast_transaction(tx) if status: print(_('Payment sent.')) #self.do_clear() #self.update_contacts_tab() else: print(_('Error'))
def test_setconfig_non_auth_number(self): self.assertEqual( 7777, Commands._setconfig_normalize_value("rpcport", "7777")) self.assertEqual( 7777, Commands._setconfig_normalize_value("rpcport", "7777")) self.assertAlmostEqual( PyDecimal(2.3), Commands._setconfig_normalize_value("somekey", "2.3"))
def history_rate(self, d_t): rate = self.exchange.historical_rate(self.ccy, d_t) # Frequently there is no rate for today, until tomorrow :) # Use spot quotes in that case if rate is None and (datetime.today().date() - d_t.date()).days <= 2: rate = self.exchange.quotes.get(self.ccy) self.history_used_spot = True return PyDecimal(rate) if rate is not None else None
def listunspent(self): """List unspent outputs. Returns the list of unspent transaction outputs in your wallet.""" l = self.wallet.get_utxos(exclude_frozen=False) for i in l: v = i["value"] i["value"] = str(PyDecimal(v) / COIN) if v is not None else None i["address"] = i["address"].to_ui_string() return l
def do_send(self): if not Address.is_valid(self.str_recipient): self.show_message(_('Invalid DeVault address')) return try: amount = int(PyDecimal(self.str_amount) * COIN) except Exception: self.show_message(_('Invalid Amount')) return try: fee = int(PyDecimal(self.str_fee) * COIN) except Exception: self.show_message(_('Invalid Fee')) return if self.wallet.has_password(): password = self.password_dialog() if not password: return else: password = None try: tx = self.wallet.mktx([(TYPE_ADDRESS, self.str_recipient, amount)], password, self.config, fee) except Exception as e: self.show_message(str(e)) return if self.str_description: self.wallet.labels[tx.txid()] = self.str_description self.show_message(_("Please wait..."), getchar=False) status, msg = self.network.broadcast_transaction(tx) if status: self.show_message(_('Payment sent.')) self.do_clear() #self.update_contacts_tab() else: self.show_message(_('Error'))
def listunspent(self): """List unspent outputs. Returns the list of unspent transaction outputs in your wallet.""" l = self.wallet.get_utxos(exclude_frozen=False) for i in l: v = i["value"] height, conf, timestamp = self.wallet.get_tx_height( i['prevout_hash']) i["value"] = str(PyDecimal(v) / COIN) if v is not None else None i["address"] = i["address"].to_ui_string() i["confirmations"] = conf return l
def generate_val(self, val_type): '''Generate and return a single random val. Use the val_type parameter to specify the type of val to generate. See types.py for valid val_type options. Ex: generator = RandomValGenerator(min_number=1, max_number=5) val = generator.generate_val(model.Int) assert 1 <= val and val <= 5 ''' if issubclass(val_type, Char): val = self.generate_val(Int) return None if val is None else str(val)[:val_type.MAX] if random() < self.null_val_percentage: return None if issubclass(val_type, Int): return randint(max(self.min_number, val_type.MIN), min(val_type.MAX, self.max_number)) if issubclass(val_type, Decimal): # Create an int within the maximum length of the Decimal, then shift the decimal # point as needed. if val_type.MAX_FRACTIONAL_DIGITS > self.max_decimal_fractional_digits: max_digits = val_type.MAX_DIGITS \ - (val_type.MAX_FRACTIONAL_DIGITS - self.max_decimal_fractional_digits) fractal_digits = self.max_decimal_fractional_digits else: max_digits = val_type.MAX_DIGITS fractal_digits = val_type.MAX_FRACTIONAL_DIGITS max_type_val = 10**max_digits decimal_point_shift = 10**fractal_digits max_val = min(self.max_number * decimal_point_shift, max_type_val) min_val = max(self.min_number * decimal_point_shift, -1 * max_type_val) return PyDecimal(randint(min_val + 1, max_val - 1)) / decimal_point_shift if issubclass(val_type, Float): return uniform(self.min_number, self.max_number) if issubclass(val_type, Timestamp): delta = self.max_date - self.min_date delta_in_seconds = delta.days * 24 * 60 * 60 + delta.seconds offset_in_seconds = randint(0, delta_in_seconds) val = self.min_date + timedelta(0, offset_in_seconds) return datetime(val.year, val.month, val.day) if issubclass(val_type, Boolean): return randint(0, 1) == 1 raise Exception('Unsupported type %s' % val_type.__name__)
def get_rates(self, ccy): json_eur = self.get_json('wex.nz', '/api/3/ticker/bch_eur') json_rub = self.get_json('wex.nz', '/api/3/ticker/bch_rur') json_usd = self.get_json('wex.nz', '/api/3/ticker/bch_usd') json_btc = self.get_json('wex.nz', '/api/3/ticker/bch_btc') json_ltc = self.get_json('wex.nz', '/api/3/ticker/bch_ltc') json_eth = self.get_json('wex.nz', '/api/3/ticker/bch_eth') json_dsh = self.get_json('wex.nz', '/api/3/ticker/bch_dsh') return {'EUR': PyDecimal(json_eur['bch_eur']['last']), 'RUB': PyDecimal(json_rub['bch_rur']['last']), 'USD': PyDecimal(json_usd['bch_usd']['last']), 'BTC': PyDecimal(json_btc['bch_btc']['last']), 'LTC': PyDecimal(json_ltc['bch_ltc']['last']), 'ETH': PyDecimal(json_eth['bch_eth']['last']), 'DSH': PyDecimal(json_dsh['bch_dsh']['last'])}
def _mktx(self, outputs, fee=None, feerate=None, change_addr=None, domain=None, nocheck=False, unsigned=False, password=None, locktime=None, op_return=None, op_return_raw=None, addtransaction=False): if fee is not None and feerate is not None: raise ValueError("Cannot specify both 'fee' and 'feerate' at the same time!") if op_return and op_return_raw: raise ValueError('Both op_return and op_return_raw cannot be specified together!') self.nocheck = nocheck change_addr = self._resolver(change_addr) domain = None if domain is None else map(self._resolver, domain) final_outputs = [] if op_return: final_outputs.append(OPReturn.output_for_stringdata(op_return)) elif op_return_raw: try: op_return_raw = op_return_raw.strip() tmp = bytes.fromhex(op_return_raw).hex() assert tmp == op_return_raw.lower() op_return_raw = tmp except Exception as e: raise ValueError("op_return_raw must be an even number of hex digits") from e final_outputs.append(OPReturn.output_for_rawhex(op_return_raw)) for address, amount in outputs: address = self._resolver(address) amount = satoshis(amount) final_outputs.append((TYPE_ADDRESS, address, amount)) coins = self.wallet.get_spendable_coins(domain, self.config) if feerate is not None: fee_per_kb = 1000 * PyDecimal(feerate) fee_estimator = lambda size: SimpleConfig.estimate_fee_for_feerate(fee_per_kb, size) else: fee_estimator = fee tx = self.wallet.make_unsigned_transaction(coins, final_outputs, self.config, fee_estimator, change_addr) if locktime != None: tx.locktime = locktime if not unsigned: run_hook('sign_tx', self.wallet, tx) self.wallet.sign_transaction(tx, password) if addtransaction: self.wallet.add_transaction(tx.txid(), tx) self.wallet.add_tx_to_history(tx.txid()) self.wallet.save_transactions() return tx
def historical_value(self, satoshis, d_t): rate = self.history_rate(d_t) if rate: return PyDecimal(satoshis) / COIN * PyDecimal(rate)
def exchange_rate(self): '''Returns None, or the exchange rate as a PyDecimal''' rate = self.exchange.quotes.get(self.ccy) if rate: return PyDecimal(rate)
def get_rates(self, ccy): json = self.get_json('api.coincap.io', '/v2/rates/bitcoin-cash/') return {'USD': PyDecimal(json['data']['rateUsd'])}
def get_rates(self, ccy): json = self.get_json('webapi.coinfloor.co.uk:8090/bist/BCH/GBP', '/ticker/') return {'GBP': PyDecimal(json['last'])}
def get_rates(self, ccy): json = self.get_json('api.bitso.com', '/v2/ticker/?book=bch_btc') return {'BTC': PyDecimal(json['last'])}
def get_rates(self, ccy): json = self.get_json('bitpay.com', '/api/rates/BCH') return dict([(r['code'], PyDecimal(r['rate'])) for r in json])