Exemple #1
0
    def provider_handle_pay_request(self, nexus, bolt11, request_uuid):
        msats = Bolt11.get_msats(bolt11)
        if not msats:
            return "no amount specified in bolt11"
        payment_hash = Bolt11.get_payment_hash(bolt11)
        shared_seed = nexus.get_shared_seed()
        liability_account = self.liabilities.lookup_by_seed(shared_seed)
        spendable_msats = (liability_account.get_msatoshis() -
                           liability_account.get_pending_msatoshis())
        if msats > spendable_msats:
            return "insufficent balance to pay"

        # decide which of our asset accounts will pay the bolt11
        asset_nexus_uuid = self.asset_pool.select_paying_nexus_uuid(msats)
        if not asset_nexus_uuid:
            return "no account capable of receiving"

        liability_account.add_paying(payment_hash, bolt11)
        self.liabilities.reindex_account(liability_account)

        our_request_uuid = self.consumer_stack.request_pay(
            asset_nexus_uuid, bolt11)
        self.pay_requests[our_request_uuid] = {
            'liability_nexus_uuid': nexus.uuid,
            'liability_request_uuid': request_uuid,
            'liability_account_uuid': liability_account.uuid,
            'bolt11': bolt11,
            'asset_nexus_uuid': asset_nexus_uuid
        }
Exemple #2
0
    def _handle_paying_preimage(self, nexus, preimage, request_reference_uuid):
        payment_hash = Bolt11.preimage_to_payment_hash(preimage)
        logging.info("preimage %s payment_hash %s" % (preimage, payment_hash))

        liability_accounts = list(
            self.liabilities.lookup_by_paying_payment_hash(payment_hash))
        assert len(liability_accounts) <= 1, "can't handle collision yet"
        if len(liability_accounts) == 0:
            logging.error("got preimage not associated to liability?")
            return
        liability_account = liability_accounts[0]

        shared_seeds = liability_account.get_all_shared_seeds()

        msats_sent = [
            Bolt11.get_msats(bolt11)
            for ph, bolt11 in liability_account.iter_paying()
            if ph == payment_hash
        ][0]
        liability_account.remove_paying(payment_hash)
        liability_account.subtract_wad(Wad.bitcoin(msats_sent))
        self.liabilities.reindex_account(liability_account)

        if request_reference_uuid in self.pay_requests:
            info = self.pay_requests.pop(request_reference_uuid)
            rrid = info['liability_request_uuid']
        else:
            rrid = None

        self.provider_stack.notify_preimage(shared_seeds, preimage, rrid)
Exemple #3
0
    def handle_pay_request(self, nexus, bolt11, request_uuid):
        shared_seed = nexus.get_shared_seed()
        account = self.directory.lookup_by_seed(shared_seed)
        assert account is not None, "shared seed not from known account?"

        shared_seeds = account.get_all_shared_seeds()

        msats = Bolt11.get_msats(bolt11)
        if (msats is None):
            err = "bolt11 does not specify amount",
            account.session_error_notified(shared_seed, err)
            self.provider_error(shared_seeds, err, request_uuid)
            return

        wad = account.get_wad()
        if msats > wad['msats']:
            # TODO - estimate routing fees?
            err = "insufficent account balance"
            account.session_error_notified(shared_seed, err)
            self.provider_error(shared_seeds, err, request_uuid)
            return

        account.session_pay_requested(shared_seed, bolt11)

        preimage, paid_msats, err = self.lightning.pay_invoice(
            bolt11, request_uuid)
        if err:
            account.session_error_notified(shared_seed, err)
            self.provider_error(shared_seeds, err, request_uuid)
            return

        paid_wad = Wad.bitcoin(paid_msats)

        if (paid_msats > wad['msats']):
            # routing fees could have exceeded balance... need to figure
            # out the best way to deal with this
            paid_msats = wad['msats']
        account.subtract_wad(paid_wad)

        # TODO new pay preimage message to propagate fees
        self.provider_stack.notify_preimage(shared_seeds, preimage,
                                            request_uuid)
        for ss in shared_seeds:
            account.session_preimage_notified(ss, preimage, False, paid_msats)
Exemple #4
0
    def terminus_handle_pay_request(self, shared_seed, bolt11):
        # TODO - this should be a request-> callback to allow for an
        # asynchronous call to the daemon.

        account = self.directory.lookup_by_seed(shared_seed)
        assert account is not None, "shared seed not from known account?"

        msats = Bolt11.get_msats(bolt11)
        wad = account.get_wad()
        if msats > wad['msats']:
            return # msatoshi balance exceeded

        # TODO handle failure
        preimage, paid_msats = self.lightning.pay_invoice(bolt11)

        paid_wad = Wad.bitcoin(paid_msats)

        account.subtract_wad(paid_wad)

        shared_seeds = account.get_all_shared_seeds()
        # TODO pay preimage
        self.terminus_stack.notify_preimage(shared_seeds, preimage)
Exemple #5
0
    def consumer_on_invoice(self, nexus, bolt11, request_reference_uuid):
        if request_reference_uuid not in self.invoice_requests:
            logging.error("got bolt11 not requested? %s" %
                          request_reference_uuid)
            return

        request_info = self.invoice_requests.pop(request_reference_uuid)

        liability_nexus_uuid = request_info['liability_nexus_uuid']
        liability_request_uuid = request_info['liability_request_uuid']
        liability_account_uuid = request_info['liability_account_uuid']
        asset_nexus_uuid = request_info['asset_nexus_uuid']
        msats_requested = request_info['msats_requested']

        liability_account = self.liabilities.lookup_by_uuid(
            liability_account_uuid)

        if asset_nexus_uuid != nexus.uuid:
            logging.info("got bolt11 from different nexus than requested?")

        if not liability_account:
            logging.error("liability account removed?")
            return

        bolt11_msats = Bolt11.get_msats(bolt11)
        if bolt11_msats and bolt11_msats != msats_requested:
            logging.error("got wrong msats amount?")
            return

        bolt11_payment_hash = Bolt11.get_payment_hash(bolt11)
        liability_account.add_pending(bolt11_payment_hash, bolt11)
        self.liabilities.reindex_account(liability_account)

        shared_seeds = liability_account.get_all_shared_seeds()

        self.provider_stack.notify_invoice(shared_seeds, bolt11,
                                           liability_request_uuid)
Exemple #6
0
 def session_pay_requested(self, shared_seed, bolt11):
     msats = Bolt11.get_msats(bolt11)
     wad = Wad.bitcoin(msats)
     entry = SocketSessionReceipt.pay_request_entry(bolt11, wad)
     self.db.add_receipt_entry(shared_seed, entry)
Exemple #7
0
 def get_pending_msatoshis(self):
     msats = 0
     for _, bolt11 in self.get_pending():
         msats += Bolt11.get_msats(bolt11)
     return msats