Esempio n. 1
0
    def _do_pay_lightning(self, invoice: Invoice, pw) -> None:
        amount_msat = invoice.get_amount_msat()

        def pay_thread():
            try:
                coro = self.app.wallet.lnworker.pay_invoice(
                    invoice.lightning_invoice, amount_msat=amount_msat)
                fut = asyncio.run_coroutine_threadsafe(
                    coro, self.app.network.asyncio_loop)
                fut.result()
            except Exception as e:
                self.app.show_error(repr(e))

        self.save_invoice(invoice)
        threading.Thread(target=pay_thread).start()
Esempio n. 2
0
    def pay_lightning_invoice(self, invoice: Invoice):
        amount_sat = invoice.get_amount_sat()
        key = self.wallet.get_key_for_outgoing_invoice(invoice)
        if amount_sat is None:
            raise Exception("missing amount for LN invoice")
        if not self.wallet.lnworker.can_pay_invoice(invoice):
            num_sats_can_send = int(self.wallet.lnworker.num_sats_can_send())
            lightning_needed = amount_sat - num_sats_can_send
            lightning_needed += (lightning_needed // 20
                                 )  # operational safety margin
            coins = self.window.get_coins(nonlocal_only=True)
            can_pay_onchain = invoice.get_address(
            ) and self.wallet.can_pay_onchain(invoice.get_outputs(),
                                              coins=coins)
            can_pay_with_new_channel = self.wallet.lnworker.suggest_funding_amount(
                amount_sat, coins=coins)
            can_pay_with_swap = self.wallet.lnworker.suggest_swap_to_send(
                amount_sat, coins=coins)
            rebalance_suggestion = self.wallet.lnworker.suggest_rebalance_to_send(
                amount_sat)
            can_rebalance = bool(
                rebalance_suggestion) and self.window.num_tasks() == 0
            choices = {}
            if can_rebalance:
                msg = ''.join([
                    _('Rebalance existing channels'), '\n',
                    _('Move funds between your channels in order to increase your sending capacity.'
                      )
                ])
                choices[0] = msg
            if can_pay_with_new_channel:
                msg = ''.join([
                    _('Open a new channel'), '\n',
                    _('You will be able to pay once the channel is open.')
                ])
                choices[1] = msg
            if can_pay_with_swap:
                msg = ''.join([
                    _('Swap onchain funds for lightning funds'), '\n',
                    _('You will be able to pay once the swap is confirmed.')
                ])
                choices[2] = msg
            if can_pay_onchain:
                msg = ''.join([
                    _('Pay onchain'), '\n',
                    _('Funds will be sent to the invoice fallback address.')
                ])
                choices[3] = msg
            if not choices:
                raise NotEnoughFunds()
            msg = _('You cannot pay that invoice using Lightning.')
            if self.wallet.lnworker.channels:
                msg += '\n' + _('Your channels can send {}.').format(
                    self.format_amount(num_sats_can_send) + self.base_unit())
            r = self.window.query_choice(msg, choices)
            if r is not None:
                self.save_pending_invoice()
                if r == 0:
                    chan1, chan2, delta = rebalance_suggestion
                    self.window.rebalance_dialog(chan1,
                                                 chan2,
                                                 amount_sat=delta)
                elif r == 1:
                    amount_sat, min_amount_sat = can_pay_with_new_channel
                    self.window.channels_list.new_channel_dialog(
                        amount_sat=amount_sat, min_amount_sat=min_amount_sat)
                elif r == 2:
                    chan, swap_recv_amount_sat = can_pay_with_swap
                    self.window.run_swap_dialog(
                        is_reverse=False,
                        recv_amount_sat=swap_recv_amount_sat,
                        channels=[chan])
                elif r == 3:
                    self.pay_onchain_dialog(coins, invoice.get_outputs())
            return

        # FIXME this is currently lying to user as we truncate to satoshis
        amount_msat = invoice.get_amount_msat()
        msg = _("Pay lightning invoice?") + '\n\n' + _(
            "This will send {}?").format(
                self.format_amount_and_units(Decimal(amount_msat) / 1000))
        if not self.question(msg):
            return
        self.save_pending_invoice()
        coro = self.wallet.lnworker.pay_invoice(invoice.lightning_invoice,
                                                amount_msat=amount_msat)
        self.window.run_coroutine_from_thread(coro, _('Sending payment'))