def create_window_for_wallet(self, wallet): w = ElectrumWindow(self, wallet) self.windows.append(w) self.build_tray_menu() # FIXME: Remove in favour of the load_wallet hook run_hook('on_new_window', w) return w
def __init__(self, config, daemon, plugins): set_language(config.get('language')) # Uncomment this call to verify objects are being properly # GC-ed when windows are closed #network.add_jobs([DebugMem([Abstract_Wallet, SPV, Synchronizer, # ElectrumWindow], interval=5)]) QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_X11InitThreads) if hasattr(QtCore.Qt, "AA_ShareOpenGLContexts"): QtCore.QCoreApplication.setAttribute( QtCore.Qt.AA_ShareOpenGLContexts) if hasattr(QGuiApplication, 'setDesktopFileName'): QGuiApplication.setDesktopFileName('electrum-dash.desktop') self.config = config self.daemon = daemon self.plugins = plugins self.windows = [] self.efilter = OpenFileEventFilter(self.windows) self.app = QElectrumApplication(sys.argv) self.app.installEventFilter(self.efilter) self.app.setStyle('Fusion') self.app.setStyleSheet(dash_stylesheet) self.timer = Timer() self.nd = None self.network_updated_signal_obj = QNetworkUpdatedSignalObject() # init tray self.dark_icon = self.config.get("dark_icon", False) self.tray = QSystemTrayIcon(self.tray_icon(), None) self.tray.setToolTip('Electrum-DASH') self.tray.activated.connect(self.tray_activated) self.build_tray_menu() self.tray.show() self.app.new_window_signal.connect(self.start_new_window) run_hook('init_qt', self) ColorScheme.update_from_widget(QWidget())
def close_window(self, window): self.windows.remove(window) self.build_tray_menu() # save wallet path of last open window if not self.windows: self.config.save_last_wallet(window.wallet) run_hook('on_close_window', window)
def create_menu(self, position): menu = QMenu() selected = self.selectedItems() if not selected: menu.addAction(_("New contact"), lambda: self.parent.new_contact_dialog()) menu.addAction(_("Import file"), lambda: self.import_contacts()) else: names = [item.text(0) for item in selected] keys = [item.text(1) for item in selected] column = self.currentColumn() column_title = self.headerItem().text(column) column_data = '\n'.join([item.text(column) for item in selected]) menu.addAction( _("Copy %s") % column_title, lambda: self.parent.app.clipboard().setText(column_data)) if column in self.editable_columns: item = self.currentItem() menu.addAction( _("Edit %s") % column_title, lambda: self.editItem(item, column)) menu.addAction(_("Pay to"), lambda: self.parent.payto_contacts(keys)) menu.addAction(_("Delete"), lambda: self.parent.delete_contacts(keys)) URLs = [ block_explorer_URL(self.config, 'addr', key) for key in filter(is_address, keys) ] if URLs: menu.addAction(_("View on block explorer"), lambda: map(webbrowser.open, URLs)) run_hook('create_contact_menu', menu, selected) menu.exec_(self.viewport().mapToGlobal(position))
def create_quote_text(self, btc_balance): """Return a string copy of the amount fiat currency the user has in Dash.""" from electrum_dash.plugins import run_hook r = {} run_hook('get_fiat_balance_text', btc_balance, r) return r.get(0, '')
def __init__(self, config, daemon, plugins): set_language(config.get('language')) # Uncomment this call to verify objects are being properly # GC-ed when windows are closed #network.add_jobs([DebugMem([Abstract_Wallet, SPV, Synchronizer, # ElectrumWindow], interval=5)]) self.config = config self.daemon = daemon self.plugins = plugins self.windows = [] self.efilter = OpenFileEventFilter(self.windows) self.app = QApplication(sys.argv) self.app.installEventFilter(self.efilter) self.app.setStyleSheet(dash_stylesheet) self.timer = Timer() self.nd = None # init tray self.dark_icon = self.config.get("dark_icon", False) self.tray = QSystemTrayIcon(self.tray_icon(), None) self.tray.setToolTip('Electrum-QBC') self.tray.activated.connect(self.tray_activated) self.build_tray_menu() self.tray.show() self.app.connect(self.app, QtCore.SIGNAL('new_window'), self.start_new_window) run_hook('init_qt', self)
def create_menu(self, position): item = self.itemAt(position) if not item: return addr = str(item.text(1)) req = self.wallet.receive_requests.get(addr) if req is None: self.update() return column = self.currentColumn() column_title = self.headerItem().text(column) column_data = item.text(column) menu = QMenu(self) menu.addAction( _("Copy {}").format(column_title), lambda: self.parent.app.clipboard().setText(column_data)) menu.addAction( _("Copy URI"), lambda: self.parent.view_and_paste( 'URI', '', self.parent.get_request_URI(addr))) menu.addAction(_("Save as BIP70 file"), lambda: self.parent.export_payment_request(addr)) menu.addAction(_("Delete"), lambda: self.parent.delete_payment_request(addr)) run_hook('receive_list_menu', menu, addr) menu.exec_(self.viewport().mapToGlobal(position))
def __init__(self, text="", allow_multi=False): ButtonsTextEdit.__init__(self, text) self.allow_multi = allow_multi self.setReadOnly(0) self.addButton(":icons/file.png", self.file_input, _("Read file")) icon = ":icons/qrcode.png" self.addButton(icon, self.qr_input, _("Read QR code")) run_hook('scan_text_edit', self)
def create_quote_text(self, btc_balance): """Return a string copy of the amount fiat currency the user has in Dash.""" from electrum_dash.plugins import run_hook r = {} run_hook("get_fiat_balance_text", btc_balance, r) return r.get(0, "")
def load_wallet(self, wallet): self.wallet = wallet self.update_wallet() # Once GUI has been initialized check if we want to announce something # since the callback has been called before the GUI was initialized if self.receive_screen: self.receive_screen.clear() self.update_tabs() run_hook('load_wallet', wallet, self)
def on_update(self): item = self.currentItem() current_key = item.data(0, Qt.UserRole).toString() if item else None self.clear() for key in sorted(self.parent.contacts.keys()): _type, name = self.parent.contacts[key] item = QTreeWidgetItem([name, key]) item.setData(0, Qt.UserRole, key) self.addTopLevelItem(item) if key == current_key: self.setCurrentItem(item) run_hook('update_contacts_tab', self)
def update(self): desc = self.desc base_unit = self.main_window.base_unit() format_amount = self.main_window.format_amount tx_hash, status, label, can_broadcast, amount, fee, height, conf, timestamp, exp_n = self.wallet.get_tx_info( self.tx) size = self.tx.estimated_size() self.broadcast_button.setEnabled(can_broadcast) can_sign = not self.tx.is_complete() and \ (self.wallet.can_sign(self.tx) or bool(self.main_window.tx_external_keypairs)) self.sign_button.setEnabled(can_sign) self.tx_hash_e.setText(tx_hash or _('Unknown')) if desc is None: self.tx_desc.hide() else: self.tx_desc.setText(_("Description") + ': ' + desc) self.tx_desc.show() self.status_label.setText(_('Status:') + ' ' + status) if timestamp: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat( ' ')[:-3] self.date_label.setText(_("Date: {}").format(time_str)) self.date_label.show() elif exp_n: text = '%.2f MB' % (exp_n / 1000000) self.date_label.setText( _('Position in mempool: {} from tip').format(text)) self.date_label.show() else: self.date_label.hide() if amount is None: amount_str = _("Transaction unrelated to your wallet") elif amount > 0: amount_str = _("Amount received:" ) + ' %s' % format_amount(amount) + ' ' + base_unit else: amount_str = _("Amount sent:" ) + ' %s' % format_amount(-amount) + ' ' + base_unit size_str = _("Size:") + ' %d bytes' % size fee_str = _("Fee") + ': %s' % (format_amount(fee) + ' ' + base_unit if fee is not None else _('unknown')) if fee is not None: fee_rate = fee / size * 1000 fee_str += ' ( %s ) ' % self.main_window.format_fee_rate(fee_rate) confirm_rate = simple_config.FEERATE_WARNING_HIGH_FEE if fee_rate > confirm_rate: fee_str += ' - ' + _('Warning') + ': ' + _("high fee") + '!' self.amount_label.setText(amount_str) self.fee_label.setText(fee_str) self.size_label.setText(size_str) run_hook('transaction_dialog_update', self)
def __init__(self, parent, seed, passphrase): WindowModalDialog.__init__(self, parent, ('Electrum-DASH - ' + _('Seed'))) self.setMinimumWidth(400) vbox = QVBoxLayout(self) title = _("Your wallet generation seed is:") slayout = SeedLayout(title=title, seed=seed, msg=True, passphrase=passphrase) vbox.addLayout(slayout) run_hook('set_seed', seed, slayout.seed_e) vbox.addLayout(Buttons(CloseButton(self)))
def create_menu(self, position): from electrum_dash.wallet import Multisig_Wallet is_multisig = isinstance(self.wallet, Multisig_Wallet) can_delete = self.wallet.can_delete_address() selected = self.selectedItems() multi_select = len(selected) > 1 addrs = [item.text(1) for item in selected] if not addrs: return if not multi_select: item = self.itemAt(position) col = self.currentColumn() if not item: return addr = addrs[0] if not is_address(addr): item.setExpanded(not item.isExpanded()) return menu = QMenu() if not multi_select: column_title = self.headerItem().text(col) copy_text = item.text(col) menu.addAction(_("Copy {}").format(column_title), lambda: self.parent.app.clipboard().setText(copy_text)) menu.addAction(_('Details'), lambda: self.parent.show_address(addr)) if col in self.editable_columns: menu.addAction(_("Edit {}").format(column_title), lambda: self.editItem(item, col)) menu.addAction(_("Request payment"), lambda: self.parent.receive_at(addr)) if self.wallet.can_export(): menu.addAction(_("Private key"), lambda: self.parent.show_private_key(addr)) if not is_multisig and not self.wallet.is_watching_only(): menu.addAction(_("Sign/verify message"), lambda: self.parent.sign_verify_message(addr)) menu.addAction(_("Encrypt/decrypt message"), lambda: self.parent.encrypt_message(addr)) if can_delete: menu.addAction(_("Remove from wallet"), lambda: self.parent.remove_address(addr)) addr_URL = block_explorer_URL(self.config, 'addr', addr) if addr_URL: menu.addAction(_("View on block explorer"), lambda: webbrowser.open(addr_URL)) if not self.wallet.is_frozen(addr): menu.addAction(_("Freeze"), lambda: self.parent.set_frozen_state([addr], True)) else: menu.addAction(_("Unfreeze"), lambda: self.parent.set_frozen_state([addr], False)) coins = self.wallet.get_utxos(addrs) if coins: menu.addAction(_("Spend from"), lambda: self.parent.spend_coins(coins)) run_hook('receive_menu', menu, addrs, self.wallet) menu.exec_(self.viewport().mapToGlobal(position))
def __init__(self, parent=None, msg=None): msg = msg or _('Please enter your password') WindowModalDialog.__init__(self, parent, _("Enter Password")) self.pw = pw = QLineEdit() pw.setEchoMode(2) vbox = QVBoxLayout() vbox.addWidget(QLabel(msg)) grid = QGridLayout() grid.setSpacing(8) grid.addWidget(QLabel(_('Password')), 1, 0) grid.addWidget(pw, 1, 1) vbox.addLayout(grid) vbox.addLayout(Buttons(CancelButton(self), OkButton(self))) self.setLayout(vbox) run_hook('password_dialog', pw, grid, 1)
def update(self): desc = self.desc base_unit = self.main_window.base_unit() format_amount = self.main_window.format_amount tx_hash, status, label, can_broadcast, amount, fee, height, conf, timestamp, exp_n = self.wallet.get_tx_info( self.tx) size = self.tx.estimated_size() self.broadcast_button.setEnabled(can_broadcast) self.sign_button.setEnabled(self.wallet.can_sign(self.tx)) self.tx_hash_e.setText(tx_hash or _('Unknown')) if desc is None: self.tx_desc.hide() else: self.tx_desc.setText(_("Description") + ': ' + desc) self.tx_desc.show() self.status_label.setText(_('Status:') + ' ' + status) if timestamp: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat( ' ')[:-3] self.date_label.setText(_("Date: %s") % time_str) self.date_label.show() elif exp_n: text = '%d blocks' % (exp_n) if exp_n > 0 else _( 'unknown (low fee)') self.date_label.setText( _('Expected confirmation time') + ': ' + text) self.date_label.show() else: self.date_label.hide() if amount is None: amount_str = _("Transaction unrelated to your wallet") elif amount > 0: amount_str = _("Amount received:" ) + ' %s' % format_amount(amount) + ' ' + base_unit else: amount_str = _("Amount sent:" ) + ' %s' % format_amount(-amount) + ' ' + base_unit size_str = _("Size:") + ' %d bytes' % size fee_str = _("Fee") + ': %s' % (format_amount(fee) + ' ' + base_unit if fee is not None else _('unknown')) if fee is not None: fee_str += ' ( %s )' % (format_amount(fee * 1000 / size) + ' ' + base_unit + '/kB') self.amount_label.setText(amount_str) self.fee_label.setText(fee_str) self.size_label.setText(size_str) run_hook('transaction_dialog_update', self)
def _do_send(self, amount, message, outputs): # make unsigned transaction config = self.app.electrum_config coins = self.app.wallet.get_spendable_coins(None, config) try: tx = self.app.wallet.make_unsigned_transaction( coins, outputs, config, None) except NotEnoughFunds: self.app.show_error(_("Not enough funds")) return except Exception as e: traceback.print_exc(file=sys.stdout) self.app.show_error(str(e)) return fee = tx.get_fee() msg = [ _("Amount to be sent") + ": " + self.app.format_amount_and_units(amount), _("Mining fee") + ": " + self.app.format_amount_and_units(fee), ] x_fee = run_hook('get_tx_extra_fee', self.app.wallet, tx) if x_fee: x_fee_address, x_fee_amount = x_fee msg.append( _("Additional fees") + ": " + self.app.format_amount_and_units(x_fee_amount)) if fee >= config.get('confirm_fee', 10000): msg.append( _('Warning') + ': ' + _("The fee for this transaction seems unusually high.")) msg.append(_("Enter your PIN code to proceed")) self.app.protected('\n'.join(msg), self.send_tx, (tx, message))
def _sign_tx(self, tx, password, on_success, on_failure): try: self.wallet.sign_transaction(tx, password) except InvalidPassword: Clock.schedule_once(lambda dt: on_failure(_("Invalid PIN"))) return on_success = run_hook('tc_sign_wrapper', self.wallet, tx, on_success, on_failure) or on_success Clock.schedule_once(lambda dt: on_success(tx))
def on_start(self): ''' This is the start point of the kivy ui ''' import time Logger.info('Time to on_start: {} <<<<<<<<'.format(time.clock())) win = Window win.bind(size=self.on_size, on_keyboard=self.on_keyboard) win.bind(on_key_down=self.on_key_down) #win.softinput_mode = 'below_target' self.on_size(win, win.size) self.init_ui() crash_reporter.ExceptionHook(self) # init plugins run_hook('init_kivy', self) # fiat currency self.fiat_unit = self.fx.ccy if self.fx.is_enabled() else '' # default tab self.switch_to('history') # bind intent for dash: URI scheme if platform == 'android': from android import activity from jnius import autoclass PythonActivity = autoclass('org.kivy.android.PythonActivity') mactivity = PythonActivity.mActivity self.on_new_intent(mactivity.getIntent()) activity.bind(on_new_intent=self.on_new_intent) # connect callbacks if self.network: interests = [ 'updated', 'status', 'new_transaction', 'verified', 'interfaces' ] self.network.register_callback(self.on_network_event, interests) self.network.register_callback(self.on_fee, ['fee']) self.network.register_callback(self.on_quotes, ['on_quotes']) self.network.register_callback(self.on_history, ['on_history']) # load wallet self.load_wallet_by_name(self.electrum_config.get_wallet_path()) # URI passed in config uri = self.electrum_config.get('url') if uri: self.set_URI(uri)
def update(self, h): self.wallet = self.parent.wallet item = self.currentItem() current_tx = item.data(0, Qt.UserRole).toString() if item else None self.clear() for item in h: tx_hash, conf, value, timestamp, balance = item time_str = _("unknown") if conf is None and timestamp is None: continue # skip history in offline mode if conf > 0: time_str = format_time(timestamp) if conf == -1: time_str = 'unverified' icon = QIcon(":icons/unconfirmed.png") elif conf == 0: time_str = 'pending' icon = QIcon(":icons/unconfirmed.png") elif conf < 6: icon = QIcon(":icons/clock%d.png" % conf) else: icon = QIcon(":icons/confirmed.png") v_str = self.parent.format_amount(value, True, whitespaces=True) balance_str = self.parent.format_amount(balance, whitespaces=True) label, is_default_label = self.wallet.get_label(tx_hash) item = QTreeWidgetItem(['', time_str, label, v_str, balance_str]) item.setFont(2, QFont(MONOSPACE_FONT)) item.setFont(3, QFont(MONOSPACE_FONT)) item.setFont(4, QFont(MONOSPACE_FONT)) if value < 0: item.setForeground(3, QBrush(QColor("#BC1E1E"))) if tx_hash: item.setData(0, Qt.UserRole, tx_hash) if is_default_label: item.setForeground(2, QBrush(QColor('grey'))) item.setIcon(0, icon) self.insertTopLevelItem(0, item) if current_tx == tx_hash: self.setCurrentItem(item) run_hook('history_tab_update')
def update(self, h): self.wallet = self.parent.wallet item = self.currentItem() current_tx = item.data(0, Qt.UserRole).toString() if item else None self.clear() for item in h: tx_hash, conf, value, timestamp, balance = item time_str = _("unknown") if conf is None and timestamp is None: continue # skip history in offline mode if conf > 0: time_str = format_time(timestamp) if conf == -1: time_str = 'unverified' icon = QIcon(":icons/unconfirmed.png") elif conf == 0: time_str = 'pending' icon = QIcon(":icons/unconfirmed.png") elif conf < 6: icon = QIcon(":icons/clock%d.png"%conf) else: icon = QIcon(":icons/confirmed.png") v_str = self.parent.format_amount(value, True, whitespaces=True) balance_str = self.parent.format_amount(balance, whitespaces=True) label, is_default_label = self.wallet.get_label(tx_hash) item = QTreeWidgetItem( [ '', time_str, label, v_str, balance_str] ) item.setFont(2, QFont(MONOSPACE_FONT)) item.setFont(3, QFont(MONOSPACE_FONT)) item.setFont(4, QFont(MONOSPACE_FONT)) if value < 0: item.setForeground(3, QBrush(QColor("#BC1E1E"))) if tx_hash: item.setData(0, Qt.UserRole, tx_hash) if is_default_label: item.setForeground(2, QBrush(QColor('grey'))) item.setIcon(0, icon) self.insertTopLevelItem(0, item) if current_tx == tx_hash: self.setCurrentItem(item) run_hook('history_tab_update')
def get_max_amount(self): if run_hook('abort_send', self): return '' inputs = self.wallet.get_spendable_coins(None, self.electrum_config) if not inputs: return '' addr = str( self.send_screen.screen.address) or self.wallet.dummy_address() outputs = [(TYPE_ADDRESS, addr, '!')] try: tx = self.wallet.make_unsigned_transaction(inputs, outputs, self.electrum_config) except NoDynamicFeeEstimates as e: Clock.schedule_once( lambda dt, bound_e=e: self.show_error(str(bound_e))) return '' amount = tx.output_value() __, x_fee_amount = run_hook('get_tx_extra_fee', self.wallet, tx) or (None, 0) amount_after_all_fees = amount - x_fee_amount return format_satoshis_plain(amount_after_all_fees, self.decimal_point())
def __init__(self, text=None): ButtonsTextEdit.__init__(self, text) self.setReadOnly(1) self.addButton(":icons/qrcode.png", self.qr_show, _("Show as QR code")) run_hook('show_text_edit', self)
def __init__(self, text=""): ButtonsTextEdit.__init__(self, text) self.setReadOnly(0) self.addButton(":icons/file.png", self.file_input, _("Read file")) self.addButton(":icons/qrcode.png", self.qr_input, _("Read QR code")) run_hook('scan_text_edit', self)
def estimated_fee(self, tx): fee = Multisig_Wallet.estimated_fee(self, tx) x = run_hook('extra_fee', tx) if x: fee += x return fee
def main(self, url): last_wallet = self.config.get('gui_last_wallet') if last_wallet is not None and self.config.get('wallet_path') is None: if os.path.exists(last_wallet): self.config.cmdline_options['default_wallet_path'] = last_wallet try: storage = WalletStorage(self.config.get_wallet_path()) except BaseException as e: QMessageBox.warning(None, _('Warning'), str(e), _('OK')) self.config.set_key('gui_last_wallet', None) return if storage.file_exists: try: wallet = Wallet(storage) except BaseException as e: QMessageBox.warning(None, _('Warning'), str(e), _('OK')) return action = wallet.get_action() else: action = 'new' if action is not None: wallet = self.run_wizard(storage, action) if not wallet: return else: wallet.start_threads(self.network) # init tray self.dark_icon = self.config.get("dark_icon", False) icon = QIcon(":icons/electrum_dark_icon.png") if self.dark_icon else QIcon(':icons/electrum_light_icon.png') self.tray = QSystemTrayIcon(icon, None) self.tray.setToolTip('Electrum-DASH') self.tray.activated.connect(self.tray_activated) self.build_tray_menu() self.tray.show() # main window self.main_window = w = ElectrumWindow(self.config, self.network, self) self.current_window = self.main_window #lite window self.init_lite() # plugins interact with main window run_hook('init_qt', self) w.load_wallet(wallet) # initial configuration if self.config.get('hide_gui') is True and self.tray.isVisible(): self.main_window.hide() self.lite_window.hide() else: if self.config.get('lite_mode') is True: self.go_lite() else: self.go_full() s = Timer() s.start() self.windows.append(w) if url: self.set_url(url) w.connect_slots(s) signal.signal(signal.SIGINT, lambda *args: self.app.quit()) self.app.exec_() if self.tray: self.tray.hide() # clipboard persistence # see http://www.mail-archive.com/[email protected]/msg17328.html event = QtCore.QEvent(QtCore.QEvent.Clipboard) self.app.sendEvent(self.app.clipboard(), event) w.close_wallet()
def __init__(self, tx, parent, desc, prompt_if_unsaved): '''Transactions in the wallet will show their description. Pass desc to give a description for txs not yet in the wallet. ''' # We want to be a top-level window QDialog.__init__(self, parent=None) # Take a copy; it might get updated in the main window by # e.g. the FX plugin. If this happens during or after a long # sign operation the signatures are lost. self.tx = copy.deepcopy(tx) self.tx.deserialize() self.main_window = parent self.wallet = parent.wallet self.prompt_if_unsaved = prompt_if_unsaved self.saved = False self.desc = desc self.setMinimumWidth(750) self.setWindowTitle(_("Transaction")) vbox = QVBoxLayout() self.setLayout(vbox) vbox.addWidget(QLabel(_("Transaction ID:"))) self.tx_hash_e = ButtonsLineEdit() qr_show = lambda: parent.show_qrcode( str(self.tx_hash_e.text()), 'Transaction ID', parent=self) self.tx_hash_e.addButton(":icons/qrcode.png", qr_show, _("Show as QR code")) self.tx_hash_e.setReadOnly(True) vbox.addWidget(self.tx_hash_e) self.tx_desc = QLabel() vbox.addWidget(self.tx_desc) self.status_label = QLabel() vbox.addWidget(self.status_label) self.date_label = QLabel() vbox.addWidget(self.date_label) self.amount_label = QLabel() vbox.addWidget(self.amount_label) self.size_label = QLabel() vbox.addWidget(self.size_label) self.fee_label = QLabel() vbox.addWidget(self.fee_label) self.add_io(vbox) vbox.addStretch(1) self.sign_button = b = QPushButton(_("Sign")) b.clicked.connect(self.sign) self.broadcast_button = b = QPushButton(_("Broadcast")) b.clicked.connect(self.do_broadcast) self.save_button = b = QPushButton(_("Save")) b.clicked.connect(self.save) self.cancel_button = b = QPushButton(_("Close")) b.clicked.connect(self.close) b.setDefault(True) self.qr_button = b = QPushButton() b.setIcon(QIcon(":icons/qrcode.png")) b.clicked.connect(self.show_qr) self.copy_button = CopyButton(lambda: str(self.tx), parent.app) # Action buttons self.buttons = [ self.sign_button, self.broadcast_button, self.cancel_button ] # Transaction sharing buttons self.sharing_buttons = [ self.copy_button, self.qr_button, self.save_button ] run_hook('transaction_dialog', self) hbox = QHBoxLayout() hbox.addLayout(Buttons(*self.sharing_buttons)) hbox.addStretch(1) hbox.addLayout(Buttons(*self.buttons)) vbox.addLayout(hbox) self.update()
def main(self, url): last_wallet = self.config.get('gui_last_wallet') if last_wallet is not None and self.config.get('wallet_path') is None: if os.path.exists(last_wallet): self.config.cmdline_options[ 'default_wallet_path'] = last_wallet try: storage = WalletStorage(self.config.get_wallet_path()) except BaseException as e: QMessageBox.warning(None, _('Warning'), str(e), _('OK')) self.config.set_key('gui_last_wallet', None) return if storage.file_exists: try: wallet = Wallet(storage) except BaseException as e: QMessageBox.warning(None, _('Warning'), str(e), _('OK')) return action = wallet.get_action() else: action = 'new' if action is not None: wallet = self.run_wizard(storage, action) if not wallet: return else: wallet.start_threads(self.network) # init tray self.dark_icon = self.config.get("dark_icon", False) icon = QIcon( ":icons/electrum_dark_icon.png") if self.dark_icon else QIcon( ':icons/electrum_light_icon.png') self.tray = QSystemTrayIcon(icon, None) self.tray.setToolTip('Electrum-DASH') self.tray.activated.connect(self.tray_activated) self.build_tray_menu() self.tray.show() # main window self.main_window = w = ElectrumWindow(self.config, self.network, self) self.current_window = self.main_window #lite window self.init_lite() # plugins interact with main window run_hook('init_qt', self) w.load_wallet(wallet) # initial configuration if self.config.get('hide_gui') is True and self.tray.isVisible(): self.main_window.hide() self.lite_window.hide() else: if self.config.get('lite_mode') is True: self.go_lite() else: self.go_full() s = Timer() s.start() self.windows.append(w) if url: self.set_url(url) w.connect_slots(s) signal.signal(signal.SIGINT, lambda *args: self.app.quit()) self.app.exec_() if self.tray: self.tray.hide() # clipboard persistence # see http://www.mail-archive.com/[email protected]/msg17328.html event = QtCore.QEvent(QtCore.QEvent.Clipboard) self.app.sendEvent(self.app.clipboard(), event) w.close_wallet()
def update(self): is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(self.tx) tx_hash = self.tx.hash() desc = self.desc time_str = None self.broadcast_button.hide() if self.tx.is_complete(): status = _("Signed") if tx_hash in self.wallet.transactions.keys(): desc, is_default = self.wallet.get_label(tx_hash) conf, timestamp = self.wallet.get_confirmations(tx_hash) if timestamp: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] else: time_str = _('Pending') status = _("%d confirmations")%conf else: self.broadcast_button.show() # cannot broadcast when offline if self.parent.network is None: self.broadcast_button.setEnabled(False) else: s, r = self.tx.signature_count() status = _("Unsigned") if s == 0 else _('Partially signed') + ' (%d/%d)'%(s,r) tx_hash = _('Unknown'); if self.wallet.can_sign(self.tx): self.sign_button.show() else: self.sign_button.hide() self.tx_hash_e.setText(tx_hash) if desc is None: self.tx_desc.hide() else: self.tx_desc.setText(_("Description") + ': ' + desc) self.tx_desc.show() self.status_label.setText(_('Status:') + ' ' + status) if time_str is not None: self.date_label.setText(_("Date: %s")%time_str) self.date_label.show() else: self.date_label.hide() # if we are not synchronized, we cannot tell if not self.wallet.up_to_date: return if is_relevant: if is_mine: if fee is not None: self.amount_label.setText(_("Amount sent:")+' %s'% self.parent.format_amount(-v+fee) + ' ' + self.parent.base_unit()) self.fee_label.setText(_("Transaction fee")+': %s'% self.parent.format_amount(-fee) + ' ' + self.parent.base_unit()) else: self.amount_label.setText(_("Amount sent:")+' %s'% self.parent.format_amount(-v) + ' ' + self.parent.base_unit()) self.fee_label.setText(_("Transaction fee")+': '+ _("unknown")) else: self.amount_label.setText(_("Amount received:")+' %s'% self.parent.format_amount(v) + ' ' + self.parent.base_unit()) else: self.amount_label.setText(_("Transaction unrelated to your wallet")) run_hook('transaction_dialog_update', self)
def __init__(self, tx, parent, desc, prompt_if_unsaved): '''Transactions in the wallet will show their description. Pass desc to give a description for txs not yet in the wallet. ''' self.tx = tx self.tx.deserialize() self.parent = parent self.wallet = parent.wallet self.prompt_if_unsaved = prompt_if_unsaved self.saved = False self.broadcast = False self.desc = desc QDialog.__init__(self) self.setMinimumWidth(600) self.setWindowTitle(_("Transaction")) vbox = QVBoxLayout() self.setLayout(vbox) vbox.addWidget(QLabel(_("Transaction ID:"))) self.tx_hash_e = ButtonsLineEdit() qr_show = lambda: self.parent.show_qrcode(str(self.tx_hash_e.text()), 'Transaction ID') self.tx_hash_e.addButton(":icons/qrcode.png", qr_show, _("Show as QR code")) self.tx_hash_e.setReadOnly(True) vbox.addWidget(self.tx_hash_e) self.status_label = QLabel() vbox.addWidget(self.status_label) self.tx_desc = QLabel() vbox.addWidget(self.tx_desc) self.date_label = QLabel() vbox.addWidget(self.date_label) self.amount_label = QLabel() vbox.addWidget(self.amount_label) self.fee_label = QLabel() vbox.addWidget(self.fee_label) self.add_io(vbox) vbox.addStretch(1) self.sign_button = b = QPushButton(_("Sign")) b.clicked.connect(self.sign) self.broadcast_button = b = QPushButton(_("Broadcast")) b.clicked.connect(self.do_broadcast) self.save_button = b = QPushButton(_("Save")) b.clicked.connect(self.save) self.cancel_button = b = QPushButton(_("Close")) b.clicked.connect(self.close) b.setDefault(True) self.qr_button = b = QPushButton() b.setIcon(QIcon(":icons/qrcode.png")) b.clicked.connect(self.show_qr) self.copy_button = CopyButton(lambda: str(self.tx), self.parent.app) # Action buttons self.buttons = [ self.sign_button, self.broadcast_button, self.cancel_button ] # Transaction sharing buttons self.sharing_buttons = [ self.copy_button, self.qr_button, self.save_button ] run_hook('transaction_dialog', self) hbox = QHBoxLayout() hbox.addLayout(Buttons(*self.sharing_buttons)) hbox.addStretch(1) hbox.addLayout(Buttons(*self.buttons)) vbox.addLayout(hbox) self.update()
def __init__(self, tx, parent, desc, prompt_if_unsaved): '''Transactions in the wallet will show their description. Pass desc to give a description for txs not yet in the wallet. ''' self.tx = tx self.tx.deserialize() self.parent = parent self.wallet = parent.wallet self.prompt_if_unsaved = prompt_if_unsaved self.saved = False self.broadcast = False self.desc = desc QDialog.__init__(self) self.setMinimumWidth(600) self.setWindowTitle(_("Transaction")) vbox = QVBoxLayout() self.setLayout(vbox) vbox.addWidget(QLabel(_("Transaction ID:"))) self.tx_hash_e = ButtonsLineEdit() qr_show = lambda: self.parent.show_qrcode(str(self.tx_hash_e.text()), 'Transaction ID') self.tx_hash_e.addButton(":icons/qrcode.png", qr_show, _("Show as QR code")) self.tx_hash_e.setReadOnly(True) vbox.addWidget(self.tx_hash_e) self.status_label = QLabel() vbox.addWidget(self.status_label) self.tx_desc = QLabel() vbox.addWidget(self.tx_desc) self.date_label = QLabel() vbox.addWidget(self.date_label) self.amount_label = QLabel() vbox.addWidget(self.amount_label) self.fee_label = QLabel() vbox.addWidget(self.fee_label) self.add_io(vbox) vbox.addStretch(1) self.sign_button = b = QPushButton(_("Sign")) b.clicked.connect(self.sign) self.broadcast_button = b = QPushButton(_("Broadcast")) b.clicked.connect(self.do_broadcast) self.save_button = b = QPushButton(_("Save")) b.clicked.connect(self.save) self.cancel_button = b = QPushButton(_("Close")) b.clicked.connect(self.close) b.setDefault(True) self.qr_button = b = QPushButton() b.setIcon(QIcon(":icons/qrcode.png")) b.clicked.connect(self.show_qr) self.copy_button = CopyButton(lambda: str(self.tx), self.parent.app) # Action buttons self.buttons = [self.sign_button, self.broadcast_button, self.cancel_button] # Transaction sharing buttons self.sharing_buttons = [self.copy_button, self.qr_button, self.save_button] run_hook('transaction_dialog', self) hbox = QHBoxLayout() hbox.addLayout(Buttons(*self.sharing_buttons)) hbox.addStretch(1) hbox.addLayout(Buttons(*self.buttons)) vbox.addLayout(hbox) self.update()
def __init__(self, tx, parent, desc, prompt_if_unsaved): '''Transactions in the wallet will show their description. Pass desc to give a description for txs not yet in the wallet. ''' # We want to be a top-level window QDialog.__init__(self, parent=None) # Take a copy; it might get updated in the main window by # e.g. the FX plugin. If this happens during or after a long # sign operation the signatures are lost. self.tx = tx = copy.deepcopy(tx) try: self.tx.deserialize() except BaseException as e: raise SerializationError(e) self.main_window = parent self.wallet = parent.wallet self.prompt_if_unsaved = prompt_if_unsaved self.saved = False self.desc = desc # if the wallet can populate the inputs with more info, do it now. # as a result, e.g. we might learn an imported address tx is segwit, # in which case it's ok to display txid self.wallet.add_input_info_to_all_inputs(tx) self.setMinimumWidth(950) self.setWindowTitle(_("Transaction")) vbox = QVBoxLayout() self.setLayout(vbox) vbox.addWidget(QLabel(_("Transaction ID:"))) self.tx_hash_e = ButtonsLineEdit() qr_show = lambda: parent.show_qrcode( str(self.tx_hash_e.text()), 'Transaction ID', parent=self) self.tx_hash_e.addButton(":icons/qrcode.png", qr_show, _("Show as QR code")) self.tx_hash_e.setReadOnly(True) vbox.addWidget(self.tx_hash_e) self.tx_desc = QLabel() vbox.addWidget(self.tx_desc) self.status_label = QLabel() vbox.addWidget(self.status_label) self.date_label = QLabel() vbox.addWidget(self.date_label) self.amount_label = QLabel() vbox.addWidget(self.amount_label) self.size_label = QLabel() vbox.addWidget(self.size_label) self.fee_label = QLabel() vbox.addWidget(self.fee_label) self.add_io(vbox) vbox.addStretch(1) self.sign_button = b = QPushButton(_("Sign")) b.clicked.connect(self.sign) self.broadcast_button = b = QPushButton(_("Broadcast")) b.clicked.connect(self.do_broadcast) self.save_button = b = QPushButton(_("Save")) save_button_disabled = not tx.is_complete() b.setDisabled(save_button_disabled) if save_button_disabled: b.setToolTip(SAVE_BUTTON_DISABLED_TOOLTIP) else: b.setToolTip(SAVE_BUTTON_ENABLED_TOOLTIP) b.clicked.connect(self.save) self.export_button = b = QPushButton(_("Export")) b.clicked.connect(self.export) self.cancel_button = b = QPushButton(_("Close")) b.clicked.connect(self.close) b.setDefault(True) self.qr_button = b = QPushButton() b.setIcon(QIcon(":icons/qrcode.png")) b.clicked.connect(self.show_qr) self.copy_button = CopyButton(lambda: str(self.tx), parent.app) # Action buttons self.buttons = [ self.sign_button, self.broadcast_button, self.cancel_button ] # Transaction sharing buttons self.sharing_buttons = [ self.copy_button, self.qr_button, self.export_button, self.save_button ] run_hook('transaction_dialog', self) hbox = QHBoxLayout() hbox.addLayout(Buttons(*self.sharing_buttons)) hbox.addStretch(1) hbox.addLayout(Buttons(*self.buttons)) vbox.addLayout(hbox) self.update()
def get_tx_fee(self, tx): fee = Multisig_Wallet.get_tx_fee(self, tx) x = run_hook('extra_fee', tx) if x: fee += x return fee
def update(self): is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(self.tx) tx_hash = self.tx.hash() desc = self.desc time_str = None self.broadcast_button.hide() if self.tx.is_complete(): status = _("Signed") if tx_hash in self.wallet.transactions.keys(): desc, is_default = self.wallet.get_label(tx_hash) conf, timestamp = self.wallet.get_confirmations(tx_hash) if timestamp: time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3] else: time_str = _('Pending') status = _("%d confirmations") % conf else: self.broadcast_button.show() # cannot broadcast when offline if self.parent.network is None: self.broadcast_button.setEnabled(False) else: s, r = self.tx.signature_count() status = _("Unsigned") if s == 0 else _( 'Partially signed') + ' (%d/%d)' % (s, r) tx_hash = _('Unknown') if self.wallet.can_sign(self.tx): self.sign_button.show() else: self.sign_button.hide() self.tx_hash_e.setText(tx_hash) if desc is None: self.tx_desc.hide() else: self.tx_desc.setText(_("Description") + ': ' + desc) self.tx_desc.show() self.status_label.setText(_('Status:') + ' ' + status) if time_str is not None: self.date_label.setText(_("Date: %s") % time_str) self.date_label.show() else: self.date_label.hide() # if we are not synchronized, we cannot tell if not self.wallet.up_to_date: return if is_relevant: if is_mine: if fee is not None: self.amount_label.setText( _("Amount sent:") + ' %s' % self.parent.format_amount(-v + fee) + ' ' + self.parent.base_unit()) self.fee_label.setText( _("Transaction fee") + ': %s' % self.parent.format_amount(-fee) + ' ' + self.parent.base_unit()) else: self.amount_label.setText( _("Amount sent:") + ' %s' % self.parent.format_amount(-v) + ' ' + self.parent.base_unit()) self.fee_label.setText( _("Transaction fee") + ': ' + _("unknown")) else: self.amount_label.setText( _("Amount received:") + ' %s' % self.parent.format_amount(v) + ' ' + self.parent.base_unit()) else: self.amount_label.setText( _("Transaction unrelated to your wallet")) run_hook('transaction_dialog_update', self)