def pay_cb(n, action): assert action == "pay" PAYMENT = stub.SendPaymentSync(ln.SendRequest(payment_request=LN_INVOICE)) if PAYMENT.payment_error: notify2.Notification("Lightning Pay", "Transaction to \n{}\nfailed with \n{}".format(DEST,PAYMENT.payment_error),icon=ICON_FAILURE).show() else: notify2.Notification("Lightning Pay","Transaction to \n{}\nis successful".format(DEST),icon=ICON_SUCCESS).show() n.close()
def scan_channel(my_channel_id: int, scan_channel_id: int): # Grab some initial data and make sure everything came back OK node = init_node() my_channels = node.ListChannels(ln.ListChannelsRequest()).channels my_channel = [c for c in my_channels if c.chan_id == my_channel_id][0] channel = node.GetChanInfo(ln.ChanInfoRequest(chan_id=scan_channel_id)) if not my_channel: raise Exception(f'You have no channel with ID "{my_channel_id}"') if not channel: raise Exception(f'Unknown channel with ID "{scan_channel_id}"') # Determine the max we can scan, and who's the "receiver" maximum = min( int(channel.capacity), int(my_channel.local_balance), MAX_PAYMENT_SIZE, ) dest_pubkey = channel.node2_pub if my_channel.remote_pubkey == channel.node1_pub else channel.node2_pub # Loop send bogus payments until we find the balance low = 0 high = maximum print(f'Beginning scan of channel {scan_channel_id}, max scannable {maximum} satoshis...') while high - low > 1: test_amount = math.ceil((low + high) / 2) print(f'Probing with a {test_amount} sat payment...') res = node.SendPaymentSync(ln.SendRequest( dest_string=dest_pubkey, amt=test_amount, payment_hash_string=make_random_hash(), outgoing_chan_id=my_channel.chan_id, final_cltv_delta=144, )) err = res.payment_error # Depending on the error, raise or lower the amount. The route note having # enough capacity comes in many shapes and sizes of error, so we have to # check for a few types here. if 'UnknownPaymentHash' in err: print('Amount was too low, raising lower bound...') low = test_amount elif 'unable to find a path' in err or \ 'insufficient' in err or \ 'TemporaryChannelFailure' in err: print('Amount was too high, lowering upper bound...') high = test_amount else: raise Exception(f'Unknown error occured when trying to scan: {err}') print(f'Balance for channel ${scan_channel_id} is between {low} and {high} satoshis!') if high == maximum: print(f'NOTE: The balance exceeds the height we were able to scan, so it may be larger than {maximum} satoshis')
def _pay(self, bolt11): try: request = ln.SendRequest(payment_request=bolt11) response = self.stub.SendPaymentSync(request) logging.info(response) if response.payment_preimage: return "Preimage %s" % MessageToJson(response.payment_preimage) else: return str(response) except grpc.RpcError as e: logging.error(e) return e.details()
def pay_invoice(self, pay_req): invoice_details = self.decode_pay_request(pay_req) try: request = ln.SendRequest( dest_string=invoice_details.destination, amt=invoice_details.num_satoshis, payment_hash_string=invoice_details.payment_hash, final_cltv_delta=144 # final_cltv_delta=144 is default for lnd ) response = self.client.SendPaymentSync(request) logger.warning(response) except Exception as e: logger.exception(e)
def sendPayment(self, invoice, amt=None): if amt: if amt < 100000: feeLimit = 20 elif amt < 200000: feeLimit = 20 elif amt < 300000: feeLimit = 30 elif amt < 400000: feeLimit = 40 elif amt < 500000: feeLimit = 50 else: feeLimit = 50 request = ln.SendRequest(payment_request=invoice, fee_limit=ln.FeeLimit(fixed=feeLimit), amt=amt) else: request = ln.SendRequest(payment_request=invoice, fee_limit=ln.FeeLimit(fixed=10)) return self.stub.SendPaymentSync(request)
def pay_invoice(invoice): send_req = ln.SendRequest(payment_request=invoice) sent_payment = stub.SendPaymentSync(send_req) if "unable to find a path to destination" in sent_payment.payment_error: return sent_payment.payment_error return invoice
raise e logger.debug(decode_payreq) satoshis = decode_payreq.num_satoshis destination = decode_payreq.destination if satoshis > db.get_balance(session, user): update.message.reply_text("Insufficient funds") return logger.info("{} initiating payment of {}".format(user, payment_request)) update.message.reply_text("Sending payment...") # XXX: This is a synchonous command, will block until GRPC_TIMEOUT try: ret = stub.SendPaymentSync( ln.SendRequest(payment_request=payment_request), timeout=GRPC_TIMEOUT) except Exception, e: update.message.reply_markdown(messages.exception(e)) raise e if ret.payment_route \ and ret.payment_route.total_amt > 0: # Payment successfully went through sent_amount = ret.payment_route.total_amt num_hops = len(ret.payment_route.hops) fee_amount = sent_amount - satoshis logger.info("{} sent payment of {} satoshis to {}".format( user, sent_amount, destination)) db.add_transaction(session, user, -sent_amount, payment_request) session.commit()
def send_payment(pay_req): request = ln.SendRequest(payment_request=pay_req) response = stub.SendPaymentSync(request) return True
def send(self, bolt11): req = lnrpc.SendRequest(payment_request=bolt11) res = self.rpc.stub.SendPaymentSync(req) if res.payment_error: raise ValueError(res.payment_error) return hexlify(res.payment_preimage)
def send(self, req): req = lnrpc.SendRequest(payment_request=req) res = self.rpc.stub.SendPaymentSync(req) return hexlify(res.payment_preimage)
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 if sys.stdout.isatty(): print("{} mBTC in Lightning Network".format(BALANCE)) if DEST in whitelist and MBTC <= MAX_AUTOPAY_AMT and BALANCE >= MIN_AUTOPAY_BALANCE : print("Paying to {} for {} with {}".format(DEST,DESC,MBTC)) PAYMENT = stub.SendPaymentSync(ln.SendRequest(payment_request=LN_INVOICE)) if PAYMENT.payment_error: _ = input("Transaction to {} failed with {}, press any key to exit".format(DEST,PAYMENT.payment_error)) else: print("Transaction to {} is successful".format(DEST)) sleep(1) else: CMD = input("Pay to {} for {} with {} mBTC y/n: ".format(DEST,DESC,MBTC)) if CMD == 'y': PAYMENT = stub.SendPaymentSync(ln.SendRequest(payment_request=LN_INVOICE)) if PAYMENT.payment_error: _ = input("Transaction to {} failed with {}, press any key to exit".format(DEST,PAYMENT.payment_error)) else: print("Transaction to {} is successful".format(DEST)) sleep(1)
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
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)