예제 #1
0
 def read_invoice(self):
     if self.check_send_tab_payto_line_and_show_errors():
         return
     try:
         if not self._is_onchain:
             invoice_str = self.payto_e.lightning_invoice
             if not invoice_str:
                 return
             if not self.wallet.has_lightning():
                 self.show_error(_('Lightning is disabled'))
                 return
             invoice = Invoice.from_bech32(invoice_str)
             if invoice.amount_msat is None:
                 amount_sat = self.amount_e.get_amount()
                 if amount_sat:
                     invoice.amount_msat = int(amount_sat * 1000)
                 else:
                     self.show_error(_('No amount'))
                     return
             return invoice
         else:
             outputs = self.read_outputs()
             if self.check_send_tab_onchain_outputs_and_show_errors(
                     outputs):
                 return
             message = self.message_e.text()
             return self.wallet.create_invoice(outputs=outputs,
                                               message=message,
                                               pr=self.payment_request,
                                               URI=self.payto_URI)
     except InvoiceError as e:
         self.show_error(_('Error creating payment') + ':\n' + str(e))
예제 #2
0
 def read_invoice(self):
     address = str(self.address)
     if not address:
         self.app.show_error(
             _('Recipient not specified.') + ' ' +
             _('Please scan a Bitcoin address or a payment request'))
         return
     if not self.amount:
         self.app.show_error(_('Please enter an amount'))
         return
     if self.is_max:
         amount = '!'
     else:
         try:
             amount = self.app.get_amount(self.amount)
         except:
             self.app.show_error(_('Invalid amount') + ':\n' + self.amount)
             return
     message = self.message
     try:
         if self.is_lightning:
             return Invoice.from_bech32(address)
         else:  # on-chain
             if self.payment_request:
                 outputs = self.payment_request.get_outputs()
             else:
                 if not bitcoin.is_address(address):
                     self.app.show_error(
                         _('Invalid Bitcoin Address') + ':\n' + address)
                     return
                 outputs = [
                     PartialTxOutput.from_address_and_value(
                         address, amount)
                 ]
             return self.app.wallet.create_invoice(outputs=outputs,
                                                   message=message,
                                                   pr=self.payment_request,
                                                   URI=self.parsed_URI)
     except InvoiceError as e:
         self.app.show_error(_('Error creating payment') + ':\n' + str(e))
예제 #3
0
    def validateRecipient(self, recipient):
        if not recipient:
            self.setInvoiceType(QEInvoice.Type.Invalid)
            return

        maybe_lightning_invoice = recipient

        def _payment_request_resolved(request):
            self._logger.debug('resolved payment request')
            outputs = request.get_outputs()
            invoice = self.create_onchain_invoice(outputs, None, request, None)
            self.setValidOnchainInvoice(invoice)

        try:
            self._bip21 = parse_URI(recipient, _payment_request_resolved)
            if self._bip21:
                if 'r' in self._bip21 or ('name' in self._bip21 and 'sig' in self._bip21): # TODO set flag in util?
                    # let callback handle state
                    return
                if ':' not in recipient:
                    # address only
                    self.setValidAddressOnly()
                    self.validationSuccess.emit()
                    return
                else:
                    # fallback lightning invoice?
                    if 'lightning' in self._bip21:
                        maybe_lightning_invoice = self._bip21['lightning']
        except InvalidBitcoinURI as e:
            self._bip21 = None
            self._logger.debug(repr(e))

        lninvoice = None
        maybe_lightning_invoice = maybe_extract_lightning_payment_identifier(maybe_lightning_invoice)
        if maybe_lightning_invoice is not None:
            try:
                lninvoice = Invoice.from_bech32(maybe_lightning_invoice)
            except InvoiceError as e:
                e2 = e.__cause__
                if isinstance(e2, LnInvoiceException):
                    self.validationError.emit('unknown', _("Error parsing Lightning invoice") + f":\n{e2}")
                    self.clear()
                    return
                if isinstance(e2, lnutil.IncompatibleOrInsaneFeatures):
                    self.validationError.emit('unknown', _("Invoice requires unknown or incompatible Lightning feature") + f":\n{e2!r}")
                    self.clear()
                    return
                self._logger.exception(repr(e))

        if not lninvoice and not self._bip21:
            self.validationError.emit('unknown',_('Unknown invoice'))
            self.clear()
            return

        if lninvoice:
            if not self._wallet.wallet.has_lightning():
                if not self._bip21:
                    # TODO: lightning onchain fallback in ln invoice
                    #self.validationError.emit('no_lightning',_('Detected valid Lightning invoice, but Lightning not enabled for wallet'))
                    self.setValidLightningInvoice(lninvoice)
                    self.clear()
                    return
                else:
                    self._logger.debug('flow with LN but not LN enabled AND having bip21 uri')
                    self.setValidOnchainInvoice(self._bip21['address'])
            else:
                self.setValidLightningInvoice(lninvoice)
                if not self._wallet.wallet.lnworker.channels:
                    self.validationWarning.emit('no_channels',_('Detected valid Lightning invoice, but there are no open channels'))
                else:
                    self.validationSuccess.emit()
        else:
            self._logger.debug('flow without LN but having bip21 uri')
            if 'amount' not in self._bip21: #TODO can we have amount-less invoices?
                self.validationError.emit('no_amount', 'no amount in uri')
                return
            outputs = [PartialTxOutput.from_address_and_value(self._bip21['address'], self._bip21['amount'])]
            self._logger.debug(outputs)
            message = self._bip21['message'] if 'message' in self._bip21 else ''
            invoice = self.create_onchain_invoice(outputs, message, None, self._bip21)
            self._logger.debug(repr(invoice))
            self.setValidOnchainInvoice(invoice)
            self.validationSuccess.emit()