Exemplo n.º 1
0
 def qr_input(self):
     from electroncash import qrscanner, get_config
     try:
         data = qrscanner.scan_barcode(get_config().get_video_device())
     except BaseException as e:
         self.show_error(str(e))
         data = ''
     self.setText(data)
     return data
Exemplo n.º 2
0
 def qr_input(self):
     from electroncash import qrscanner, get_config
     try:
         data = qrscanner.scan_barcode(get_config().get_video_device())
     except BaseException as e:
         self.show_error(str(e))
         data = ''
     if not data:
         data = ''
     if self.allow_multi:
         new_text = self.text() + data + '\n'
     else:
         new_text = data
     self.setText(new_text)
     return data
Exemplo n.º 3
0
    def warn_if_no_secp(self,
                        parent=None,
                        message=None,
                        icon=QMessageBox.Warning,
                        relaxed=False):
        ''' Returns True if it DID warn: ie if there's no secp and ecc operations
        are slow, otherwise returns False if we have secp.

        Pass message (rich text) to provide a custom message.

        Note that the URL link to the HOWTO will always be appended to the custom message.'''
        from electroncash import ecc_fast
        has_secp = ecc_fast.is_using_fast_ecc()
        if has_secp:
            return False

        # When relaxwarn is set return True without showing the warning
        from electroncash import get_config
        if relaxed and get_config().cmdline_options["relaxwarn"]:
            return True

        # else..
        howto_url = 'https://github.com/Electron-Cash/Electron-Cash/blob/master/contrib/secp_HOWTO.md#libsecp256k1-0-for-electron-cash'
        template = '''
        <html><body>
            <p>
            {message}
            <p>
            {url_blurb}
            </p>
            <p><a href="{url}">Electron Cash Secp Mini-HOWTO</a></p>
        </body></html>
        '''
        msg = template.format(
            message=message or
            _("Electron Cash was unable to find the secp256k1 library on this system. Elliptic curve cryptography operations will be performed in slow Python-only mode."
              ),
            url=howto_url,
            url_blurb=
            _("Please visit this page for instructions on how to correct the situation:"
              ))
        self.warning(parent=parent,
                     title=_("Missing libsecp256k1"),
                     message=msg,
                     rich_text=True)
        return True
Exemplo n.º 4
0
    def __init__(self, data, parent=None, title="", show_text=False):
        WindowModalDialog.__init__(self, parent, title)

        vbox = QVBoxLayout()
        qrw = QRCodeWidget(data)
        p = QPixmap.grabWindow(qrw.winId())
        qscreen = QApplication.primaryScreen()
        vbox.addWidget(qrw, 1)
        if show_text:
            text = QTextEdit()
            text.setText(data)
            text.setReadOnly(True)
            vbox.addWidget(text)
        hbox = QHBoxLayout()
        hbox.addStretch(1)

        config = get_config()
        if config:
            filename = os.path.join(config.path, "qrcode.png")

            def print_qr():
                p = QPixmap.grabWindow(qrw.winId())
                p.save(filename, 'png')
                self.show_message(_("QR code saved to file") + " " + filename)

            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"))

            b = QPushButton(_("Copy"))
            hbox.addWidget(b)
            b.clicked.connect(copy_to_clipboard)

            b = QPushButton(_("Save"))
            hbox.addWidget(b)
            b.clicked.connect(print_qr)

        b = QPushButton(_("Close"))
        hbox.addWidget(b)
        b.clicked.connect(self.accept)
        b.setDefault(True)

        vbox.addLayout(hbox)
        self.setLayout(vbox)
Exemplo n.º 5
0
    def qr_input(self, callback=None):
        if self.qr_dialog:
            # Re-entrancy prevention -- there is some lag between when the user
            # taps the QR button and the modal dialog appears.  We want to
            # prevent multiple instances of the dialog from appearing, so we
            # must do this.
            util.print_error(
                "[ScanQRTextEdit] Warning: QR dialog is already presented, ignoring."
            )
            return
        from . import ElectrumGui
        if ElectrumGui.instance.warn_if_cant_import_qrreader(self):
            return
        from electroncash import get_config
        from .qrreader import QrReaderCameraDialog
        try:
            self.qr_dialog = QrReaderCameraDialog(
                parent=self.top_level_window())

            def _on_qr_reader_finished(success: bool, error: str, result):
                if self.qr_dialog:
                    self.qr_dialog.deleteLater()
                    self.qr_dialog = None
                if not success:
                    if error:
                        self.show_error(error)
                    return
                if not result:
                    result = ''
                if self.allow_multi:
                    new_text = self.text() + result + '\n'
                else:
                    new_text = result
                self.setText(new_text)
                if callback and success:
                    callback(result)

            self.qr_dialog.qr_finished.connect(_on_qr_reader_finished)
            self.qr_dialog.start_scan(get_config().get_video_device())
        except Exception as e:
            if util.is_verbose:
                import traceback
                traceback.print_exc()
            self.qr_dialog = None
            self.show_error(str(e))
Exemplo n.º 6
0
    def __init__(self, parent):
        ''' Note: make sure parent is a "top_level_window()" as per
        MessageBoxMixin API else bad things can happen on macOS. '''
        QtWidgets.QDialog.__init__(self, parent=parent)

        self.validator: AbstractQrReaderValidator = None
        self.frame_id: int = 0
        self.qr_crop: QRect = None
        self.qrreader_res: List[QrCodeResult] = []
        self.validator_res: QrReaderValidatorResult = None
        self.last_stats_time: float = 0.0
        self.frame_counter: int = 0
        self.qr_frame_counter: int = 0
        self.last_qr_scan_ts: float = 0.0
        self.camera: QCamera = None
        self._error_message: str = None
        self._ok_done: bool = False
        self.camera_sc_conn = None
        self.resolution: QSize = None

        self.config = get_config()

        # Try to get the QR reader for this system
        self.qrreader = get_qr_reader()
        if not self.qrreader:
            raise MissingQrDetectionLib(
                _("The platform QR detection library is not available."))

        # Set up the window, add the maximize button
        flags = self.windowFlags()
        flags = flags | Qt.WindowMaximizeButtonHint
        self.setWindowFlags(flags)
        self.setWindowTitle(_("Scan QR Code"))
        self.setWindowModality(
            Qt.WindowModal if parent else Qt.ApplicationModal)

        # Create video widget and fixed aspect ratio layout to contain it
        self.video_widget = QrReaderVideoWidget()
        self.video_overlay = QrReaderVideoOverlay()
        self.video_layout = FixedAspectRatioLayout()
        self.video_layout.addWidget(self.video_widget)
        self.video_layout.addWidget(self.video_overlay)

        # Create root layout and add the video widget layout to it
        vbox = QtWidgets.QVBoxLayout()
        self.setLayout(vbox)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.addLayout(self.video_layout)

        self.lowres_label = QtWidgets.QLabel(
            _("Note: This camera generates frames of relatively low resolution; QR scanning accuracy may be affected"
              ))
        self.lowres_label.setWordWrap(True)
        self.lowres_label.setAlignment(Qt.AlignVCenter | Qt.AlignHCenter)
        vbox.addWidget(self.lowres_label)
        self.lowres_label.setHidden(True)

        # Create a layout for the controls
        controls_layout = QtWidgets.QHBoxLayout()
        controls_layout.addStretch(2)
        controls_layout.setContentsMargins(10, 10, 10, 10)
        controls_layout.setSpacing(10)
        vbox.addLayout(controls_layout)

        # Flip horizontally checkbox with default coming from global config
        self.flip_x = QtWidgets.QCheckBox()
        self.flip_x.setText(_("&Flip horizontally"))
        self.flip_x.setChecked(bool(self.config.get('qrreader_flip_x', True)))
        self.flip_x.stateChanged.connect(self._on_flip_x_changed)
        controls_layout.addWidget(self.flip_x)

        close_but = QtWidgets.QPushButton(_("&Close"))
        close_but.clicked.connect(self.reject)
        controls_layout.addWidget(close_but)

        # Create the video surface and receive events when new frames arrive
        self.video_surface = QrReaderVideoSurface(self)
        self.video_surface.frame_available.connect(self._on_frame_available)

        # Create the crop blur effect
        self.crop_blur_effect = QrReaderCropBlurEffect(self)
        self.image_effect = ImageGraphicsEffect(self, self.crop_blur_effect)

        # Note these should stay as queued connections becasue we use the idiom
        # self.reject() and self.accept() in this class to kill the scan --
        # and we do it from within callback functions. If you don't use
        # queued connections here, bad things can happen.
        self.finished.connect(self._boilerplate_cleanup, Qt.QueuedConnection)
        self.finished.connect(self._on_finished, Qt.QueuedConnection)
Exemplo n.º 7
0
    def pay(self, tips: list):
        """constructs and broadcasts transaction paying the given tips. No questions asked."""
        if not self.network:
            return False

        if len(tips) <= 0:
            return False

        # (re)check wether tips qualify for autopay
        tips = [tip for tip in tips if self.qualifiesForAutopay(tip)]

        if len(tips) <= 0:
            return

        # label
        desc = "chaintip "
        desc_separator = ""
        for tip in tips:
            if tip.recipient_address and tip.amount_bch and isinstance(
                    tip.recipient_address, Address) and isinstance(
                        tip.amount_bch, Decimal):
                desc += f"{desc_separator}{tip.amount_bch} BCH to u/{tip.username} ({tip.chaintip_message_id})"
                desc_separator = ", "
        self.print_error("label for tx: ", desc)

        # construct transaction
        outputs = []
        #outputs.append(OPReturn.output_for_stringdata(op_return))
        for tip in tips:
            address = tip.recipient_address
            amount = int(COIN * tip.amount_bch)
            outputs.append((TYPE_ADDRESS, address, amount))
            self.print_error("address: ", address, "amount:", amount)

        try:
            for tip in tips:
                tip.payment_status = "autopaying..."

            tx = self.wallet.mktx(outputs, password=None, config=get_config())

            self.print_error("txid:", tx.txid())
            self.print_error("tx:", tx)

            status, msg = self.network.broadcast_transaction(tx)
            self.print_error("status: ", status, "msg: ", msg)

            self.resetTimer()

            if status:  # success
                # set tx label for history
                self.wallet.set_label(tx.txid(), text=desc, save=True)

                # this is a half-baked workaround for utxo set not being up-to-date on next payment
                #self.wallet.wait_until_synchronized() # should give some time
                #sleep(3) # my god, where have I gone?
            else:
                for tip in tips:
                    tip.payment_status = "autopay error: " + msg
                    self.tiplist.updateTip(tip)

            return status

        except Exception as e:
            self.print_error("error creating/sending tx: ", e)
            if isinstance(e, NotEnoughFunds):
                error = "not enough funds"
            else:
                error = "tx create/send error: " + str(e).partition('\n')[0]
            for tip in tips:
                tip.payment_status = error
                self.tiplist.updateTip(tip)
            return False