Example #1
0
 def decodepay(self, bolt11):
     try:
         request = ln.PayReqString(pay_req=bolt11)
         response = self.stub.DecodePayReq(request)
         logging.info(response)
     except grpc.RpcError as e:
         logging.error(e)
Example #2
0
 def decode_pay_request(self, pay_req):
     try:
         pay_req = pay_req.rstrip()
         raw_invoice = ln.PayReqString(pay_req=str(pay_req))
         response = self.client.DecodePayReq(raw_invoice)
         return response
     except Exception as e:
         logger.exception(e)
Example #3
0
def decode_invoice(string):
    """Decode invoice using lnd"""
    # First do a quick negative test on the human-readable part
    # NOTE: lnd does not currently support invoices without
    # amount so we don't either
    if not re.match("^ln(bc|tb)[0-9]+[munp]", string):
        return
    return stub.DecodePayReq(ln.PayReqString(pay_req=string),
                             timeout=GRPC_TIMEOUT)
Example #4
0
def is_received(pay_req):
    # first decode pay_req to get pay_hash
    request = ln.PayReqString(pay_req=pay_req)
    response = stub.DecodePayReq(request)
    pay_hash = response.payment_hash

    # check if settled
    request = ln.PaymentHash(r_hash_str=pay_hash)
    response = stub.LookupInvoice(request)
    return response.settled
Example #5
0
 def decode_payment_request(self, payment_request):
     request = ln.PayReqString(
         pay_req=payment_request,
     )
     return self.stub.DecodePayReq(request)
Example #6
0
def closed_cb(n):
    Gtk.main_quit()

try:
    if sys.argv[1][:10] == 'lightning:':
        LN_INVOICE = sys.argv[1][10:]
    else:
        LN_INVOICE = sys.argv[1]
except IndexError:
    LN_INVOICE = input('Paste your Lightning Network invoice here: ')
    if LN_INVOICE == '':
        _ = input("No Lightning Network invoice entered, press enter to exit")
        raise

try:
    DECODED_PAYREQ = stub.DecodePayReq(ln.PayReqString(pay_req=LN_INVOICE))
except grpc._channel._Rendezvous:
    if sys.stdout.isatty():
        _ = input("Invalid Lightning Network invoice, press enter to exit")
        raise ValueError
    else:
        notify2.init("LN-Pay")
        notify2.Notification("Invalid Lightning Network invoice").show()
        sys.exit(1)


MBTC = DECODED_PAYREQ.num_satoshis/100000
DEST = DECODED_PAYREQ.destination
DESC = DECODED_PAYREQ.description
BALANCE = stub.ChannelBalance(ln.ChannelBalanceRequest()).balance * 100000
async def r_decode_invoice(*_, invoice: str):
    request = ln.PayReqString(pay_req=invoice.replace("lightning:", ""))
    try:
        return await LND.stub.DecodePayReq(request)
    except GRPCError:
        return None
Example #8
0
async def r_pay_invoice(user: User,
                        *_,
                        invoice: str,
                        amt: Optional[int] = None):
    # determine true invoice amount
    pay_string = ln.PayReqString(pay_req=invoice.replace("lightning:", ""))
    try:
        decoded = await LND.stub.DecodePayReq(pay_string)
    except GRPCError as e:
        return Error("PaymentError", str(e))

    if amt is not None and decoded.num_satoshis != amt and decoded.num_satoshis > 0:
        return Error("PaymentError",
                     "Payment amount does not match invoice amount")

    if decoded.num_satoshis == 0 and not amt:
        return Error("PaymentError",
                     "You must specify an amount for this tip invoice")

    payment_amt = amt or decoded.num_satoshis
    fee_limit = ceil(payment_amt * 0.01)

    # convert decoded hex to string b64
    b64_payment_hash = b64encode(b16decode(decoded.payment_hash,
                                           casefold=True)).decode()

    # lock payer's db row before determining balance
    async with GINO.db.transaction():
        # potentially user.query.with_for..
        await user.query.with_for_update().gino.status()  # obtain lock
        user_balance = await user.balance()
        if payment_amt + fee_limit > user_balance:
            return Error(
                "InsufficientFunds",
                f"""Attempting to pay {payment_amt} sat
                with fee limit {fee_limit} sat
                with only {user_balance} sat""",
            )

        # determine if external node invoice
        if LND.id_pubkey != decoded.destination:

            req = ln.SendRequest(
                payment_request=invoice,
                amt=payment_amt,
                fee_limit=ln.FeeLimit(fixed=fee_limit),
            )

            invoice_obj = Invoice(
                payment_hash=b64_payment_hash,
                payment_request=invoice,
                timestamp=decoded.timestamp,
                expiry=decoded.expiry,
                memo=decoded.description,
                paid=False,  # not yet paid
                amount=decoded.num_satoshis,
                payer=user.username,
            )

            payment_res = await LND.stub.SendPaymentSync(req)
            if payment_res.payment_error or not payment_res.payment_preimage:
                return Error("PaymentError", payment_res.payment_error)

            invoice_obj.payment_preimage = b64encode(
                payment_res.payment_preimage).decode()
            # impose maximum fee
            invoice_obj.fee = max(fee_limit,
                                  payment_res.payment_route.total_fees)
            invoice_obj.paid = True
            invoice_obj.paid_at = int(time())

            return await invoice_obj.create()

        # determine if internal user invoice
        elif LND.id_pubkey == decoded.destination and (
                invoice_obj := await Invoice.get(b64_payment_hash)):
            if invoice_obj.paid:
                return Error("PaymentError",
                             "This invoice has already been paid")
            # internal invoice, get payee from db
            if not (payee := await User.get(invoice_obj.payee)):
                # could not find the invoice payee in the db
                return Error("PaymentError", "This invoice is invalid")

            await invoice_obj.update(paid=True,
                                     payer=user.username,
                                     fee=fee_limit,
                                     paid_at=time()).apply()

            # check if there are clients in the subscribe channel for this invoice
            if payee.username in PUBSUB.keys():
                # clients are listening, push to all open clients
                for client in PUBSUB[payee.username]:
                    await client.put(invoice_obj)

            return invoice_obj
Example #9
0
 def decodePayRequest(self, payRequest):
     return self.stub.DecodePayReq(ln.PayReqString(pay_req=payRequest))
Example #10
0
def makepayment():
     try:
        rpc_connect = AuthServiceProxy("http://{}:{}@{}:{}".format(rpc_user,rpc_password,allowed_ip,rpc_port))
        current_block_height = rpc_connect.getblockcount()
        onchain_peers = rpc_connect.getconnectioncount()
        chain_type = rpc_connect.getblockchaininfo()['chain']
        onchain_balance = rpc_connect.getbalance()
        fasttx = rpc_connect.estimatesmartfee(2)
        medtx = rpc_connect.estimatesmartfee(6)
        slowtx = rpc_connect.estimatesmartfee(12)

        newaddress = rpc_connect.getnewaddress()
        packqraddr = pyqrcode.create(newaddress)
        packqraddr.svg("app/static/img/newaddress.svg", scale=8)

        if chain_type == "main":
            fasttxrate = u"~₿ " + str(fasttx['feerate'])
            medtxrate = u"~₿ " + str(medtx['feerate'])
            slowtxrate = u"~₿ " + str(slowtx['feerate'])
        else:
            fasttxrate = u"~t₿ " + str(fasttx['feerate'])
            medtxrate = u"~t₿ " + str(medtx['feerate'])
            slowtxrate = u"~t₿ " + str(slowtx['feerate'])

        if onchain_balance > 0 and chain_type == "main":
            onchain_balance = u"₿ " + str(onchain_balance)
        elif onchain_balance == 0:
            onchain_balance = u"₿ " + str(0)
        elif onchain_balance > 0 and chain_type == "test":
            onchain_balance = u"t₿ " + str(onchain_balance)        
        else:
            onchain_balance = u"t₿ " + str(0)
        if chain_type == "test":
            chaintype_ln = "testnet"
        else:
            chaintype_ln = "mainnet"

        conn = True
     except:
        onchain_balance = "Offline!"
        fasttxrate, medtxrate, slowtxrate = "", "", ""
        conn = False

     try:
      os.environ["GRPC_SSL_CIPHER_SUITES"] = 'HIGH+ECDSA'
      with open(os.path.expanduser(lnd_dir_location + 'data/chain/bitcoin/{}/admin.macaroon'.format(chaintype_ln)), 'rb') as f:
        macaroon_bytes = f.read()
        macaroon = codecs.encode(macaroon_bytes, 'hex')
      cert = open(os.path.expanduser(lnd_dir_location + 'tls.cert'), 'rb').read()
      creds = grpc.ssl_channel_credentials(cert)
      channel = grpc.secure_channel('localhost:10009', creds)
      stub = lnrpc.LightningStub(channel)

      satbalance = stub.ChannelBalance(ln.ChannelBalanceRequest(), metadata=[('macaroon', macaroon)])
      offchain_balance = u"ş " + str(format(satbalance.balance,','))

      lninvoice = (stub.AddInvoice(ln.Invoice(), metadata=[('macaroon', macaroon)])).payment_request
      packlnaddr = pyqrcode.create(lninvoice)
      packqraddr.svg("app/static/img/lninvoice.svg", scale=8)

     except:
      offchain_balance = "Offline!"

     if conn == True:
      if request.method == 'POST':
        if request.form['action'] == "sendbutton":
          if request.form['fee'] == "medfee":
            try:
              txid = rpc_connect.sendtoaddress(request.form['address'], request.form['amt'], "", "", False, True, medtx['blocks'])

              return render_template('makepayment.html', onchain_balance=onchain_balance, fasttxrate=fasttxrate, medtxrate=medtxrate, slowtxrate=slowtxrate, successfultx=True, txid=txid, offchain_balance=offchain_balance, newaddress=newaddress, lninvoice=lninvoice)
            except:

              return render_template('makepayment.html', onchain_balance=onchain_balance, fasttxrate=fasttxrate, medtxrate=medtxrate, slowtxrate=slowtxrate, successfultx=False, offchain_balance=offchain_balance, newaddress=newaddress, lninvoice=lninvoice)

          elif request.form['fee'] == "highfee":
            try:
              txid = rpc_connect.sendtoaddress(request.form['address'], request.form['amt'], "", "", False, True, fasttx['blocks'])

              return render_template('makepayment.html', onchain_balance=onchain_balance, fasttxrate=fasttxrate, medtxrate=medtxrate, slowtxrate=slowtxrate, successfultx=True, txid=txid, offchain_balance=offchain_balance, newaddress=newaddress, lninvoice=lninvoice)
            except:

              return render_template('makepayment.html', onchain_balance=onchain_balance, fasttxrate=fasttxrate, medtxrate=medtxrate, slowtxrate=slowtxrate, successfultx=False, offchain_balance=offchain_balance, newaddress=newaddress, lninvoice=lninvoice) 
          elif request.form['fee'] == "lowfee":
            try:
              txid = rpc_connect.sendtoaddress(request.form['address'], request.form['amt'], "", "", False, True, slowtx['blocks'])

              return render_template('makepayment.html', onchain_balance=onchain_balance, fasttxrate=fasttxrate, medtxrate=medtxrate, slowtxrate=slowtxrate, successfultx=True, txid=txid, offchain_balance=offchain_balance, newaddress=newaddress, lninvoice=lninvoice)
            except:
              return render_template('makepayment.html', onchain_balance=onchain_balance, fasttxrate=fasttxrate, medtxrate=medtxrate, slowtxrate=slowtxrate, successfultx=False, offchain_balance=offchain_balance, newaddress=newaddress, lninvoice=lninvoice)

        if request.form['action'] == "decodereq":
            try:
              os.environ["GRPC_SSL_CIPHER_SUITES"] = 'HIGH+ECDSA'
              with open(os.path.expanduser(lnd_dir_location + 'data/chain/bitcoin/{}/admin.macaroon'.format(chaintype_ln)), 'rb') as f:
                macaroon_bytes = f.read()
                macaroon = codecs.encode(macaroon_bytes, 'hex')
              cert = open(os.path.expanduser(lnd_dir_location + 'tls.cert'), 'rb').read()
              creds = grpc.ssl_channel_credentials(cert)
              channel = grpc.secure_channel('localhost:10009', creds)
              stub = lnrpc.LightningStub(channel)
              if len(request.form['reqtext']) > 20:
                req_whole = request.form['reqtext']
                decoded_req = stub.DecodePayReq(ln.PayReqString(pay_req=req_whole), metadata=[('macaroon', macaroon)])
                req_desc = decoded_req.description
                req_amt = u"ş " + str(format(decoded_req.num_satoshis,','))
                req_to = decoded_req.destination
                with open("invoice.txt",'wb') as invoicefile:
                 invoicefile.write(req_whole)
                 invoicefile.close()
                return render_template('makepayment.html', onchain_balance=onchain_balance, fasttxrate=fasttxrate, medtxrate=medtxrate, slowtxrate=slowtxrate, successfultx="N/A", req_desc=req_desc, req_amt=req_amt, req_to=req_to, switch=True, offchain_balance=offchain_balance, req_whole=req_whole, newaddress=newaddress, lninvoice=lninvoice)
              else:
                return render_template('makepayment.html', onchain_balance=onchain_balance, fasttxrate=fasttxrate, medtxrate=medtxrate, slowtxrate=slowtxrate, successfultx="N/A", switch=False, offchain_balance=offchain_balance, newaddress=newaddress, lninvoice=lninvoice)
            except:
              return render_template('makepayment.html', onchain_balance=onchain_balance, fasttxrate=fasttxrate, medtxrate=medtxrate, slowtxrate=slowtxrate, successfultx="N/A", switch=False, offchain_balance=offchain_balance, newaddress=newaddress, lninvoice=lninvoice)
        if request.form['action'] == "confirmbutton":
            try:
              os.environ["GRPC_SSL_CIPHER_SUITES"] = 'HIGH+ECDSA'
              with open(os.path.expanduser(lnd_dir_location + 'data/chain/bitcoin/{}/admin.macaroon'.format(chaintype_ln)), 'rb') as f:
                macaroon_bytes = f.read()
                macaroon = codecs.encode(macaroon_bytes, 'hex')
              cert = open(os.path.expanduser(lnd_dir_location + 'tls.cert'), 'rb').read()
              creds = grpc.ssl_channel_credentials(cert)
              channel = grpc.secure_channel('localhost:10009', creds)
              stub = lnrpc.LightningStub(channel)
              with open("invoice.txt",'r') as invoicefile:
                invoice_confirmed = invoicefile.read()    

              try:
               result = stub.SendPaymentSync(ln.SendRequest(payment_request=str(invoice_confirmed)), metadata=[('macaroon', macaroon)])
               if result.payment_error:
                 return render_template('makepayment.html', onchain_balance=onchain_balance, fasttxrate=fasttxrate, medtxrate=medtxrate, slowtxrate=slowtxrate, successfultx="N/A", offchain_balance=offchain_balance, successln=False, error=result.payment_error, newaddress=newaddress, lninvoice=lninvoice)
               else:
                return render_template('makepayment.html', onchain_balance=onchain_balance, fasttxrate=fasttxrate, medtxrate=medtxrate, slowtxrate=slowtxrate, successfultx="N/A", offchain_balance=offchain_balance, successln=True, preimage=hexlify(result.payment_preimage), newaddress=newaddress, lninvoice=lninvoice)
              except:
                return render_template('makepayment.html', onchain_balance=onchain_balance, fasttxrate=fasttxrate, medtxrate=medtxrate, slowtxrate=slowtxrate, successfultx=False, offchain_balance=offchain_balance, newaddress=newaddress, lninvoice=lninvoice)
            except:
                return render_template('makepayment.html', onchain_balance=onchain_balance, fasttxrate=fasttxrate, medtxrate=medtxrate, slowtxrate=slowtxrate, successfultx=False, offchain_balance=offchain_balance, newaddress=newaddress, lninvoice=lninvoice)
        
      else:
        return render_template('makepayment.html', onchain_balance=onchain_balance, fasttxrate=fasttxrate, medtxrate=medtxrate, slowtxrate=slowtxrate, successfultx="N/A", offchain_balance=offchain_balance, newaddress=newaddress, lninvoice=lninvoice)
     return render_template('makepayment.html', onchain_balance=onchain_balance, fasttxrate=fasttxrate, medtxrate=medtxrate, slowtxrate=slowtxrate, successfultx="N/A", offchain_balance=offchain_balance)