def do_full_pull(self, force=False): try: connection = httplib.HTTPConnection(self.target_host) connection.request("GET", ("/api/wallets/%s/labels.json?auth_token=%s" % (self.wallet_id, self.auth_token())), "", {'Content-Type': 'application/json'}) response = connection.getresponse() if response.reason == httplib.responses[httplib.NOT_FOUND]: return try: response = json.loads(response.read()) except ValueError as e: return False if "error" in response: QMessageBox.warning( None, _("Error"), _("Could not sync labels: %s" % response["error"])) return False for label in response: decoded_key = self.decode(label["external_id"]) decoded_label = self.decode(label["text"]) if force or not self.labels.get(decoded_key): self.labels[decoded_key] = decoded_label return True except socket.gaierror as e: print_error('Error connecting to service: %s ' % e) return False
def do_full_push(self): try: bundle = {"labels": {}} for key, value in self.labels.iteritems(): encoded = self.encode(key) bundle["labels"][encoded] = self.encode(value) params = json.dumps(bundle) connection = httplib.HTTPConnection(self.target_host) connection.request( "POST", ("/api/wallets/%s/labels/batch.json?auth_token=%s" % (self.wallet_id, self.auth_token())), params, {'Content-Type': 'application/json'}) response = connection.getresponse() if response.reason == httplib.responses[httplib.NOT_FOUND]: return try: response = json.loads(response.read()) except ValueError as e: return False if "error" in response: QMessageBox.warning( None, _("Error"), _("Could not sync labels: %s" % response["error"])) return False return True except socket.gaierror as e: print_error('Error connecting to service: %s ' % e) return False
def __init__(self, gui): self.target_host = 'labelectrum.herokuapp.com' BasePlugin.__init__( self, gui, 'labels', _('Label Sync'), _('This plugin can sync your labels accross multiple Electrum installs by using a remote database to save your data. Labels, \ transactions and addresses are all sent and stored encrypted on the remote server. This code might increase the load of your wallet with a few microseconds as it will sync labels on each startup.\n\n\ To get started visit http://labelectrum.herokuapp.com/ to sign up for an account.' )) self.wallet = gui.wallet self.gui = gui self.config = gui.config self.labels = self.wallet.labels self.transactions = self.wallet.transactions self.encode_password = hashlib.sha1( self.config.get("master_public_key")).digest().encode('hex')[:32] self.wallet_id = hashlib.sha256( str(self.config.get("master_public_key"))).digest().encode('hex') addresses = [] for k, account in self.wallet.accounts.items(): for address in account[0]: addresses.append(address) self.addresses = addresses
def do_full_push(self): bundle = {"labels": {}} for key, value in self.labels.iteritems(): encoded = self.encode(key) bundle["labels"][encoded] = self.encode(value) params = json.dumps(bundle) connection = httplib.HTTPConnection(self.target_host) connection.request( "POST", ("/api/wallets/%s/labels/batch.json?auth_token=%s" % (self.wallet_id, self.auth_token())), params, {"Content-Type": "application/json"}, ) response = connection.getresponse() if response.reason == httplib.responses[httplib.NOT_FOUND]: return try: response = json.loads(response.read()) except ValueError as e: return False if "error" in response: QMessageBox.warning(None, _("Error"), _("Could not sync labels: %s" % response["error"])) return False return True
def __init__(self, gui): self.target_host = "labelectrum.herokuapp.com" BasePlugin.__init__( self, gui, "labels", _("Label Sync"), _( "This plugin can sync your labels accross multiple Electrum installs by using a remote database to save your data. Labels are not encrypted, \ transactions and addresses are however. This code might increase the load of your wallet with a few micoseconds as it will sync labels on each startup.\n\n\ To get started visit http://labelectrum.herokuapp.com/ to sign up for an account." ), ) self.wallet = gui.wallet self.gui = gui self.config = gui.config self.labels = self.wallet.labels self.transactions = self.wallet.transactions self.encode_password = hashlib.sha1(self.config.get("master_public_key")).digest().encode("hex")[:32] self.wallet_id = hashlib.sha256(str(self.config.get("master_public_key"))).digest().encode("hex") addresses = [] for k, account in self.wallet.accounts.items(): for address in account[0]: addresses.append(address) self.addresses = addresses
def delete_alias(self, x): if self.gui.question(_("Do you want to remove")+" %s "%x +_("from your list of contacts?")): if x in self.aliases: self.aliases.pop(x) self.update_history_tab() self.update_contacts_tab() self.update_completions()
def create_contact_menu(self, menu, item): label = unicode(item.text(1)) if label in self.aliases.keys(): addr = unicode(item.text(0)) label = unicode(item.text(1)) menu.addAction(_("View alias details"), lambda: self.show_contact_details(label)) menu.addAction(_("Delete alias"), lambda: delete_alias(self, label))
def do_full_pull(self, force=False): connection = httplib.HTTPConnection(self.target_host) connection.request( "GET", ("/api/wallets/%s/labels.json?auth_token=%s" % (self.wallet_id, self.auth_token())), "", {"Content-Type": "application/json"}, ) response = connection.getresponse() if response.reason == httplib.responses[httplib.NOT_FOUND]: return try: response = json.loads(response.read()) except ValueError as e: return False if "error" in response: QMessageBox.warning(None, _("Error"), _("Could not sync labels: %s" % response["error"])) return False for label in response: decoded_key = self.decode(label["external_id"]) decoded_label = self.decode(label["text"]) if force or not self.labels.get(decoded_key): self.labels[decoded_key] = decoded_label return True
def show_tx_qrcode(self, data, title): if not data: return d = QDialog(self.gui) d.setModal(1) d.setWindowTitle(title) d.setMinimumSize(250, 525) vbox = QVBoxLayout() qrw = QRCodeWidget(data) vbox.addWidget(qrw, 0) hbox = QHBoxLayout() hbox.addStretch(1) def print_qr(self): filename = "qrcode.bmp" electrum_gui.bmp.save_qrcode(qrw.qr, filename) QMessageBox.information(None, _('Message'), _("QR code saved to file") + " " + filename, _('OK')) b = QPushButton(_("Save")) hbox.addWidget(b) b.clicked.connect(print_qr) b = QPushButton(_("Close")) hbox.addWidget(b) b.clicked.connect(d.accept) b.setDefault(True) vbox.addLayout(hbox, 1) d.setLayout(vbox) d.exec_()
def show_tx_qrcode(self, data, title): if not data: return d = QDialog(self.gui) d.setModal(1) d.setWindowTitle(title) d.setMinimumSize(250, 525) vbox = QVBoxLayout() qrw = QRCodeWidget(data) vbox.addWidget(qrw, 0) hbox = QHBoxLayout() hbox.addStretch(1) def print_qr(self): filename = "qrcode.bmp" electrum_gui.bmp.save_qrcode(qrw.qr, filename) QMessageBox.information( None, _('Message'), _("QR code saved to file") + " " + filename, _('OK')) b = QPushButton(_("Save")) hbox.addWidget(b) b.clicked.connect(print_qr) b = QPushButton(_("Close")) hbox.addWidget(b) b.clicked.connect(d.accept) b.setDefault(True) vbox.addLayout(hbox, 1) d.setLayout(vbox) d.exec_()
def full_pull(self, force=False): if self.do_full_pull(force) and force: QMessageBox.information(None, _("Labels synchronized"), _("Your labels have been synchronized.")) self.gui.update_history_tab() self.gui.update_completions() self.gui.update_receive_tab() self.gui.update_contacts_tab()
def __init__(self, gui): BasePlugin.__init__( self, gui, 'virtualkeyboard', 'Virtual Keyboard', '%s\n%s' % (_("Add an optional, mouse keyboard to the password dialog."), _("Warning: do not use this if it makes you pick a weaker password." ))) self.vkb = None self.vkb_index = 0
def show_contact_details(self, m): a = self.aliases.get(m) if a: if a[0] in self.authorities.keys(): s = self.authorities.get(a[0]) else: s = "self-signed" msg = _('Alias:')+' '+ m + '\n'+_('Target address:')+' '+ a[1] + '\n\n'+_('Signed by:')+' ' + s + '\n'+_('Signing address:')+' ' + a[0] QMessageBox.information(self.gui, 'Alias', msg, 'OK')
def settings_dialog(self): def check_for_api_key(api_key): if api_key and len(api_key) > 12: self.config.set_key("plugin_label_api_key", str(self.auth_token_edit.text())) self.upload.setEnabled(True) self.download.setEnabled(True) self.accept.setEnabled(True) else: self.upload.setEnabled(False) self.download.setEnabled(False) self.accept.setEnabled(False) d = QDialog(self.gui) layout = QGridLayout(d) layout.addWidget(QLabel("API Key: "), 0, 0) self.auth_token_edit = QLineEdit(self.auth_token()) self.auth_token_edit.textChanged.connect(check_for_api_key) layout.addWidget(QLabel("Label sync options: "), 2, 0) layout.addWidget(self.auth_token_edit, 0, 1, 1, 2) decrypt_key_text = QLineEdit(self.encode_password) decrypt_key_text.setReadOnly(True) layout.addWidget(decrypt_key_text, 1, 1) layout.addWidget(QLabel("Decryption key: "), 1, 0) layout.addWidget( HelpButton( "This key can be used on the LabElectrum website to decrypt your data in case you want to review it online." ), 1, 2, ) self.upload = QPushButton("Force upload") self.upload.clicked.connect(self.full_push) layout.addWidget(self.upload, 2, 1) self.download = QPushButton("Force download") self.download.clicked.connect(lambda: self.full_pull(True)) layout.addWidget(self.download, 2, 2) c = QPushButton(_("Cancel")) c.clicked.connect(d.reject) self.accept = QPushButton(_("Done")) self.accept.clicked.connect(d.accept) layout.addWidget(c, 3, 1) layout.addWidget(self.accept, 3, 2) check_for_api_key(self.auth_token()) if d.exec_(): return True else: return False
def show_raw_qr(self): r = unicode(self.gui.payto_e.text()) r = r.strip() # label or alias, with address in brackets m = re.match('(.*?)\s*\<([1-9A-HJ-NP-Za-km-z]{26,})\>', r) to_address = m.group(2) if m else r if not is_valid(to_address): QMessageBox.warning( self.gui, _('Error'), _('Invalid Bitcoin Address') + ':\n' + to_address, _('OK')) return try: amount = self.gui.read_amount(unicode(self.gui.amount_e.text())) except: QMessageBox.warning(self.gui, _('Error'), _('Invalid Amount'), _('OK')) return try: fee = self.gui.read_amount(unicode(self.gui.fee_e.text())) except: QMessageBox.warning(self.gui, _('Error'), _('Invalid Fee'), _('OK')) return try: tx = self.gui.wallet.mktx([(to_address, amount)], None, fee, account=self.gui.current_account) except BaseException, e: self.gui.show_message(str(e)) return
def settings_dialog(self): def check_for_api_key(api_key): if api_key and len(api_key) > 12: self.config.set_key("plugin_label_api_key", str(self.auth_token_edit.text())) self.upload.setEnabled(True) self.download.setEnabled(True) self.accept.setEnabled(True) else: self.upload.setEnabled(False) self.download.setEnabled(False) self.accept.setEnabled(False) d = QDialog(self.gui) layout = QGridLayout(d) layout.addWidget(QLabel("API Key: "), 0, 0) self.auth_token_edit = QLineEdit(self.auth_token()) self.auth_token_edit.textChanged.connect(check_for_api_key) layout.addWidget(QLabel("Label sync options: "), 2, 0) layout.addWidget(self.auth_token_edit, 0, 1, 1, 2) decrypt_key_text = QLineEdit(self.encode_password) decrypt_key_text.setReadOnly(True) layout.addWidget(decrypt_key_text, 1, 1) layout.addWidget(QLabel("Decryption key: "), 1, 0) layout.addWidget( HelpButton( "This key can be used on the LabElectrum website to decrypt your data in case you want to review it online." ), 1, 2) self.upload = QPushButton("Force upload") self.upload.clicked.connect(self.full_push) layout.addWidget(self.upload, 2, 1) self.download = QPushButton("Force download") self.download.clicked.connect(lambda: self.full_pull(True)) layout.addWidget(self.download, 2, 2) c = QPushButton(_("Cancel")) c.clicked.connect(d.reject) self.accept = QPushButton(_("Done")) self.accept.clicked.connect(d.accept) layout.addWidget(c, 3, 1) layout.addWidget(self.accept, 3, 2) check_for_api_key(self.auth_token()) if d.exec_(): return True else: return False
def create_send_tab(self, grid): b = QPushButton(_("Scan QR code")) b.clicked.connect(self.fill_from_qr) grid.addWidget(b, 1, 5) b2 = QPushButton(_("Scan TxQR")) b2.clicked.connect(self.read_raw_qr) if not self.gui.wallet.seed: b3 = QPushButton(_("Show unsigned TxQR")) b3.clicked.connect(self.show_raw_qr) grid.addWidget(b3, 7, 1) grid.addWidget(b2, 7, 2) else: grid.addWidget(b2, 7, 1)
def show_raw_qr(self): r = unicode( self.gui.payto_e.text() ) r = r.strip() # label or alias, with address in brackets m = re.match('(.*?)\s*\<([1-9A-HJ-NP-Za-km-z]{26,})\>', r) to_address = m.group(2) if m else r if not is_valid(to_address): QMessageBox.warning(self.gui, _('Error'), _('Invalid Bitcoin Address') + ':\n' + to_address, _('OK')) return try: amount = self.gui.read_amount(unicode( self.gui.amount_e.text())) except: QMessageBox.warning(self.gui, _('Error'), _('Invalid Amount'), _('OK')) return try: fee = self.gui.read_amount(unicode( self.gui.fee_e.text())) except: QMessageBox.warning(self.gui, _('Error'), _('Invalid Fee'), _('OK')) return try: tx = self.gui.wallet.mktx( [(to_address, amount)], None, fee, account=self.gui.current_account) except BaseException, e: self.gui.show_message(str(e)) return
def __init__(self, gui): BasePlugin.__init__( self, gui, "virtualkeyboard", "Virtual Keyboard", "%s\n%s" % ( _("Add an optional, mouse keyboard to the password dialog."), _("Warning: do not use this if it makes you pick a weaker password."), ), ) self.vkb = None self.vkb_index = 0
def __init__(self, exchanger): QWidget.__init__(self) self.exchanger = exchanger self.setWindowTitle('Electrum - ' + _('Invoice')) self.setMinimumSize(800, 250) self.address = '' self.label = '' self.amount = 0 self.setFocusPolicy(QtCore.Qt.NoFocus) main_box = QHBoxLayout() self.qrw = QRCodeWidget() main_box.addWidget(self.qrw, 1) vbox = QVBoxLayout() main_box.addLayout(vbox) self.address_label = QLabel("") #self.address_label.setFont(QFont(MONOSPACE_FONT)) vbox.addWidget(self.address_label) self.label_label = QLabel("") vbox.addWidget(self.label_label) self.amount_label = QLabel("") vbox.addWidget(self.amount_label) vbox.addStretch(1) self.setLayout(main_box)
def __init__(self, exchanger): QWidget.__init__(self) self.exchanger = exchanger self.setWindowTitle('Electrum - '+_('Invoice')) self.setMinimumSize(800, 250) self.address = '' self.label = '' self.amount = 0 self.setFocusPolicy(QtCore.Qt.NoFocus) main_box = QHBoxLayout() self.qrw = QRCodeWidget() main_box.addWidget(self.qrw, 1) vbox = QVBoxLayout() main_box.addLayout(vbox) self.address_label = QLabel("") #self.address_label.setFont(QFont(MONOSPACE_FONT)) vbox.addWidget(self.address_label) self.label_label = QLabel("") vbox.addWidget(self.label_label) self.amount_label = QLabel("") vbox.addWidget(self.amount_label) vbox.addStretch(1) self.setLayout(main_box)
def __init__(self, gui): BasePlugin.__init__( self, gui, 'pointofsale', 'Point of Sale', _('Show QR code window and amounts requested for each address. Add menu item to request amount.' )) self.qr_window = None self.requested_amounts = self.config.get('requested_amounts', {}) self.merchant_name = self.config.get('merchant_name', 'Invoice')
def create_transaction_details_window(self, tx_dict): tx = Transaction(tx_dict["hex"]) dialog = QDialog(self.gui) dialog.setMinimumWidth(500) dialog.setWindowTitle(_('Process Offline transaction')) dialog.setModal(1) l = QGridLayout() dialog.setLayout(l) l.addWidget(QLabel(_("Transaction status:")), 3,0) l.addWidget(QLabel(_("Actions")), 4,0) if tx_dict["complete"] == False: l.addWidget(QLabel(_("Unsigned")), 3,1) if self.gui.wallet.seed : b = QPushButton("Sign transaction") input_info = json.loads(tx_dict["input_info"]) b.clicked.connect(lambda: self.sign_raw_transaction(tx, input_info, dialog)) l.addWidget(b, 4, 1) else: l.addWidget(QLabel(_("Wallet is de-seeded, can't sign.")), 4,1) else: l.addWidget(QLabel(_("Signed")), 3,1) b = QPushButton("Broadcast transaction") b.clicked.connect(lambda: self.gui.send_raw_transaction(tx, dialog)) l.addWidget(b,4,1) l.addWidget( self.gui.generate_transaction_information_widget(tx), 0,0,2,3) closeButton = QPushButton(_("Close")) closeButton.clicked.connect(lambda: dialog.done(0)) l.addWidget(closeButton, 4,2) dialog.exec_()
def __init__(self, gui): self.target_host = 'labelectrum.herokuapp.com' BasePlugin.__init__(self, gui, 'labels', _('Label Sync'), '%s\n\n%s%s%s' % (_("This plugin can sync your labels across multiple Electrum installs by using a remote database to save your data. Labels, transactions and addresses are all sent and stored encrypted on the remote server. This code might increase the load of your wallet with a few microseconds as it will sync labels on each startup."), _("To get started visit"), " http://labelectrum.herokuapp.com/", _(" to sign up for an account."))) self.wallet = gui.wallet self.gui = gui self.config = gui.config self.labels = self.wallet.labels self.transactions = self.wallet.transactions self.encode_password = hashlib.sha1(self.config.get("master_public_key")).digest().encode('hex')[:32] self.wallet_id = hashlib.sha256(str(self.config.get("master_public_key"))).digest().encode('hex') addresses = [] for k, account in self.wallet.accounts.items(): for address in account[0]: addresses.append(address) self.addresses = addresses
def create_transaction_details_window(self, tx_dict): tx = Transaction(tx_dict["hex"]) dialog = QDialog(self.gui) dialog.setMinimumWidth(500) dialog.setWindowTitle(_('Process Offline transaction')) dialog.setModal(1) l = QGridLayout() dialog.setLayout(l) l.addWidget(QLabel(_("Transaction status:")), 3,0) l.addWidget(QLabel(_("Actions")), 4,0) if tx_dict["complete"] == False: l.addWidget(QLabel(_("Unsigned")), 3,1) if self.gui.wallet.seed : b = QPushButton("Sign transaction") input_info = json.loads(tx_dict["input_info"]) b.clicked.connect(lambda: self.sign_raw_transaction(tx, input_info, dialog)) l.addWidget(b, 4, 1) else: l.addWidget(QLabel(_("Wallet is de-seeded, can't sign.")), 4,1) else: l.addWidget(QLabel(_("Signed")), 3,1) b = QPushButton("Broadcast transaction") b.clicked.connect(lambda: self.gui.send_raw_transaction(tx, dialog)) l.addWidget(b,4,1)
def init_gui(self): enabled = self.is_enabled() if enabled: self.gui.expert_mode = True self.gui.receive_list.setHeaderLabels( [_('Address'), _('Label'), _('Balance'), _('Request')]) else: self.gui.receive_list.setHeaderLabels( [_('Address'), _('Label'), _('Balance'), _('Tx')]) self.toggle_QR_window(enabled)
def init_gui(self): enabled = self.is_enabled() if enabled: self.gui.expert_mode = True self.gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Request')]) else: self.gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Tx')]) self.toggle_QR_window(enabled)
def read_raw_qr(self): qrcode = self.scan_qr() if qrcode: tx_dict = self.gui.tx_dict_from_text(qrcode) if tx_dict: self.create_transaction_details_window(tx_dict) def create_transaction_details_window(self, tx_dict): tx = Transaction(tx_dict["hex"]) dialog = QDialog(self.gui) dialog.setMinimumWidth(500) dialog.setWindowTitle(_('Process Offline transaction')) dialog.setModal(1) l = QGridLayout() dialog.setLayout(l) l.addWidget(QLabel(_("Transaction status:")), 3,0) l.addWidget(QLabel(_("Actions")), 4,0) if tx_dict["complete"] == False: l.addWidget(QLabel(_("Unsigned")), 3,1) if self.gui.wallet.seed : b = QPushButton("Sign transaction") input_info = json.loads(tx_dict["input_info"]) b.clicked.connect(lambda: self.sign_raw_transaction(tx, input_info, dialog)) l.addWidget(b, 4, 1) else: l.addWidget(QLabel(_("Wallet is de-seeded, can't sign.")), 4,1) else: l.addWidget(QLabel(_("Signed")), 3,1) b = QPushButton("Broadcast transaction") b.clicked.connect(lambda: self.gui.send_raw_transaction(tx, dialog)) l.addWidget(b,4,1) l.addWidget( self.gui.generate_transaction_information_widget(tx), 0,0,2,3) closeButton = QPushButton(_("Close")) closeButton.clicked.connect(lambda: dialog.done(0)) l.addWidget(closeButton, 4,2) dialog.exec_()
def full_push(self): if self.do_full_push(): QMessageBox.information(None, _("Labels uploaded"), _("Your labels have been uploaded."))
def __init__(self, gui): BasePlugin.__init__(self, gui, 'aliases', 'Aliases', _('Retrieve aliases using http.')) self.aliases = self.config.get('aliases', {}) # aliases for addresses self.authorities = self.config.get('authorities', {}) # trusted addresses self.receipts = self.config.get('receipts',{}) # signed URIs
def __init__(self, gui): BasePlugin.__init__(self, gui, 'virtualkeyboard', 'Virtual Keyboard', _("Add an optional, mouse keyboard to the password dialog.\nWarning: do not use this if it makes you pick a weaker password.")) self.vkb = None self.vkb_index = 0
def password_dialog(self, pw, grid, pos): vkb_button = QPushButton(_("+")) vkb_button.setFixedWidth(20) vkb_button.clicked.connect(lambda: self.toggle_vkb(grid, pw)) grid.addWidget(vkb_button, pos, 2) self.kb_pos = 2
def receive_menu(self, menu): menu.addAction(_("Request amount"), self.edit_amount)
def print_qr(self): filename = "qrcode.bmp" electrum_gui.bmp.save_qrcode(qrw.qr, filename) QMessageBox.information(None, _('Message'), _("QR code saved to file") + " " + filename, _('OK'))
class ContextMenu(Bubble): buttons = ListProperty([_('ok'), _('cancel')]) '''List of Buttons to be displayed at the bottom''' __events__ = ('on_press', 'on_release') def __init__(self, **kwargs): self._old_buttons = self.buttons super(ContextMenu, self).__init__(**kwargs) self.on_buttons(self, self.buttons) def on_touch_down(self, touch): if not self.collide_point(*touch.pos): self.hide() return return super(ContextMenu, self).on_touch_down(touch) def on_buttons(self, _menu, value): if 'menu_content' not in self.ids.keys(): return if value == self._old_buttons: return blayout = self.ids.menu_content blayout.clear_widgets() for btn in value: ib = ContextButton(text=btn) ib.bind(on_press=partial(self.dispatch, 'on_press')) ib.bind(on_release=partial(self.dispatch, 'on_release')) blayout.add_widget(ib) self._old_buttons = value def on_press(self, instance): pass def on_release(self, instance): pass def show(self, pos, duration=0): Window.add_widget(self) # wait for the bubble to adjust it's size according to text then animate Clock.schedule_once(lambda dt: self._show(pos, duration)) def _show(self, pos, duration): def on_stop(*l): if duration: Clock.schedule_once(self.hide, duration + .5) self.opacity = 0 arrow_pos = self.arrow_pos if arrow_pos[0] in ('l', 'r'): pos = pos[0], pos[1] - (self.height/2) else: pos = pos[0] - (self.width/2), pos[1] self.limit_to = Window anim = Animation(opacity=1, pos=pos, d=.32) anim.bind(on_complete=on_stop) anim.cancel_all(self) anim.start(self) def hide(self, *dt): def on_stop(*l): Window.remove_widget(self) anim = Animation(opacity=0, d=.25) anim.bind(on_complete=on_stop) anim.cancel_all(self) anim.start(self) def add_widget(self, widget, index=0): if not isinstance(widget, ContextMenuItem): super(ContextMenu, self).add_widget(widget, index) return menu_content.add_widget(widget, index)
def print_qr(self): filename = "qrcode.bmp" electrum_gui.bmp.save_qrcode(qrw.qr, filename) QMessageBox.information( None, _('Message'), _("QR code saved to file") + " " + filename, _('OK'))
def create_send_tab(self, grid): b = QPushButton(_("Scan QR code")) b.clicked.connect(self.fill_from_qr) grid.addWidget(b, 1, 5)
class Plugin(BasePlugin): def __init__(self, gui): BasePlugin.__init__( self, gui, 'qrscans', 'QR scans', "QR Scans.\nInstall the zbar package (http://zbar.sourceforge.net/download.html) to enable this plugin" ) self._is_available = self._init() def _init(self): if not zbar: return False try: proc = zbar.Processor() proc.init() except zbar.SystemError: # Cannot open video device return False return True def is_available(self): return self._is_available def create_send_tab(self, grid): b = QPushButton(_("Scan QR code")) b.clicked.connect(self.fill_from_qr) grid.addWidget(b, 1, 5) b2 = QPushButton(_("Scan TxQR")) b2.clicked.connect(self.read_raw_qr) if not self.gui.wallet.seed: b3 = QPushButton(_("Show unsigned TxQR")) b3.clicked.connect(self.show_raw_qr) grid.addWidget(b3, 7, 1) grid.addWidget(b2, 7, 2) else: grid.addWidget(b2, 7, 1) def scan_qr(self): proc = zbar.Processor() proc.init() proc.visible = True while True: try: proc.process_one() except: # User closed the preview window return {} for r in proc.results: if str(r.type) != 'QRCODE': continue return r.data def show_raw_qr(self): r = unicode(self.gui.payto_e.text()) r = r.strip() # label or alias, with address in brackets m = re.match('(.*?)\s*\<([1-9A-HJ-NP-Za-km-z]{26,})\>', r) to_address = m.group(2) if m else r if not is_valid(to_address): QMessageBox.warning( self.gui, _('Error'), _('Invalid Bitcoin Address') + ':\n' + to_address, _('OK')) return try: amount = self.gui.read_amount(unicode(self.gui.amount_e.text())) except: QMessageBox.warning(self.gui, _('Error'), _('Invalid Amount'), _('OK')) return try: fee = self.gui.read_amount(unicode(self.gui.fee_e.text())) except: QMessageBox.warning(self.gui, _('Error'), _('Invalid Fee'), _('OK')) return try: tx = self.gui.wallet.mktx([(to_address, amount)], None, fee, account=self.gui.current_account) except BaseException, e: self.gui.show_message(str(e)) return if tx.requires_fee( self.gui.wallet.verifier) and fee < MIN_RELAY_TX_FEE: QMessageBox.warning( self.gui, _('Error'), _("This transaction requires a higher fee, or it will not be propagated by the network." ), _('OK')) return try: out = {"hex": tx.hash(), "complete": "false"} input_info = [] except BaseException, e: self.gui.show_message(str(e))
def __init__(self, gui): BasePlugin.__init__(self, gui, 'pointofsale', 'Point of Sale', _('Show QR code window and amounts requested for each address. Add menu item to request amount.') ) self.qr_window = None self.requested_amounts = self.config.get('requested_amounts',{}) self.merchant_name = self.config.get('merchant_name', 'Invoice')