Example #1
0
 def get_card(self, req: Invoice) -> Dict[str, Any]:
     is_lightning = req.is_lightning()
     if not is_lightning:
         assert isinstance(req, OnchainInvoice)
         address = req.get_address()
         key = address
     else:
         assert isinstance(req, LNInvoice)
         key = req.rhash
         address = req.invoice
     amount = req.get_amount_sat()
     description = req.message
     status = self.app.wallet.get_request_status(key)
     status_str = req.get_status_str(status)
     ci = {}
     ci['screen'] = self
     ci['address'] = address
     ci['is_lightning'] = is_lightning
     ci['key'] = key
     ci['amount'] = self.app.format_amount_and_units(
         amount) if amount else ''
     ci['memo'] = description or _('No Description')
     ci['status'] = status
     ci['status_str'] = status_str
     return ci
Example #2
0
 def get_card(self, item: Invoice) -> Dict[str, Any]:
     status = self.app.wallet.get_invoice_status(item)
     status_str = item.get_status_str(status)
     is_lightning = item.type == PR_TYPE_LN
     if is_lightning:
         assert isinstance(item, LNInvoice)
         key = item.rhash
         address = key
         if self.app.wallet.lnworker:
             log = self.app.wallet.lnworker.logs.get(key)
             if status == PR_INFLIGHT and log:
                 status_str += '... (%d)' % len(log)
         is_bip70 = False
     else:
         assert isinstance(item, OnchainInvoice)
         key = item.id
         address = item.get_address()
         is_bip70 = bool(item.bip70)
     return {
         'is_lightning': is_lightning,
         'is_bip70': is_bip70,
         'screen': self,
         'status': status,
         'status_str': status_str,
         'key': key,
         'memo': item.message or _('No Description'),
         'address': address,
         'amount': self.app.format_amount_and_units(item.get_amount_sat()
                                                    or 0),
     }
Example #3
0
 def get_card(self, req: Invoice) -> Dict[str, Any]:
     is_lightning = req.is_lightning()
     if not is_lightning:
         address = req.get_address()
     else:
         address = req.lightning_invoice
     key = self.app.wallet.get_key_for_receive_request(req)
     amount = req.get_amount_sat()
     description = req.message
     status = self.app.wallet.get_request_status(key)
     status_str = req.get_status_str(status)
     ci = {}
     ci['screen'] = self
     ci['address'] = address
     ci['is_lightning'] = is_lightning
     ci['key'] = key
     ci['amount'] = self.app.format_amount_and_units(
         amount) if amount else ''
     ci['memo'] = description or _('No Description')
     ci['status'] = status
     ci['status_str'] = status_str
     return ci
Example #4
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'))