def receive_list_menu(self, menu, addr): window = menu.parentWidget() menu.addAction(_("Send via e-mail"), lambda: self.send(window, addr))
def create_menu(self, position): from fermatum.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 = [unicode(item.text(0)) 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) menu.addAction( _("Copy %s") % column_title, lambda: self.parent.app.clipboard().setText(item.text(col))) if col in self.editable_columns: menu.addAction( _("Edit %s") % column_title, lambda: self.editItem(item, col)) menu.addAction(_("Request payment"), lambda: self.parent.receive_at(addr)) menu.addAction(_('History'), lambda: self.parent.show_address(addr)) menu.addAction(_('Public Keys'), lambda: self.parent.show_public_keys(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 description(self): return _("Send and receive payment requests via email")
def copy_to_clipboard(): p = QPixmap.grabWindow(qrw.winId()) p.save(filename, 'png') QApplication.clipboard().setImage(QImage(filename)) self.show_message(_("QR code copied to clipboard"))
def __init__(self, parent=None): MyTreeWidget.__init__( self, parent, self.create_menu, [_('Address'), _('Label'), _('Balance'), _('Tx')], 1) self.setSelectionMode(QAbstractItemView.ExtendedSelection)
from fermatum.i18n import _ fullname = _('Cosigner Pool') description = ' '.join([ _("This plugin facilitates the use of multi-signatures wallets."), _("It sends and receives partially signed transactions from/to your cosigner wallet." ), _("Transactions are encrypted and stored on a remote server.") ]) #requires_wallet_type = ['2of2', '2of3'] available_for = ['qt']
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 change_label(self, label): self.msg = _("Confirm the new label on your %s device") self.apply_settings(label=label)
def change_homescreen(self, homescreen): self.msg = _("Confirm on your %s device to change your home screen") self.apply_settings(homescreen=homescreen)
def decrypt_message(self, pubkey, message, password): raise RuntimeError( _('Encryption and decryption are currently not supported for %s') % self.device)
def sign_transaction(self, tx, password): if tx.is_complete(): return client = self.get_client() self.signing = True inputs = [] inputsPaths = [] pubKeys = [] chipInputs = [] redeemScripts = [] signatures = [] preparedTrustedInputs = [] changePath = "" changeAmount = None output = None outputAmount = None p2shTransaction = False reorganize = False pin = "" self.get_client( ) # prompt for the PIN before displaying the dialog if necessary # Fetch inputs of the transaction to sign derivations = self.get_tx_derivations(tx) for txin in tx.inputs(): if txin['type'] == 'coinbase': self.give_error( "Coinbase not supported") # should never happen if txin['type'] in ['p2sh']: p2shTransaction = True pubkeys, x_pubkeys = tx.get_sorted_pubkeys(txin) for i, x_pubkey in enumerate(x_pubkeys): if x_pubkey in derivations: signingPos = i s = derivations.get(x_pubkey) hwAddress = "%s/%d/%d" % (self.get_derivation()[2:], s[0], s[1]) break else: self.give_error("No matching x_key for sign_transaction" ) # should never happen inputs.append([ txin['prev_tx'].raw, txin['prevout_n'], txin.get('redeemScript'), txin['prevout_hash'], signingPos ]) inputsPaths.append(hwAddress) pubKeys.append(pubkeys) # Sanity check if p2shTransaction: for txin in tx.inputs(): if txin['type'] != 'p2sh': self.give_error( "P2SH / regular input mixed in same transaction not supported" ) # should never happen txOutput = var_int(len(tx.outputs())) for txout in tx.outputs(): output_type, addr, amount = txout txOutput += int_to_hex(amount, 8) script = tx.pay_script(output_type, addr) txOutput += var_int(len(script) / 2) txOutput += script txOutput = txOutput.decode('hex') # Recognize outputs - only one output and one change is authorized if not p2shTransaction: if not self.get_client_fermatum().supports_multi_output(): if len(tx.outputs()) > 2: self.give_error( "Transaction with more than 2 outputs not supported") for _type, address, amount in tx.outputs(): assert _type == TYPE_ADDRESS info = tx.output_info.get(address) if (info is not None) and (len(tx.outputs()) != 1): index, xpubs, m = info changePath = self.get_derivation()[2:] + "/%d/%d" % index changeAmount = amount else: output = address outputAmount = amount self.handler.show_message( _("Confirm Transaction on your Ledger device...")) try: # Get trusted inputs from the original transactions for utxo in inputs: if not p2shTransaction: txtmp = iopTransaction(bytearray(utxo[0].decode('hex'))) chipInputs.append(self.get_client().getTrustedInput( txtmp, utxo[1])) redeemScripts.append(txtmp.outputs[utxo[1]].script) else: tmp = utxo[3].decode('hex')[::-1].encode('hex') tmp += int_to_hex(utxo[1], 4) chipInputs.append({'value': tmp.decode('hex')}) redeemScripts.append(bytearray(utxo[2].decode('hex'))) # Sign all inputs firstTransaction = True inputIndex = 0 rawTx = tx.serialize() self.get_client().enableAlternate2fa(False) while inputIndex < len(inputs): self.get_client().startUntrustedTransaction( firstTransaction, inputIndex, chipInputs, redeemScripts[inputIndex]) if not p2shTransaction: outputData = self.get_client().finalizeInput( output, format_satoshis_plain(outputAmount), format_satoshis_plain(tx.get_fee()), changePath, bytearray(rawTx.decode('hex'))) reorganize = True else: outputData = self.get_client().finalizeInputFull(txOutput) outputData['outputData'] = txOutput if firstTransaction: transactionOutput = outputData['outputData'] if outputData['confirmationNeeded']: outputData['address'] = output self.handler.clear_dialog() pin = self.handler.get_auth( outputData ) # does the authenticate dialog and returns pin if not pin: raise UserWarning() if pin != 'paired': self.handler.show_message( _("Confirmed. Signing Transaction...")) 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 if pin != 'paired': firstTransaction = False except UserWarning: self.handler.show_error(_('Cancelled by user')) return except BaseException as e: traceback.print_exc(file=sys.stdout) self.give_error(e, True) finally: self.handler.clear_dialog() # Reformat transaction inputIndex = 0 while inputIndex < len(inputs): if p2shTransaction: signaturesPack = [signatures[inputIndex]] * len( pubKeys[inputIndex]) inputScript = get_p2sh_input_script(redeemScripts[inputIndex], signaturesPack) preparedTrustedInputs.append([ ("\x00" * 4) + chipInputs[inputIndex]['value'], inputScript ]) else: inputScript = get_regular_input_script( signatures[inputIndex], pubKeys[inputIndex][0].decode('hex')) preparedTrustedInputs.append( [chipInputs[inputIndex]['value'], inputScript]) inputIndex = inputIndex + 1 updatedTransaction = format_transaction(transactionOutput, preparedTrustedInputs) updatedTransaction = hexlify(updatedTransaction) if reorganize: tx.update(updatedTransaction) else: tx.update_signatures(updatedTransaction) self.signing = False
class Ledger_KeyStore(Hardware_KeyStore): hw_type = 'ledger' device = 'Ledger' def __init__(self, d): Hardware_KeyStore.__init__(self, d) # Errors and other user interaction is done through the wallet's # handler. The handler is per-window and preserved across # device reconnects self.force_watching_only = False self.signing = False self.cfg = d.get('cfg', {'mode': 0, 'pair': ''}) def dump(self): obj = Hardware_KeyStore.dump(self) obj['cfg'] = self.cfg return obj def get_derivation(self): return self.derivation def get_client(self): return self.plugin.get_client(self).dongleObject def get_client_fermatum(self): return self.plugin.get_client(self) def give_error(self, message, clear_client=False): print_error(message) if not self.signing: self.handler.show_error(message) else: self.signing = False if clear_client: self.client = None raise Exception(message) def address_id_stripped(self, address): # Strip the leading "m/" change, index = self.get_address_index(address) derivation = self.derivation address_path = "%s/%d/%d" % (derivation, change, index) return address_path[2:] def decrypt_message(self, pubkey, message, password): raise RuntimeError( _('Encryption and decryption are currently not supported for %s') % self.device) def sign_message(self, sequence, message, password): self.signing = True # prompt for the PIN before displaying the dialog if necessary client = self.get_client() address_path = self.get_derivation()[2:] + "/%d/%d" % sequence self.handler.show_message("Signing message ...") try: info = self.get_client().signMessagePrepare(address_path, message) pin = "" if info['confirmationNeeded']: pin = self.handler.get_auth( info) # does the authenticate dialog and returns pin if not pin: raise UserWarning(_('Cancelled by user')) pin = str(pin).encode() signature = self.get_client().signMessageSign(pin) except BTChipException, e: if e.sw == 0x6a80: self.give_error( "Unfortunately, this message cannot be signed by the Ledger wallet. Only alphanumerical messages shorter than 140 characters are supported. Please remove any extra characters (tab, carriage return) and retry." ) else: self.give_error(e, True) except UserWarning: self.handler.show_error(_('Cancelled by user')) return ''
def sign_transaction(self, tx, password): if tx.is_complete(): return try: p2shTransaction = False derivations = self.get_tx_derivations(tx) hasharray = [] pubkeyarray = [] # Build hasharray from inputs for i, txin in enumerate(tx.inputs()): if txin['type'] == 'coinbase': self.give_error("Coinbase not supported") # should never happen if txin['type'] in ['p2sh']: p2shTransaction = True for x_pubkey in txin['x_pubkeys']: if x_pubkey in derivations: index = derivations.get(x_pubkey) inputPath = "%s/%d/%d" % (self.get_derivation(), index[0], index[1]) inputHash = Hash(tx.serialize_preimage(i).decode('hex')).encode('hex') hasharray_i = {'hash': inputHash, 'keypath': inputPath} hasharray.append(hasharray_i) break else: self.give_error("No matching x_key for sign_transaction") # should never happen # Sanity check if p2shTransaction: for txinput in tx.inputs(): if txinput['type'] != 'p2sh': self.give_error("P2SH / regular input mixed in same transaction not supported") # should never happen # Build pubkeyarray from outputs (unused because echo for smart verification not implemented) if not p2shTransaction: for _type, address, amount in tx.outputs(): assert _type == TYPE_ADDRESS info = tx.output_info.get(address) if info is not None: index, xpubs, m = info changePath = self.get_derivation() + "/%d/%d" % index changePubkey = self.derive_pubkey(index[0], index[1]) pubkeyarray_i = {'pubkey': changePubkey, 'keypath': changePath} pubkeyarray.append(pubkeyarray_i) # Build sign command dbb_signatures = [] steps = math.ceil(1.0 * len(hasharray) / self.maxInputs) for step in range(int(steps)): hashes = hasharray[step * self.maxInputs : (step + 1) * self.maxInputs] msg = '{"sign": {"meta":"%s", "data":%s, "checkpub":%s} }' % \ (Hash(tx.serialize()).encode('hex'), json.dumps(hashes), json.dumps(pubkeyarray)) dbb_client = self.plugin.get_client(self) if not dbb_client.is_paired(): raise Exception("Could not sign transaction.") reply = dbb_client.hid_send_encrypt(msg) if 'error' in reply: raise Exception(reply['error']['message']) if 'echo' not in reply: raise Exception("Could not sign transaction.") if steps > 1: self.handler.show_message(_("Signing large transaction. Please be patient ...\r\n\r\n" \ "To continue, touch the Digital Bitbox's blinking light for 3 seconds. " \ "(Touch " + str(step + 1) + " of " + str(int(steps)) + ")\r\n\r\n" \ "To cancel, briefly touch the blinking light or wait for the timeout.\r\n\r\n")) else: self.handler.show_message(_("Signing transaction ...\r\n\r\n" \ "To continue, touch the Digital Bitbox's blinking light for 3 seconds.\r\n\r\n" \ "To cancel, briefly touch the blinking light or wait for the timeout.")) reply = dbb_client.hid_send_encrypt(msg) # Send twice, first returns an echo for smart verification (not implemented) self.handler.clear_dialog() if 'error' in reply: raise Exception(reply['error']['message']) if 'sign' not in reply: raise Exception("Could not sign transaction.") dbb_signatures.extend(reply['sign']) # Fill signatures if len(dbb_signatures) <> len(tx.inputs()): raise Exception("Incorrect number of transactions signed.") # Should never occur for i, txin in enumerate(tx.inputs()): num = txin['num_sig'] for pubkey in txin['pubkeys']: signatures = filter(None, txin['signatures']) if len(signatures) == num: break # txin is complete ii = txin['pubkeys'].index(pubkey) signed = dbb_signatures[i] if signed['pubkey'] != pubkey: continue sig_r = int(signed['sig'][:64], 16) sig_s = int(signed['sig'][64:], 16) sig = sigencode_der(sig_r, sig_s, generator_secp256k1.order()) txin['signatures'][ii] = sig.encode('hex') tx._inputs[i] = txin except BaseException as e: self.give_error(e, True) else: print_error("Transaction is_complete", tx.is_complete()) tx.raw = tx.serialize()
def show_settings_dialog(self, window, success): if not success: window.show_message(_('Server not reachable.')) return wallet = window.wallet d = WindowModalDialog(window, _("TrustedCoin Information")) d.setMinimumSize(500, 200) vbox = QVBoxLayout(d) hbox = QHBoxLayout() logo = QLabel() logo.setPixmap(QPixmap(":icons/trustedcoin-status.png")) msg = _('This wallet is protected by TrustedCoin\'s two-factor authentication.') + '<br/>'\ + _("For more information, visit") + " <a href=\"https://api.trustedcoin.com/#/fermatum-help\">https://api.trustedcoin.com/#/fermatum-help</a>" label = QLabel(msg) label.setOpenExternalLinks(1) hbox.addStretch(10) hbox.addWidget(logo) hbox.addStretch(10) hbox.addWidget(label) hbox.addStretch(10) vbox.addLayout(hbox) vbox.addStretch(10) msg = _( 'TrustedCoin charges a fee per co-signed transaction. You may pay on each transaction (an extra output will be added to your transaction), or you may purchase prepaid transaction using this dialog.' ) + '<br/>' label = QLabel(msg) label.setWordWrap(1) vbox.addWidget(label) vbox.addStretch(10) grid = QGridLayout() vbox.addLayout(grid) price_per_tx = wallet.price_per_tx v = price_per_tx.get(1) grid.addWidget(QLabel(_("Price per transaction (not prepaid):")), 0, 0) grid.addWidget( QLabel(window.format_amount(v) + ' ' + window.base_unit()), 0, 1) i = 1 for k, v in sorted(price_per_tx.items()): if k == 1: continue grid.addWidget(QLabel("Price for %d prepaid transactions:" % k), i, 0) grid.addWidget( QLabel("%d x " % k + window.format_amount(v / k) + ' ' + window.base_unit()), i, 1) b = QPushButton(_("Buy")) b.clicked.connect(lambda b, k=k, v=v: self.on_buy(window, k, v, d)) grid.addWidget(b, i, 2) i += 1 n = wallet.billing_info.get('tx_remaining', 0) grid.addWidget( QLabel(_("Your wallet has %d prepaid transactions.") % n), i, 0) # tranfer button #def on_transfer(): # server.transfer_credit(self.user_id, recipient, otp, signature_callback) # pass #b = QPushButton(_("Transfer")) #b.clicked.connect(on_transfer) #grid.addWidget(b, 1, 2) #grid.addWidget(QLabel(_("Next Billing Address:")), i, 0) #grid.addWidget(QLabel(self.billing_info['billing_address']), i, 1) vbox.addLayout(Buttons(CloseButton(d))) d.exec_()
def settings_widget(self, window): return EnterButton(_('Settings'), partial(self.settings_dialog, window))
class GuiMixin(object): # Requires: self.proto, self.device messages = { 3: _("Confirm the transaction output on your %s device"), 4: _("Confirm internal entropy on your %s device to begin"), 5: _("Write down the seed word shown on your %s"), 6: _("Confirm on your %s that you want to wipe it clean"), 7: _("Confirm on your %s device the message to sign"), 8: _("Confirm the total amount spent and the transaction fee on your " "%s device"), 10: _("Confirm wallet address on your %s device"), 'default': _("Check your %s device to continue"), } def callback_Failure(self, msg): # BaseClient's unfortunate call() implementation forces us to # raise exceptions on failure in order to unwind the stack. # However, making the user acknowledge they cancelled # gets old very quickly, so we suppress those. The NotInitialized # one is misnamed and indicates a passphrase request was cancelled. if msg.code in (self.types.Failure_PinCancelled, self.types.Failure_ActionCancelled, self.types.Failure_NotInitialized): raise UserCancelled() raise RuntimeError(msg.message) def callback_ButtonRequest(self, msg): message = self.msg if not message: message = self.messages.get(msg.code, self.messages['default']) self.handler.show_message(message % self.device, self.cancel) return self.proto.ButtonAck() def callback_PinMatrixRequest(self, msg): if msg.type == 2: msg = _("Enter a new PIN for your %s:") elif msg.type == 3: msg = (_("Re-enter the new PIN for your %s.\n\n" "NOTE: the positions of the numbers have changed!")) else: msg = _("Enter your current %s PIN:") pin = self.handler.get_pin(msg % self.device) if not pin: return self.proto.Cancel() return self.proto.PinMatrixAck(pin=pin) def callback_PassphraseRequest(self, req): if self.creating_wallet: msg = _("Enter a passphrase to generate this wallet. Each time " "you use this wallet your %s will prompt you for the " "passphrase. If you forget the passphrase you cannot " "access the IoPs in the wallet.") % self.device else: msg = _("Enter the passphrase to unlock this wallet:") passphrase = self.handler.get_passphrase(msg, self.creating_wallet) if passphrase is None: return self.proto.Cancel() passphrase = bip39_normalize_passphrase(passphrase) return self.proto.PassphraseAck(passphrase=passphrase) def callback_WordRequest(self, msg): self.step += 1 msg = _("Step %d/24. Enter seed word as explained on " "your %s:") % (self.step, self.device) word = self.handler.get_word(msg) # Unfortunately the device can't handle self.proto.Cancel() return self.proto.WordAck(word=word) def callback_CharacterRequest(self, msg): char_info = self.handler.get_char(msg) if not char_info: return self.proto.Cancel() return self.proto.CharacterAck(**char_info)
def __init__(self, network, config, wizard=False): self.network = network self.config = config self.protocol = None self.tor_proxy = None self.servers = network.get_servers() host, port, protocol, proxy_config, auto_connect = network.get_parameters( ) if not proxy_config: proxy_config = { "mode": "none", "host": "localhost", "port": "9050" } if not wizard: n = len(network.get_interfaces()) if n: status = _("Blockchain") + ": " + "%d " % ( network.get_local_height()) + _("blocks") + ".\n" + _( "Getting block headers from %d nodes.") % n else: status = _("Not connected") if network.is_connected(): status += "\n" + _("Server") + ": %s" % (host) else: status += "\n" + _("Disconnected from server") else: status = _("Please choose a server.") + "\n" + _( "Press 'Next' if you are offline.") vbox = QVBoxLayout() hbox = QHBoxLayout() l = QLabel() l.setPixmap(QPixmap(":icons/network.png")) hbox.addStretch(10) hbox.addWidget(l) hbox.addWidget(QLabel(status)) hbox.addStretch(50) msg = _("Fermatum sends your wallet addresses to a single server, in order to receive your transaction history.") + "\n\n" \ + _("In addition, Fermatum connects to several nodes in order to download block headers and find out the longest blockchain.") + " " \ + _("This blockchain is used to verify the transactions sent by the address server.") hbox.addWidget(HelpButton(msg)) vbox.addLayout(hbox) vbox.addSpacing(15) # grid layout grid = QGridLayout() grid.setSpacing(8) vbox.addLayout(grid) # server self.server_host = QLineEdit() self.server_host.setFixedWidth(200) self.server_port = QLineEdit() self.server_port.setFixedWidth(60) grid.addWidget(QLabel(_('Server') + ':'), 0, 0) grid.addWidget(self.server_host, 0, 1, 1, 2) grid.addWidget(self.server_port, 0, 3) # use SSL self.ssl_cb = QCheckBox(_('Use SSL')) self.ssl_cb.setChecked(auto_connect) grid.addWidget(self.ssl_cb, 0, 2, 1, 1, Qt.AlignRight) self.ssl_cb.stateChanged.connect(self.change_protocol) # auto connect self.autoconnect_cb = QCheckBox(_('Select server automatically')) self.autoconnect_cb.setChecked(auto_connect) grid.addWidget(self.autoconnect_cb, 1, 1, 1, 3) self.autoconnect_cb.setEnabled( self.config.is_modifiable('auto_connect')) msg = _("If auto-connect is enabled, Fermatum will always use a server that is on the longest blockchain.") + "\n" \ + _("If it is disabled, Fermatum will warn you if your server is lagging.") self.autoconnect_cb.setToolTip(msg) label = _('Active Servers') if network.is_connected() else _( 'Default Servers') self.servers_list_widget = QTreeWidget() self.servers_list_widget.setHeaderLabels([label, _('Limit')]) self.servers_list_widget.setMaximumHeight(150) self.servers_list_widget.setColumnWidth(0, 240) self.change_server(host, protocol) self.set_protocol(protocol) self.servers_list_widget.connect( self.servers_list_widget, SIGNAL('currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)'), lambda x, y: self.server_changed(x)) grid.addWidget(self.servers_list_widget, 2, 1, 1, 3) def enable_set_server(): if config.is_modifiable('server'): enabled = not self.autoconnect_cb.isChecked() self.server_host.setEnabled(enabled) self.server_port.setEnabled(enabled) self.servers_list_widget.setEnabled(enabled) else: for w in [ self.autoconnect_cb, self.server_host, self.server_port, self.ssl_cb, self.servers_list_widget ]: w.setEnabled(False) self.autoconnect_cb.clicked.connect(enable_set_server) enable_set_server() # proxy setting self.proxy_mode = QComboBox() self.proxy_host = QLineEdit() self.proxy_host.setFixedWidth(200) self.proxy_port = QLineEdit() self.proxy_port.setFixedWidth(60) self.proxy_mode.addItems(['NONE', 'SOCKS4', 'SOCKS5', 'HTTP']) self.proxy_user = QLineEdit() self.proxy_user.setPlaceholderText(_("Proxy user")) self.proxy_password = QLineEdit() self.proxy_password.setPlaceholderText(_("Password")) self.proxy_password.setEchoMode(QLineEdit.Password) self.proxy_password.setFixedWidth(60) def check_for_disable(index=False): if self.config.is_modifiable('proxy'): for w in [ self.proxy_host, self.proxy_port, self.proxy_user, self.proxy_password ]: w.setEnabled(self.proxy_mode.currentText() != 'NONE') else: for w in [self.proxy_host, self.proxy_port, self.proxy_mode]: w.setEnabled(False) check_for_disable() self.proxy_mode.connect(self.proxy_mode, SIGNAL('currentIndexChanged(int)'), check_for_disable) self.proxy_mode.setCurrentIndex( self.proxy_mode.findText(str(proxy_config.get("mode").upper()))) self.proxy_host.setText(proxy_config.get("host")) self.proxy_port.setText(proxy_config.get("port")) self.proxy_user.setText(proxy_config.get("user", "")) self.proxy_password.setText(proxy_config.get("password", "")) self.proxy_mode.connect(self.proxy_mode, SIGNAL('currentIndexChanged(int)'), self.proxy_settings_changed) self.proxy_host.connect(self.proxy_host, SIGNAL('textEdited(QString)'), self.proxy_settings_changed) self.proxy_port.connect(self.proxy_port, SIGNAL('textEdited(QString)'), self.proxy_settings_changed) self.proxy_user.connect(self.proxy_user, SIGNAL('textEdited(QString)'), self.proxy_settings_changed) self.proxy_password.connect(self.proxy_password, SIGNAL('textEdited(QString)'), self.proxy_settings_changed) grid.addWidget(QLabel(_('Proxy') + ':'), 4, 0) grid.addWidget(self.proxy_mode, 4, 1) grid.addWidget(self.proxy_host, 4, 2) grid.addWidget(self.proxy_port, 4, 3) grid.addWidget(self.proxy_user, 5, 2) grid.addWidget(self.proxy_password, 5, 3) self.tor_button = QCheckBox(_("Use Tor Proxy")) self.tor_button.setIcon(QIcon(":icons/tor_logo.png")) self.tor_button.hide() self.tor_button.clicked.connect(self.use_tor_proxy) grid.addWidget(self.tor_button, 6, 2, 1, 2) self.layout_ = vbox self.td = td = TorDetector() td.found_proxy.connect(self.suggest_proxy) td.start()
class Plugin(BasePlugin): button_label = _("Verify GA instant") @hook def transaction_dialog(self, d): d.verify_button = QPushButton(self.button_label) d.verify_button.clicked.connect(lambda: self.do_verify(d)) d.buttons.insert(0, d.verify_button) self.transaction_dialog_update(d) def get_my_addr(self, d): """Returns the address for given tx which can be used to request instant confirmation verification from GreenAddress""" for addr, _ in d.tx.get_outputs(): if d.wallet.is_mine(addr): return addr return None @hook def transaction_dialog_update(self, d): if d.tx.is_complete() and self.get_my_addr(d): d.verify_button.show() else: d.verify_button.hide() def do_verify(self, d): tx = d.tx wallet = d.wallet window = d.parent # 1. get the password and sign the verification request password = None if wallet.use_encryption: msg = _('GreenAddress requires your signature \n' 'to verify that transaction is instant.\n' 'Please enter your password to sign a\n' 'verification request.') password = window.password_dialog(msg, parent=d) if not password: return try: d.verify_button.setText(_('Verifying...')) QApplication.processEvents() # update the button label addr = self.get_my_addr(d) message = "Please verify if %s is GreenAddress instant confirmed" % tx.hash( ) sig = wallet.sign_message(addr, message, password) sig = base64.b64encode(sig) # 2. send the request response = requests.request( "GET", ("https://greenaddress.it/verify/?signature=%s&txhash=%s" % (urllib.quote(sig), tx.hash())), headers={'User-Agent': 'Fermatum'}) response = response.json() # 3. display the result if response.get('verified'): d.show_message( _('%s is covered by GreenAddress instant confirmation') % (tx.hash()), title=_('Verification successful!')) else: d.show_critical( _('%s is not covered by GreenAddress instant confirmation') % (tx.hash()), title=_('Verification failed!')) except BaseException as e: import traceback traceback.print_exc(file=sys.stdout) d.show_error(str(e)) finally: d.verify_button.setText(self.button_label)
def contextMenuEvent(self, e): m = self.createStandardContextMenu() m.addAction(_("Show as QR code"), self.qr_show) m.exec_(e.globalPos())
def done_processing(self, dialog, result): dialog.show_message(_("Your labels have been synchronised."))
def contextMenuEvent(self, e): m = self.createStandardContextMenu() m.addAction(_("Read QR code"), self.qr_input) m.exec_(e.globalPos())
def print_qr(): p = QPixmap.grabWindow(qrw.winId()) p.save(filename, 'png') self.show_message(_("QR code saved to file") + " " + filename)