def update_history_tab(self): cursor = self.history_treeview.get_cursor()[0] self.history_list.clear() for item in self.wallet.get_tx_history(): tx_hash, conf, is_mine, value, fee, balance, timestamp = item if conf > 0: try: time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3] except: time_str = "------" conf_icon = gtk.STOCK_APPLY elif conf == -1: time_str = 'unverified' conf_icon = None else: time_str = 'pending' conf_icon = gtk.STOCK_EXECUTE label, is_default_label = self.wallet.get_label(tx_hash) tooltip = tx_hash + "\n%d confirmations"%conf if tx_hash else '' details = self.get_tx_details(tx_hash) self.history_list.prepend( [tx_hash, conf_icon, time_str, label, is_default_label, format_satoshis(value,True,self.num_zeros, whitespaces=True), format_satoshis(balance,False,self.num_zeros, whitespaces=True), tooltip, details] ) if cursor: self.history_treeview.set_cursor( cursor )
def get_tx_details(self, tx_hash): import datetime if not tx_hash: return '' tx = self.wallet.transactions.get(tx_hash) is_relevant, is_mine, v, fee = self.wallet.get_tx_value(tx) conf, timestamp = self.wallet.verifier.get_confirmations(tx_hash) if timestamp: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] else: time_str = 'pending' inputs = map(lambda x: x.get('address'), tx.inputs) outputs = map(lambda x: x.get('address'), tx.d['outputs']) tx_details = "Transaction Details" +"\n\n" \ + "Transaction ID:\n" + tx_hash + "\n\n" \ + "Status: %d confirmations\n"%conf if is_mine: if fee: tx_details += "Amount sent: %s\n"% format_satoshis(v-fee, False) \ + "Transaction fee: %s\n"% format_satoshis(fee, False) else: tx_details += "Amount sent: %s\n"% format_satoshis(v, False) \ + "Transaction fee: unknown\n" else: tx_details += "Amount received: %s\n"% format_satoshis(v, False) \ tx_details += "Date: %s\n\n"%time_str \ + "Inputs:\n-"+ '\n-'.join(inputs) + "\n\n" \ + "Outputs:\n-"+ '\n-'.join(outputs) return tx_details
def update_status_bar(self): interface = self.wallet.interface if self.funds_error: text = "Not enough funds" elif interface and interface.is_connected: self.network_button.set_tooltip_text("Connected to %s:%d.\n%d blocks"%(interface.host, interface.port, self.wallet.network.blockchain.height)) if not self.wallet.up_to_date: self.status_image.set_from_stock(gtk.STOCK_REFRESH, gtk.ICON_SIZE_MENU) text = "Synchronizing..." else: self.status_image.set_from_stock(gtk.STOCK_YES, gtk.ICON_SIZE_MENU) self.network_button.set_tooltip_text("Connected to %s:%d.\n%d blocks"%(interface.host, interface.port, self.wallet.network.blockchain.height)) c, u = self.wallet.get_balance() text = "Balance: %s "%( format_satoshis(c,False,self.num_zeros) ) if u: text += "[%s unconfirmed]"%( format_satoshis(u,True,self.num_zeros).strip() ) else: self.status_image.set_from_stock(gtk.STOCK_NO, gtk.ICON_SIZE_MENU) self.network_button.set_tooltip_text("Not connected.") text = "Not connected" self.status_bar.pop(self.context_id) self.status_bar.push(self.context_id, text) if self.wallet.up_to_date and self.wallet_updated: self.update_history_tab() self.update_receiving_tab() # addressbook too... self.info.set_text( self.wallet.interface.banner ) self.wallet_updated = False
def update_status_bar(self): if self.funds_error: text = "Not enough funds" elif self.network.is_connected(): host, port, _,_,_ = self.network.get_parameters() port = int(port) height = self.network.get_local_height() self.network_button.set_tooltip_text("Connected to %s:%d.\n%d blocks"%(host, port, height)) if not self.wallet.up_to_date: self.status_image.set_from_stock(Gtk.STOCK_REFRESH, Gtk.IconSize.MENU) text = "Synchronizing..." else: self.status_image.set_from_stock(Gtk.STOCK_YES, Gtk.IconSize.MENU) c, u = self.wallet.get_balance() text = "Balance: %s "%( format_satoshis(c,False,self.num_zeros) ) if u: text += "[%s unconfirmed]"%( format_satoshis(u,True,self.num_zeros).strip() ) else: self.status_image.set_from_stock(Gtk.STOCK_NO, Gtk.IconSize.MENU) self.network_button.set_tooltip_text("Not connected.") text = "Not connected" self.status_bar.pop(self.context_id) self.status_bar.push(self.context_id, text) if self.wallet.up_to_date and self.wallet_updated: self.update_history_tab() self.update_receiving_tab() # addressbook too... self.info.set_text( self.network.banner ) self.wallet_updated = False
def test_format_fee_precision(self): result = format_satoshis(1666/1000, 0, 0, precision=6) expected = "1.666" self.assertEqual(expected, result) result = format_satoshis(1666/1000, 0, 0, precision=1) expected = "1.7" self.assertEqual(expected, result)
def test_format_satoshis_whitespaces_negative(self): result = format_satoshis(-12340, whitespaces=True) expected = " -0.0001234 " self.assertEqual(expected, result) result = format_satoshis(-1234, whitespaces=True) expected = " -0.00001234" self.assertEqual(expected, result)
def updateHistory(): bppclient.ui.txhist.setRowCount(0) t = None c = 0 for t in bppclient.confpayhist: c += 1 bppclient.ui.txhist.insertRow(0) bppclient.ui.txhist.setItem(0, 0, QtGui.QTableWidgetItem(t[6])) bppclient.ui.txhist.setItem(0, 1, QtGui.QTableWidgetItem(t[4])) bppclient.ui.txhist.setItem(0, 2, QtGui.QTableWidgetItem(t[2])) bppclient.ui.txhist.setItem(0, 3, QtGui.QTableWidgetItem(t[3])) bppclient.ui.txhist.setItem(0, 4, QtGui.QTableWidgetItem(format_satoshis(t[7]))) newtx = False cur = bppclient.payhist.cursor() for item in bppclient.wallet.get_tx_history()[c:]: tx_hash, conf, is_mine, value, fee, balance, timestamp = item txin = bppclient.wallet.transactions.get(tx_hash).inputs[0].get('prevout_hash') print tx_hash, conf, value if conf > 0: try: time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3] except Exception: time_str = "------" try: if txin in bppclient.pendpayhist: i = bppclient.pendpayhist[txin] cur.execute("INSERT INTO ConfPay VALUES(?, ?, ?, ?, ?, ?, ?, ?)", (txin,i[0],i[1],i[2],i[3],i[4], time_str, value)) cur.execute("DELETE FROM PendPay WHERE `Txin` = '%s'"%txin) ref, frm, to = i[3],i[1],i[2] bppclient.confpayhist += ((txin,i[0],i[1],i[2],i[3],i[4], time_str, value),) del bppclient.pendpayhist[txin] else: oaddr = bppclient.wallet.transactions.get(tx_hash).outputs[0][0] iaddr = bppclient.wallet.transactions.get(tx_hash).inputs[0].get('address') cur.execute("INSERT INTO ConfPay VALUES(?, ?, ?, ?, ?, ?, ?, ?)", (txin,'',iaddr, oaddr, '', '', time_str, value)) ref, frm, to = '',iaddr,oaddr bppclient.confpayhist += ((txin,'',iaddr,oaddr,'','', time_str, value),) except Db.Error, e: if bppclient.payhist: bppclient.payhist.rollback() QtGui.QMessageBox.critical(bppclient, 'Error', e.args[0], QtGui.QMessageBox.Ok) else: time_str = 'unverified' if conf == -1 else 'pending' if txin in bppclient.pendpayhist: i = bppclient.pendpayhist[txin] ref, frm, to = i[3],i[1],i[2] else: oaddr = bppclient.wallet.transactions.get(tx_hash).outputs[0][0] iaddr = bppclient.wallet.transactions.get(tx_hash).inputs[0].get('address') ref, frm, to = '',iaddr,oaddr bppclient.ui.txhist.insertRow(0) bppclient.ui.txhist.setItem(0, 0, QtGui.QTableWidgetItem(time_str)) bppclient.ui.txhist.setItem(0, 1, QtGui.QTableWidgetItem(ref)) bppclient.ui.txhist.setItem(0, 2, QtGui.QTableWidgetItem(frm)) bppclient.ui.txhist.setItem(0, 3, QtGui.QTableWidgetItem(to)) bppclient.ui.txhist.setItem(0, 4, QtGui.QTableWidgetItem(format_satoshis(value)))
def csv_transaction(wallet): try: select_export = _("Select file to export your wallet transactions to") fileName = QFileDialog.getSaveFileName( QWidget(), select_export, os.path.expanduser("~/electrum-history.csv"), "*.csv" ) if fileName: with open(fileName, "w+") as csvfile: transaction = csv.writer(csvfile) transaction.writerow( ["transaction_hash", "label", "confirmations", "value", "fee", "balance", "timestamp"] ) for item in wallet.get_tx_history(): tx_hash, confirmations, is_mine, value, fee, balance, timestamp = item if confirmations: if timestamp is not None: try: time_string = datetime.datetime.fromtimestamp(timestamp).isoformat(" ")[:-3] except [RuntimeError, TypeError, NameError] as reason: time_string = "unknown" pass else: time_string = "unknown" else: time_string = "pending" if value is not None: value_string = format_satoshis(value, True) else: value_string = "--" if fee is not None: fee_string = format_satoshis(fee, True) else: fee_string = "0" if tx_hash: label, is_default_label = wallet.get_label(tx_hash) else: label = "" balance_string = format_satoshis(balance, False) transaction.writerow( [tx_hash, label, confirmations, value_string, fee_string, balance_string, time_string] ) QMessageBox.information( None, _("CSV Export created"), _("Your CSV export has been successfully created.") ) except (IOError, os.error), reason: export_error_label = _("Electrum was unable to produce a transaction export.") QMessageBox.critical(None, _("Unable to create csv"), export_error_label + "\n" + str(reason))
def format_amount(self, x, is_diff=False, whitespaces=False): """ """ global format_satoshis if not format_satoshis: from electrum.util import format_satoshis return format_satoshis(x, is_diff, self.num_zeros, self.decimal_point, whitespaces)
def update_history(self): width = [20, 40, 14, 14] delta = (self.maxx - sum(width) - 4) / 3 format_str = ( "%" + "%d" % width[0] + "s" + "%" + "%d" % (width[1] + delta) + "s" + "%" + "%d" % (width[2] + delta) + "s" + "%" + "%d" % (width[3] + delta) + "s" ) b = 0 self.history = [] for item in self.wallet.get_history(): tx_hash, conf, value, timestamp, balance = item if conf: try: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(" ")[:-3] except Exception: time_str = "------" else: time_str = "pending" label, is_default_label = self.wallet.get_label(tx_hash) if len(label) > 40: label = label[0:37] + "..." self.history.append( format_str % ( time_str, label, format_satoshis(value, whitespaces=True), format_satoshis(balance, whitespaces=True), ) )
def update_history(self, tx_history): self.history_list.empty() for item in tx_history[-10:]: tx_hash, conf, is_mine, value, fee, balance, timestamp = item label = self.actuator.wallet.get_label(tx_hash)[0] #amount = D(value) / 10**8 v_str = format_satoshis(value, True) self.history_list.append(label, v_str, age(timestamp))
def print_history(self): width = [20, 40, 14, 14] delta = (80 - sum(width) - 4) / 3 format_str = ( "%" + "%d" % width[0] + "s" + "%" + "%d" % (width[1] + delta) + "s" + "%" + "%d" % (width[2] + delta) + "s" + "%" + "%d" % (width[3] + delta) + "s" ) b = 0 messages = [] for item in self.wallet.get_history(): tx_hash, confirmations, value, timestamp, balance = item if confirmations: try: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(" ")[:-3] except Exception: time_str = "unknown" else: time_str = "pending" label = self.wallet.get_label(tx_hash) messages.append( format_str % ( time_str, label, format_satoshis(value, whitespaces=True), format_satoshis(balance, whitespaces=True), ) ) self.print_list(messages[::-1], format_str % (_("Date"), _("Description"), _("Amount"), _("Balance")))
def settings_dialog(self): out = self.run_dialog('Settings', [ {'label':'Default GUI', 'type':'list', 'choices':['classic','lite','gtk','text'], 'value':self.config.get('gui')}, {'label':'Default fee', 'type':'satoshis', 'value': format_satoshis(self.wallet.fee).strip() } ], buttons = 1) if out: if out.get('Default GUI'): self.config.set_key('gui', out['Default GUI'], True) if out.get('Default fee'): fee = int ( Decimal( out['Default fee']) *10000000 ) self.config.set_key('fee_per_kb', fee, True)
def print_history(self): width = [20, 40, 14, 14] delta = (self.maxx - sum(width) - 4)/3 format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%"+"%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s" b = 0 messages = [] for item in self.wallet.get_tx_history(): tx_hash, conf, is_mine, value, fee, balance, timestamp = item if conf: try: time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3] except: time_str = "------" else: time_str = 'pending' label, is_default_label = self.wallet.get_label(tx_hash) messages.append( format_str%( time_str, label, format_satoshis(value), format_satoshis(balance) ) ) self.print_list(messages[::-1], format_str%( _("Date"), _("Description"), _("Amount"), _("Balance")))
def update_history(self): width = [20, 40, 14, 14] delta = (self.maxx - sum(width) - 4)/3 format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%"+"%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s" b = 0 self.history = [] for hist_item in self.wallet.get_history(): if hist_item.tx_mined_status.conf: timestamp = hist_item.tx_mined_status.timestamp try: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] except Exception: time_str = "------" else: time_str = 'unconfirmed' label = self.wallet.get_label(hist_item.txid) if len(label) > 40: label = label[0:37] + '...' self.history.append(format_str % (time_str, label, format_satoshis(hist_item.value, whitespaces=True), format_satoshis(hist_item.balance, whitespaces=True)))
def get_tx_details(self, tx_hash): import datetime if not tx_hash: return "" tx = self.wallet.transactions.get(tx_hash) tx.deserialize() is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx) conf, timestamp = self.wallet.get_confirmations(tx_hash) if timestamp: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(" ")[:-3] else: time_str = "pending" inputs = map(lambda x: x.get("address"), tx.inputs) outputs = map(lambda x: x[0], tx.get_outputs()) tx_details = ( "Transaction Details" + "\n\n" + "Transaction ID:\n" + tx_hash + "\n\n" + "Status: %d confirmations\n" % conf ) if is_mine: if fee: tx_details += "Amount sent: %s\n" % format_satoshis( v - fee, False ) + "Transaction fee: %s\n" % format_satoshis(fee, False) else: tx_details += "Amount sent: %s\n" % format_satoshis(v, False) + "Transaction fee: unknown\n" else: tx_details += "Amount received: %s\n" % format_satoshis(v, False) tx_details += ( "Date: %s\n\n" % time_str + "Inputs:\n-" + "\n-".join(inputs) + "\n\n" + "Outputs:\n-" + "\n-".join(outputs) ) return tx_details
def print_history(self): width = [20, 40, 14, 14] delta = (80 - sum(width) - 4)/3 format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%" \ + "%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s" messages = [] for hist_item in reversed(self.wallet.get_history()): if hist_item.tx_mined_status.conf: timestamp = hist_item.tx_mined_status.timestamp try: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] except Exception: time_str = "unknown" else: time_str = 'unconfirmed' label = self.wallet.get_label(hist_item.txid) messages.append(format_str % (time_str, label, format_satoshis(delta, whitespaces=True), format_satoshis(hist_item.balance, whitespaces=True))) self.print_list(messages[::-1], format_str%( _("Date"), _("Description"), _("Amount"), _("Balance")))
def update_status_bar(self): if self.funds_error: text = "Not enough funds" elif self.network.is_connected(): host, port, _, _, _ = self.network.get_parameters() port = int(port) height = self.network.get_local_height() self.network_button.set_tooltip_text( "Connected to %s:%d.\n%d blocks" % (host, port, height)) if not self.wallet.up_to_date: self.status_image.set_from_stock(Gtk.STOCK_REFRESH, Gtk.IconSize.MENU) text = "Synchronizing..." else: self.status_image.set_from_stock(Gtk.STOCK_YES, Gtk.IconSize.MENU) c, u = self.wallet.get_balance() text = "Balance: %s " % (format_satoshis( c, False, self.num_zeros)) if u: text += "[%s unconfirmed]" % (format_satoshis( u, True, self.num_zeros).strip()) else: self.status_image.set_from_stock(Gtk.STOCK_NO, Gtk.IconSize.MENU) self.network_button.set_tooltip_text("Not connected.") text = "Not connected" self.status_bar.pop(self.context_id) self.status_bar.push(self.context_id, text) if self.wallet.up_to_date and self.wallet_updated: self.update_history_tab() self.update_receiving_tab() # addressbook too... self.info.set_text(self.network.banner) self.wallet_updated = False
def update_history_tab(self): cursor = self.history_treeview.get_cursor()[0] self.history_list.clear() for item in self.wallet.get_tx_history(): tx_hash, conf, is_mine, value, fee, balance, timestamp = item if conf > 0: try: time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3] except: time_str = "------" conf_icon = gtk.STOCK_APPLY elif conf == -1: time_str = 'unverified' conf_icon = None else: time_str = 'pending' conf_icon = gtk.STOCK_EXECUTE label, is_default_label = self.wallet.get_label(tx_hash) tooltip = tx_hash + "\n%d confirmations" % conf if tx_hash else '' details = self.get_tx_details(tx_hash) self.history_list.prepend([ tx_hash, conf_icon, time_str, label, is_default_label, format_satoshis(value, True, self.wallet.num_zeros, whitespaces=True), format_satoshis(balance, False, self.wallet.num_zeros, whitespaces=True), tooltip, details ]) if cursor: self.history_treeview.set_cursor(cursor)
def update_receiving_tab(self): self.recv_list.clear() for address in self.wallet.addresses(True): Type = "R" c = u = 0 if self.wallet.is_change(address): Type = "C" if address in self.wallet.imported_keys.keys(): Type = "I" c, u = self.wallet.get_addr_balance(address) if address in self.wallet.frozen_addresses: Type = Type + "F" label = self.wallet.labels.get(address) h = self.wallet.history.get(address,[]) n = len(h) tx = "0" if n==0 else "%d"%n self.recv_list.append((address, label, tx, format_satoshis(c,False,self.num_zeros), Type ))
def settings_dialog(self): out = self.run_dialog( 'Settings', [{ 'label': 'Default GUI', 'type': 'list', 'choices': ['classic', 'lite', 'gtk', 'text'], 'value': self.config.get('gui') }, { 'label': 'Default fee', 'type': 'satoshis', 'value': format_satoshis(self.wallet.fee).strip() }], buttons=1) if out: if out.get('Default GUI'): self.config.set_key('gui', out['Default GUI'], True) if out.get('Default fee'): fee = int(Decimal(out['Default fee']) * 10000000) self.config.set_key('fee_per_kb', fee, True)
def settings_dialog(self): out = self.run_dialog( "Settings", [ { "label": "Default GUI", "type": "list", "choices": ["classic", "lite", "gtk", "text"], "value": self.config.get("gui"), }, {"label": "Default fee", "type": "satoshis", "value": format_satoshis(self.wallet.fee_per_kb).strip()}, ], buttons=1, ) if out: if out.get("Default GUI"): self.config.set_key("gui", out["Default GUI"], True) if out.get("Default fee"): fee = int(Decimal(out["Default fee"]) * COIN) self.config.set_key("fee_per_kb", fee, True)
def update_history(self): width = [20, 40, 14, 14] delta = (self.maxx - sum(width) - 4)/3 format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%"+"%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s" b = 0 self.history = [] for item in self.wallet.get_tx_history(): tx_hash, conf, is_mine, value, fee, balance, timestamp = item if conf: try: time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3] except Exception: time_str = "------" else: time_str = 'pending' label, is_default_label = self.wallet.get_label(tx_hash) self.history.append( format_str%( time_str, label, format_satoshis(value, whitespaces=True), format_satoshis(balance, whitespaces=True) ) )
def update_history(self): width = [20, 40, 14, 14] delta = (self.maxx - sum(width) - 4)/3 format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%"+"%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s" b = 0 self.history = [] for item in self.wallet.get_history(): tx_hash, height, conf, timestamp, value, balance = item if conf: try: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] except Exception: time_str = "------" else: time_str = 'unconfirmed' label = self.wallet.get_label(tx_hash) if len(label) > 40: label = label[0:37] + '...' self.history.append( format_str%( time_str, label, format_satoshis(value, whitespaces=True), format_satoshis(balance, whitespaces=True) ) )
def print_history(self): width = [20, 40, 14, 14] delta = (80 - sum(width) - 4)/3 format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%" \ + "%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s" messages = [] for item in self.wallet.get_history(): tx_hash, height, conf, timestamp, delta, balance = item if conf: try: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] except Exception: time_str = "unknown" else: time_str = 'unconfirmed' label = self.wallet.get_label(tx_hash) messages.append( format_str%( time_str, label, format_satoshis(delta, whitespaces=True), format_satoshis(balance, whitespaces=True) ) ) self.print_list(messages[::-1], format_str%( _("Date"), _("Description"), _("Amount"), _("Balance")))
def update_history(self): width = [20, 40, 14, 14] delta = (self.maxx - sum(width) - 4)/3 format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%"+"%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s" b = 0 self.history = [] for tx_hash, tx_mined_status, value, balance in self.wallet.get_history(): if tx_mined_status.conf: timestamp = tx_mined_status.timestamp try: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] except Exception: time_str = "------" else: time_str = 'unconfirmed' label = self.wallet.get_label(tx_hash) if len(label) > 40: label = label[0:37] + '...' self.history.append( format_str%( time_str, label, format_satoshis(value, whitespaces=True), format_satoshis(balance, whitespaces=True) ) )
def print_history(self): width = [20, 40, 14, 14] delta = (80 - sum(width) - 4)/3 format_str = "%"+"%d"%width[0]+"s"+"%"+"%d"%(width[1]+delta)+"s"+"%" \ + "%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s" messages = [] for tx_hash, tx_mined_status, delta, balance in reversed(self.wallet.get_history()): if tx_mined_status.conf: timestamp = tx_mined_status.timestamp try: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] except Exception: time_str = "unknown" else: time_str = 'unconfirmed' label = self.wallet.get_label(tx_hash) messages.append( format_str%( time_str, label, format_satoshis(delta, whitespaces=True), format_satoshis(balance, whitespaces=True) ) ) self.print_list(messages[::-1], format_str%( _("Date"), _("Description"), _("Amount"), _("Balance")))
def propose_rebuy_qt(amount): web = QWebView() box = QMessageBox() box.setFixedSize(200, 200) credentials = read_local_oauth_credentials() questionText = _('Rebuy ') + format_satoshis(amount) + _(' BTC?') if credentials: credentials.refresh() if credentials and not credentials.invalid: credentials.store_locally() totalPrice = get_coinbase_total_price(credentials, amount) questionText += _('\n(Price: ') + totalPrice + _(')') if not question(box, questionText): return if credentials: do_buy(credentials, amount) else: do_oauth_flow(web, amount) return web
def test_format_satoshis_whitespaces(self): self.assertEqual(" 0.0001234 ", format_satoshis(12340, whitespaces=True)) self.assertEqual(" 0.00001234", format_satoshis(1234, whitespaces=True)) self.assertEqual( " 0.45831275", format_satoshis(Decimal("45831275."), whitespaces=True)) self.assertEqual( " 0.45831275 ", format_satoshis(Decimal("45831275."), whitespaces=True, precision=3)) self.assertEqual( " 0.458312757 ", format_satoshis(Decimal("45831275.7"), whitespaces=True, precision=3)) self.assertEqual( " 0.45831275748", format_satoshis(Decimal("45831275.748"), whitespaces=True, precision=3))
def do_plot(self, wallet): history = wallet.get_tx_history() balance_Val = [] fee_val = [] value_val = [] datenums = [] unknown_trans = 0 pending_trans = 0 counter_trans = 0 for item in history: tx_hash, confirmations, is_mine, value, fee, balance, timestamp = item if confirmations: if timestamp is not None: try: datenums.append( md.date2num( datetime.datetime.fromtimestamp(timestamp))) balance_string = format_satoshis(balance, False) balance_Val.append( float((format_satoshis(balance, False))) * 1000.0) except [RuntimeError, TypeError, NameError] as reason: unknown_trans = unknown_trans + 1 pass else: unknown_trans = unknown_trans + 1 else: pending_trans = pending_trans + 1 if value is not None: value_string = format_satoshis(value, True) value_val.append(float(value_string) * 1000.0) else: value_string = '--' if fee is not None: fee_string = format_satoshis(fee, True) fee_val.append(float(fee_string)) else: fee_string = '0' if tx_hash: label, is_default_label = wallet.get_label(tx_hash) label = label.encode('utf-8') else: label = "" f, axarr = plt.subplots(2, sharex=True) plt.subplots_adjust(bottom=0.2) plt.xticks(rotation=25) ax = plt.gca() x = 19 test11 = "Unknown transactions = " + str( unknown_trans) + " Pending transactions = " + str( pending_trans) + " ." box1 = TextArea(" Test : Number of pending transactions", textprops=dict(color="k")) box1.set_text(test11) box = HPacker(children=[box1], align="center", pad=0.1, sep=15) anchored_box = AnchoredOffsetbox( loc=3, child=box, pad=0.5, frameon=True, bbox_to_anchor=(0.5, 1.02), bbox_transform=ax.transAxes, borderpad=0.5, ) ax.add_artist(anchored_box) plt.ylabel('mBTC') plt.xlabel('Dates') xfmt = md.DateFormatter('%Y-%m-%d') ax.xaxis.set_major_formatter(xfmt) axarr[0].plot(datenums, balance_Val, marker='o', linestyle='-', color='blue', label='Balance') axarr[0].legend(loc='upper left') axarr[0].set_title('History Transactions') xfmt = md.DateFormatter('%Y-%m-%d') ax.xaxis.set_major_formatter(xfmt) axarr[1].plot(datenums, fee_val, marker='o', linestyle='-', color='red', label='Fee') axarr[1].plot(datenums, value_val, marker='o', linestyle='-', color='green', label='Value') axarr[1].legend(loc='upper left') # plt.annotate('unknown transaction = %d \n pending transactions = %d' %(unknown_trans,pending_trans),xy=(0.7,0.05),xycoords='axes fraction',size=12) plt.show()
def test_format_satoshis_add_thousands_sep(self): self.assertEqual( "178 890 000.", format_satoshis(Decimal(178890000), decimal_point=0, add_thousands_sep=True)) self.assertEqual( "458 312.757 48", format_satoshis(Decimal("45831275.748"), decimal_point=2, add_thousands_sep=True, precision=5)) # is_diff self.assertEqual( "+4 583 127.574 8", format_satoshis(Decimal("45831275.748"), decimal_point=1, is_diff=True, add_thousands_sep=True, precision=4)) self.assertEqual( "+456 789 112.004 56", format_satoshis(Decimal("456789112.00456"), decimal_point=0, is_diff=True, add_thousands_sep=True, precision=5)) self.assertEqual( "-0.000 012 34", format_satoshis(-1234, is_diff=True, add_thousands_sep=True)) self.assertEqual( "-456 789.000 012 34", format_satoshis(-45678900001234, is_diff=True, add_thousands_sep=True)) # num_zeros self.assertEqual( "-456 789.123 400", format_satoshis(-45678912340000, num_zeros=6, add_thousands_sep=True)) self.assertEqual( "-456 789.123 4", format_satoshis(-45678912340000, num_zeros=2, add_thousands_sep=True)) # whitespaces self.assertEqual( " 1 432.731 11", format_satoshis(143273111, decimal_point=5, add_thousands_sep=True, whitespaces=True)) self.assertEqual( " 1 432.731 ", format_satoshis(143273100, decimal_point=5, add_thousands_sep=True, whitespaces=True)) self.assertEqual( " 67 891 432.731 ", format_satoshis(6789143273100, decimal_point=5, add_thousands_sep=True, whitespaces=True)) self.assertEqual( " 143 273 100.", format_satoshis(143273100, decimal_point=0, add_thousands_sep=True, whitespaces=True)) self.assertEqual( " 6 789 143 273 100.", format_satoshis(6789143273100, decimal_point=0, add_thousands_sep=True, whitespaces=True)) self.assertEqual( "56 789 143 273 100.", format_satoshis(56789143273100, decimal_point=0, add_thousands_sep=True, whitespaces=True))
def format_amount(self, x, is_diff=False, whitespaces=False): from electrum.util import format_satoshis return format_satoshis(x, is_diff, self.num_zeros, self.decimal_point, whitespaces)
def test_format_satoshis_diff_negative(self): self.assertEqual("-0.00001234", format_satoshis(-1234, is_diff=True))
def test_format_satoshis_diff_positive(self): self.assertEqual("+0.00001234", format_satoshis(1234, is_diff=True))
def do_plot(self,wallet): history = wallet.get_tx_history() balance_Val=[] fee_val=[] value_val=[] datenums=[] unknown_trans=0 pending_trans=0 counter_trans=0 for item in history: tx_hash, confirmations, is_mine, value, fee, balance, timestamp = item if confirmations: if timestamp is not None: try: datenums.append(md.date2num(datetime.datetime.fromtimestamp(timestamp))) balance_string = format_satoshis(balance, False) balance_Val.append(float((format_satoshis(balance,False)))*1000.0) except [RuntimeError, TypeError, NameError] as reason: unknown_trans=unknown_trans+1 pass else: unknown_trans=unknown_trans+1 else: pending_trans=pending_trans+1 if value is not None: value_string = format_satoshis(value, True) value_val.append(float(value_string)*1000.0) else: value_string = '--' if fee is not None: fee_string = format_satoshis(fee, True) fee_val.append(float(fee_string)) else: fee_string = '0' if tx_hash: label, is_default_label = wallet.get_label(tx_hash) label = label.encode('utf-8') else: label = "" f, axarr = plt.subplots(2, sharex=True) plt.subplots_adjust(bottom=0.2) plt.xticks( rotation=25 ) ax=plt.gca() x=19 test11="Unknown transactions = "+str(unknown_trans)+" Pending transactions = "+str(pending_trans)+" ." box1 = TextArea(" Test : Number of pending transactions", textprops=dict(color="k")) box1.set_text(test11) box = HPacker(children=[box1], align="center", pad=0.1, sep=15) anchored_box = AnchoredOffsetbox(loc=3, child=box, pad=0.5, frameon=True, bbox_to_anchor=(0.5, 1.02), bbox_transform=ax.transAxes, borderpad=0.5, ) ax.add_artist(anchored_box) plt.ylabel('mBTC') plt.xlabel('Dates') xfmt = md.DateFormatter('%Y-%m-%d') ax.xaxis.set_major_formatter(xfmt) axarr[0].plot(datenums,balance_Val,marker='o',linestyle='-',color='blue',label='Balance') axarr[0].legend(loc='upper left') axarr[0].set_title('History Transactions') xfmt = md.DateFormatter('%Y-%m-%d') ax.xaxis.set_major_formatter(xfmt) axarr[1].plot(datenums,fee_val,marker='o',linestyle='-',color='red',label='Fee') axarr[1].plot(datenums,value_val,marker='o',linestyle='-',color='green',label='Value') axarr[1].legend(loc='upper left') # plt.annotate('unknown transaction = %d \n pending transactions = %d' %(unknown_trans,pending_trans),xy=(0.7,0.05),xycoords='axes fraction',size=12) plt.show()
def update(self): self.wallet = self.parent.wallet addr_list = self.wallet.get_addresses() self.model().clear() self.asset_meta.clear() current_asset = self.current_item_user_role(col=self.Columns.IPFS) set_asset = None self.refresh_headers() assets = {} for address in addr_list: for asset, (c, u, x) in self.wallet.get_addr_balance(address)['ASSETS'].items(): if asset in assets: assets[asset]['balance'] += (c + u + x) else: meta = self.wallet.get_asset_meta(asset) meta['balance'] = (c + u + x) assets[asset] = meta for asset, meta in assets.items(): balance = meta['balance'] if balance == 0: # Don't display assets we no longer have continue if not self.parent.config.get('show_spam_assets', False): should_continue = False for regex in self.parent.asset_blacklist: if re.search(regex, asset): should_continue = True break for regex in self.parent.asset_whitelist: if re.search(regex, asset): should_continue = False break if should_continue: continue self.asset_meta[asset] = meta # 'Deep' copy reissuable = '' if 'reissuable' in meta: reissuable = str('No' if meta['reissuable'] == 0 else 'Yes') divisions = '' div_amt = 0 if 'divisions' in meta: div_amt = meta['divisions'] divisions = str(div_amt) ipfs = '' if 'ipfs' in meta: ipfs = meta['ipfs'] balance_text = format_satoshis( balance, div_amt, self.parent.decimal_point, is_diff=False, whitespaces=False) labels = [asset, balance_text, ipfs, reissuable, divisions] address_item = [QStandardItem(e) for e in labels] # align text and set fonts for i, item in enumerate(address_item): item.setTextAlignment(Qt.AlignVCenter) if i not in (self.Columns.NAME, self.Columns.IPFS): item.setFont(QFont(MONOSPACE_FONT)) item.setEditable(i in self.editable_columns) # address_item[self.Columns.BALANCE].setTextAlignment(Qt.AlignRight | Qt.AlignVCenter) count = self.model().rowCount() self.model().insertRow(count, address_item) address_idx = self.model().index(count, self.Columns.IPFS) if asset == current_asset: set_address = QPersistentModelIndex(address_idx) self.set_current_idx(set_asset) self.filter()
def test_format_satoshis_diff_negative(self): result = format_satoshis(-1234, is_diff=True) expected = "-0.00001234" self.assertEqual(expected, result)
def test_format_satoshis_negative(self): self.assertEqual("-0.00001234", format_satoshis(-1234))
def test_format_satoshis_decimal(self): self.assertEqual("0.00001234", format_satoshis(Decimal(1234)))
def sign_transaction(self, tx, password): if tx.is_complete(): return if tx.error: raise BaseException(tx.error) self.signing = True inputs = [] inputsPaths = [] pubKeys = [] trustedInputs = [] redeemScripts = [] signatures = [] preparedTrustedInputs = [] changePath = "" changeAmount = None output = None outputAmount = None use2FA = False pin = "" # Fetch inputs of the transaction to sign for txinput in tx.inputs: if ('is_coinbase' in txinput and txinput['is_coinbase']): self.give_error( "Coinbase not supported") # should never happen inputs.append([ self.transactions[txinput['prevout_hash']].raw, txinput['prevout_n'] ]) address = txinput['address'] inputsPaths.append(self.address_id(address)) pubKeys.append(self.get_public_keys(address)) # Recognize outputs - only one output and one change is authorized if len(tx.outputs) > 2: # should never happen self.give_error( "Transaction with more than 2 outputs not supported") for type, address, amount in tx.outputs: assert type == 'address' if self.is_change(address): changePath = self.address_id(address) changeAmount = amount else: if output <> None: # should never happen self.give_error( "Multiple outputs with no change not supported") output = address outputAmount = amount self.get_client( ) # prompt for the PIN before displaying the dialog if necessary if not self.check_proper_device(): self.give_error('Wrong device or password') waitDialog.start("Signing Transaction ...") try: # Get trusted inputs from the original transactions for utxo in inputs: txtmp = bitcoinTransaction(bytearray(utxo[0].decode('hex'))) trustedInputs.append(self.get_client().getTrustedInput( txtmp, utxo[1])) # TODO : Support P2SH later redeemScripts.append(txtmp.outputs[utxo[1]].script) # Sign all inputs firstTransaction = True inputIndex = 0 while inputIndex < len(inputs): self.get_client().startUntrustedTransaction( firstTransaction, inputIndex, trustedInputs, redeemScripts[inputIndex]) outputData = self.get_client().finalizeInput( output, format_satoshis(outputAmount), format_satoshis(self.get_tx_fee(tx)), changePath) if firstTransaction: transactionOutput = outputData['outputData'] if outputData['confirmationNeeded']: use2FA = True # TODO : handle different confirmation types. For the time being only supports keyboard 2FA waitDialog.emit(SIGNAL('dongle_done')) confirmed, p, pin = self.password_dialog() if not confirmed: raise Exception('Aborted by user') pin = pin.encode() self.client.bad = True self.device_checked = False self.get_client(True) waitDialog.start("Signing ...") else: # Sign input with the provided PIN inputSignature = self.get_client().untrustedHashSign( inputsPaths[inputIndex], pin) inputSignature[0] = 0x30 # force for 1.4.9+ signatures.append(inputSignature) inputIndex = inputIndex + 1 firstTransaction = False except Exception, e: self.give_error(e, True)
def test_format_satoshis_whitespaces(self): self.assertEqual(" 0.0001234 ", format_satoshis(12340, whitespaces=True)) self.assertEqual(" 0.00001234", format_satoshis(1234, whitespaces=True))
def format_amount(self, x, is_diff=False, whitespaces=False): return format_satoshis(x, is_diff, 0, self.decimal_point(), whitespaces)
def sign_transaction(self, tx, password): if tx.is_complete(): return if tx.error: raise BaseException(tx.error) self.signing = True inputs = [] inputsPaths = [] pubKeys = [] trustedInputs = [] redeemScripts = [] signatures = [] preparedTrustedInputs = [] changePath = "" changeAmount = None output = None outputAmount = None use2FA = False pin = "" # Fetch inputs of the transaction to sign for txinput in tx.inputs: if ('is_coinbase' in txinput and txinput['is_coinbase']): self.give_error("Coinbase not supported") # should never happen inputs.append([ self.transactions[txinput['prevout_hash']].raw, txinput['prevout_n'] ]) address = txinput['address'] inputsPaths.append(self.address_id(address)) pubKeys.append(self.get_public_keys(address)) # Recognize outputs - only one output and one change is authorized if len(tx.outputs) > 2: # should never happen self.give_error("Transaction with more than 2 outputs not supported") for type, address, amount in tx.outputs: assert type == 'address' if self.is_change(address): changePath = self.address_id(address) changeAmount = amount else: if output <> None: # should never happen self.give_error("Multiple outputs with no change not supported") output = address outputAmount = amount self.get_client() # prompt for the PIN before displaying the dialog if necessary if not self.check_proper_device(): self.give_error('Wrong device or password') waitDialog.start("Signing Transaction ...") try: # Get trusted inputs from the original transactions for utxo in inputs: txtmp = bitcoinTransaction(bytearray(utxo[0].decode('hex'))) trustedInputs.append(self.get_client().getTrustedInput(txtmp, utxo[1])) # TODO : Support P2SH later redeemScripts.append(txtmp.outputs[utxo[1]].script) # Sign all inputs firstTransaction = True inputIndex = 0 while inputIndex < len(inputs): self.get_client().startUntrustedTransaction(firstTransaction, inputIndex, trustedInputs, redeemScripts[inputIndex]) outputData = self.get_client().finalizeInput(output, format_satoshis(outputAmount), format_satoshis(self.get_tx_fee(tx)), changePath) if firstTransaction: transactionOutput = outputData['outputData'] if outputData['confirmationNeeded']: use2FA = True # TODO : handle different confirmation types. For the time being only supports keyboard 2FA waitDialog.emit(SIGNAL('dongle_done')) confirmed, p, pin = self.password_dialog() if not confirmed: raise Exception('Aborted by user') pin = pin.encode() self.client.bad = True self.device_checked = False self.get_client(True) waitDialog.start("Signing ...") else: # Sign input with the provided PIN inputSignature = self.get_client().untrustedHashSign(inputsPaths[inputIndex], pin) inputSignature[0] = 0x30 # force for 1.4.9+ signatures.append(inputSignature) inputIndex = inputIndex + 1 firstTransaction = False except Exception, e: self.give_error(e, True)
def test_format_satoshis_whitespaces_negative(self): self.assertEqual(" -0.0001234 ", format_satoshis(-12340, whitespaces=True)) self.assertEqual(" -0.00001234", format_satoshis(-1234, whitespaces=True))
def test_format_satoshis(self): self.assertEqual("0.00001234", format_satoshis(1234))
def test_format_satoshis_to_mbtc(self): self.assertEqual("0.01234", format_satoshis(1234, decimal_point=5))
def test_format_satoshis(self): result = format_satoshis(1234) expected = "0.00001234" self.assertEqual(expected, result)
def test_format_satoshis_msat_resolution(self): self.assertEqual("45831276.", format_satoshis(Decimal("45831276"), decimal_point=0)) self.assertEqual( "45831276.", format_satoshis(Decimal("45831275.748"), decimal_point=0)) self.assertEqual( "45831275.75", format_satoshis(Decimal("45831275.748"), decimal_point=0, precision=2)) self.assertEqual( "45831275.748", format_satoshis(Decimal("45831275.748"), decimal_point=0, precision=3)) self.assertEqual("458312.76", format_satoshis(Decimal("45831276"), decimal_point=2)) self.assertEqual( "458312.76", format_satoshis(Decimal("45831275.748"), decimal_point=2)) self.assertEqual( "458312.7575", format_satoshis(Decimal("45831275.748"), decimal_point=2, precision=2)) self.assertEqual( "458312.75748", format_satoshis(Decimal("45831275.748"), decimal_point=2, precision=3)) self.assertEqual("458.31276", format_satoshis(Decimal("45831276"), decimal_point=5)) self.assertEqual( "458.31276", format_satoshis(Decimal("45831275.748"), decimal_point=5)) self.assertEqual( "458.3127575", format_satoshis(Decimal("45831275.748"), decimal_point=5, precision=2)) self.assertEqual( "458.31275748", format_satoshis(Decimal("45831275.748"), decimal_point=5, precision=3))
def test_format_fee(self): result = format_satoshis(1700/1000, 0, 0) expected = "1.7" self.assertEqual(expected, result)