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