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 }
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)
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)
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)
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)
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)
def get_pending_msatoshis(self): msats = 0 for _, bolt11 in self.get_pending(): msats += Bolt11.get_msats(bolt11) return msats