class ElectrumGui: def __init__(self, config, daemon, plugins): self.config = config self.network = daemon.network storage = WalletStorage(config.get_wallet_path()) if not storage.file_exists: print("Wallet not found. try 'electrum-pac create'") exit() if storage.is_encrypted(): password = getpass.getpass('Password:'******'backup_message', None): print(f'{storage.backup_message}\n') input('Press Enter to continue...') self.done = 0 self.last_balance = "" console_stderr_handler.setLevel(logging.CRITICAL) self.str_recipient = "" self.str_description = "" self.str_amount = "" self.str_fee = "" self.wallet = Wallet(storage) self.wallet.start_network(self.network) self.contacts = self.wallet.contacts self.network.register_callback( self.on_network, ['wallet_updated', 'network_updated', 'banner']) self.commands = [_("[h] - displays this help text"), \ _("[i] - display transaction history"), \ _("[o] - enter payment order"), \ _("[p] - print stored payment order"), \ _("[s] - send stored payment order"), \ _("[r] - show own receipt addresses"), \ _("[c] - display contacts"), \ _("[b] - print server banner"), \ _("[q] - quit") ] self.num_commands = len(self.commands) def on_network(self, event, *args): if event in ['wallet_updated', 'network_updated']: self.updated() elif event == 'banner': self.print_banner() def main_command(self): self.print_balance() c = input("enter command: ") if c == "h": self.print_commands() elif c == "i": self.print_history() elif c == "o": self.enter_order() elif c == "p": self.print_order() elif c == "s": self.send_order() elif c == "r": self.print_addresses() elif c == "c": self.print_contacts() elif c == "b": self.print_banner() elif c == "n": self.network_dialog() elif c == "e": self.settings_dialog() elif c == "q": self.done = 1 else: self.print_commands() def updated(self): s = self.get_balance() if s != self.last_balance: print(s) self.last_balance = s return True def print_commands(self): self.print_list(self.commands, "Available commands") def print_history(self): messages = [] hist_list = reversed(self.wallet.get_history(config=self.config)) show_dip2 = self.config.get('show_dip2_tx_type', False) if show_dip2: width = [20, 18, 22, 14, 14] wdelta = (80 - sum(width) - 5) // 3 format_str = ("%" + "%d" % width[0] + "s" + "%" + "%d" % width[1] + "s" + "%" + "%d" % (width[2] + wdelta) + "s" + "%" + "%d" % (width[3] + wdelta) + "s" + "%" + "%d" % (width[4] + wdelta) + "s") else: width = [20, 40, 14, 14] wdelta = (80 - sum(width) - 4) // 3 format_str = ("%" + "%d" % width[0] + "s" + "%" + "%d" % (width[1] + wdelta) + "s" + "%" + "%d" % (width[2] + wdelta) + "s" + "%" + "%d" % (width[3] + wdelta) + "s") for (tx_hash, tx_type, tx_mined_status, delta, balance, islock) in hist_list: if tx_mined_status.conf: timestamp = tx_mined_status.timestamp try: dttm = datetime.fromtimestamp(timestamp) time_str = dttm.isoformat(' ')[:-3] except Exception: time_str = "unknown" elif islock: dttm = datetime.fromtimestamp(islock) time_str = dttm.isoformat(' ')[:-3] else: time_str = 'unconfirmed' label = self.wallet.get_label(tx_hash) if show_dip2: tx_type_name = SPEC_TX_NAMES.get(tx_type, str(tx_type)) msg = format_str % (time_str, tx_type_name, label, format_satoshis(delta, whitespaces=True), format_satoshis(balance, whitespaces=True)) messages.append(msg) else: msg = format_str % (time_str, label, format_satoshis(delta, whitespaces=True), format_satoshis(balance, whitespaces=True)) messages.append(msg) if show_dip2: self.print_list( messages[::-1], format_str % (_("Date"), 'DIP2', _("Description"), _("Amount"), _("Balance"))) else: self.print_list( messages[::-1], format_str % (_("Date"), _("Description"), _("Amount"), _("Balance"))) def print_balance(self): print(self.get_balance()) 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 " % (Decimal(c) / COIN) if u: msg += " [%f unconfirmed]" % (Decimal(u) / COIN) if x: msg += " [%f unmatured]" % (Decimal(x) / COIN) else: msg = _("Not connected") return (msg) def print_contacts(self): messages = map(lambda x: "%20s %45s " % (x[0], x[1][1]), self.contacts.items()) self.print_list(messages, "%19s %25s " % ("Key", "Value")) def print_addresses(self): messages = map( lambda addr: "%30s %30s " % (addr, self.wallet.labels.get(addr, "")), self.wallet.get_addresses()) self.print_list(messages, "%19s %25s " % ("Address", "Label")) def print_order(self): print("send order to " + self.str_recipient + ", amount: " + self.str_amount \ + "\nfee: " + self.str_fee + ", desc: " + self.str_description) def enter_order(self): self.str_recipient = input("Pay to: ") self.str_description = input("Description : ") self.str_amount = input("Amount: ") self.str_fee = input("Fee: ") def send_order(self): self.do_send() def print_banner(self): for i, x in enumerate(self.wallet.network.banner.split('\n')): print(x) def print_list(self, lst, firstline): lst = list(lst) self.maxpos = len(lst) if not self.maxpos: return print(firstline) for i in range(self.maxpos): msg = lst[i] if i < len(lst) else "" print(msg) def main(self): while self.done == 0: self.main_command() def do_send(self): if not is_address(self.str_recipient): print(_('Invalid PACGlobal address')) return try: amount = int(Decimal(self.str_amount) * COIN) except Exception: print(_('Invalid Amount')) return try: fee = int(Decimal(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( [TxOutput(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...")) try: self.network.run_from_another_thread( self.network.broadcast_transaction(tx)) except TxBroadcastError as e: msg = e.get_message_for_gui() print(msg) except BestEffortRequestFailed as e: msg = repr(e) print(msg) else: print(_('Payment sent.')) #self.do_clear() #self.update_contacts_tab() def network_dialog(self): print( "use 'electrum-pac setconfig server/proxy' to change your network settings" ) return True def settings_dialog(self): print("use 'electrum-pac setconfig' to change your settings") return True def password_dialog(self): return getpass.getpass() # XXX unused def run_receive_tab(self, c): #if c == 10: # out = self.run_popup('Address', ["Edit label", "Freeze", "Prioritize"]) return def run_contacts_tab(self, c): pass
class ElectrumGui: def __init__(self, config, daemon, plugins): colorama.init() self.config = config self.network = network = daemon.network if config.get('tor_auto_on', True): if network: proxy_modifiable = config.is_modifiable('proxy') if not proxy_modifiable or not network.detect_tor_proxy(): print(network.TOR_WARN_MSG_TXT) c = '' while c != 'y': c = input("Continue without Tor (y/n)?") if c == 'n': exit() storage = WalletStorage(config.get_wallet_path()) if not storage.file_exists: print("Wallet not found. try 'electrum-dash create'") exit() if storage.is_encrypted(): password = getpass.getpass('Password:'******'Can not open unfinished multisig wallet') exit() if getattr(storage, 'backup_message', None): print(f'{storage.backup_message}\n') input('Press Enter to continue...') self.done = 0 self.last_balance = "" console_stderr_handler.setLevel(logging.CRITICAL) self.str_recipient = "" self.str_description = "" self.str_amount = "" self.str_fee = "" self.wallet = Wallet(db, storage, config=config) self.wallet.start_network(self.network) self.contacts = self.wallet.contacts util.register_callback(self.on_network, ['wallet_updated', 'network_updated', 'banner']) self.commands = [_("[h] - displays this help text"), \ _("[i] - display transaction history"), \ _("[o] - enter payment order"), \ _("[p] - print stored payment order"), \ _("[s] - send stored payment order"), \ _("[r] - show own receipt addresses"), \ _("[c] - display contacts"), \ _("[b] - print server banner"), \ _("[M] - start PrivateSend mixing"), _("[S] - stop PrivateSend mixing"), _("[l][f][a] - print PrivateSend log (filtered/all)"), _("[q] - quit") ] self.num_commands = len(self.commands) def on_network(self, event, *args): if event in ['wallet_updated', 'network_updated']: self.updated() elif event == 'banner': self.print_banner() def main_command(self): self.print_balance() c = input("enter command: ") if c == "h": self.print_commands() elif c == "i": self.print_history() elif c == "o": self.enter_order() elif c == "p": self.print_order() elif c == "s": self.send_order() elif c == "r": self.print_addresses() elif c == "c": self.print_contacts() elif c == "b": self.print_banner() elif c == "n": self.network_dialog() elif c == "e": self.settings_dialog() elif c == "M": self.start_mixing() elif c == "S": self.stop_mixing() elif c.startswith('l'): self.privatesend_log(c) elif c == "q": self.done = 1 else: self.print_commands() def updated(self): s = self.get_balance() if s != self.last_balance: print(s) self.last_balance = s return True def print_commands(self): self.print_list(self.commands, "Available commands") def print_history(self): messages = [] def_dip2 = not self.wallet.psman.unsupported show_dip2 = self.config.get('show_dip2_tx_type', def_dip2) if show_dip2: width = [20, 18, 22, 14, 14] wdelta = (80 - sum(width) - 5) // 3 format_str = ("%" + "%d" % width[0] + "s" + "%" + "%d" % width[1] + "s" + "%" + "%d" % (width[2] + wdelta) + "s" + "%" + "%d" % (width[3] + wdelta) + "s" + "%" + "%d" % (width[4] + wdelta) + "s") else: width = [20, 40, 14, 14] wdelta = (80 - sum(width) - 4) // 3 format_str = ("%" + "%d" % width[0] + "s" + "%" + "%d" % (width[1] + wdelta) + "s" + "%" + "%d" % (width[2] + wdelta) + "s" + "%" + "%d" % (width[3] + wdelta) + "s") for hist_item in reversed(self.wallet.get_history(config=self.config)): if hist_item.tx_mined_status.conf: timestamp = hist_item.tx_mined_status.timestamp try: dttm = datetime.fromtimestamp(timestamp) time_str = dttm.isoformat(' ')[:-3] except Exception: time_str = "unknown" elif hist_item.islock: dttm = datetime.fromtimestamp(hist_item.islock) time_str = dttm.isoformat(' ')[:-3] else: time_str = 'unconfirmed' label = self.wallet.get_label_for_txid(hist_item.txid) if show_dip2: tx_type = hist_item.tx_type tx_type_name = SPEC_TX_NAMES.get(tx_type, str(tx_type)) msg = format_str % ( time_str, tx_type_name, label, format_satoshis(hist_item.delta, whitespaces=True), format_satoshis(hist_item.balance, whitespaces=True)) else: msg = format_str % ( time_str, label, format_satoshis(hist_item.delta, whitespaces=True), format_satoshis(hist_item.balance, whitespaces=True)) messages.append(msg) if show_dip2: self.print_list( messages[::-1], format_str % (_("Date"), 'Type', _("Description"), _("Amount"), _("Balance"))) else: self.print_list( messages[::-1], format_str % (_("Date"), _("Description"), _("Amount"), _("Balance"))) def print_balance(self): print(self.get_balance()) 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 " % (Decimal(c) / COIN) if u: msg += " [%f unconfirmed]" % (Decimal(u) / COIN) if x: msg += " [%f unmatured]" % (Decimal(x) / COIN) else: msg = _("Not connected") return (msg) def print_contacts(self): messages = map(lambda x: "%20s %45s " % (x[0], x[1][1]), self.contacts.items()) self.print_list(messages, "%19s %25s " % ("Key", "Value")) def print_addresses(self): w = self.wallet addrs = w.get_addresses() + w.psman.get_addresses() messages = map( lambda addr: "%30s %30s " % (addr, self.wallet.get_label(addr)), addrs) self.print_list(messages, "%19s %25s " % ("Address", "Label")) def print_order(self): print("send order to " + self.str_recipient + ", amount: " + self.str_amount \ + "\nfee: " + self.str_fee + ", desc: " + self.str_description) def enter_order(self): self.str_recipient = input("Pay to: ") self.str_description = input("Description : ") self.str_amount = input("Amount: ") self.str_fee = input("Fee: ") def send_order(self): self.do_send() def print_banner(self): for i, x in enumerate(self.wallet.network.banner.split('\n')): print(x) def print_list(self, lst, firstline): lst = list(lst) self.maxpos = len(lst) if not self.maxpos: return print(firstline) for i in range(self.maxpos): msg = lst[i] if i < len(lst) else "" print(msg) def main(self): while self.done == 0: self.main_command() def do_send(self): if not is_address(self.str_recipient): print(_('Invalid Dash address')) return try: amount = int(Decimal(self.str_amount) * COIN) except Exception: print(_('Invalid Amount')) return try: fee = int(Decimal(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(outputs=[ PartialTxOutput.from_address_and_value(self.str_recipient, amount) ], password=password, fee=fee) except Exception as e: print(repr(e)) return if self.str_description: self.wallet.set_label(tx.txid(), self.str_description) print(_("Please wait...")) try: coro = self.wallet.psman.broadcast_transaction(tx) self.network.run_from_another_thread(coro) except TxBroadcastError as e: msg = e.get_message_for_gui() print(msg) except BestEffortRequestFailed as e: msg = repr(e) print(msg) else: print(_('Payment sent.')) #self.do_clear() #self.update_contacts_tab() def network_dialog(self): print( "use 'electrum-dash setconfig server/proxy' to change your network settings" ) return True def settings_dialog(self): print("use 'electrum-dash setconfig' to change your settings") return True def start_mixing(self): if self.wallet.has_password(): password = self.password_dialog() if not password: return else: password = None self.wallet.psman.start_mixing(password) return True def stop_mixing(self): self.wallet.psman.stop_mixing() def privatesend_log(self, cmd): try: cmd = cmd.lower() subcmds = cmd[1:].split() print_filtered = True if 'f' in subcmds else False print_tail = True if 'a' not in subcmds else False log_handler = self.wallet.psman.log_handler p_from = log_handler.tail - 20 if print_tail else log_handler.head p_from = max(p_from, log_handler.head) for i in range(p_from, log_handler.tail): log_line = '' log_record = log_handler.log.get(i, None) if log_record: created = time.localtime(log_record.created) created = time.strftime('%x %X', created) log_line = f'{created} {log_record.msg}' if print_filtered: log_line = filter_log_line(log_line) if log_record.subcat == PSLogSubCat.WflDone: log_line = f'{Fore.BLUE}{log_line}{Style.RESET_ALL}' elif log_record.subcat == PSLogSubCat.WflOk: log_line = f'{Fore.GREEN}{log_line}{Style.RESET_ALL}' elif log_record.subcat == PSLogSubCat.WflErr: log_line = f'{Fore.RED}{log_line}{Style.RESET_ALL}' print(log_line) except: import traceback traceback.print_exc() def password_dialog(self): return getpass.getpass() # XXX unused def run_receive_tab(self, c): #if c == 10: # out = self.run_popup('Address', ["Edit label", "Freeze", "Prioritize"]) return def run_contacts_tab(self, c): pass