request-invoice: Remove the plugin

It's utterly outdated, and has been replaced by a number of other
plugins, no point in keeping it around.
This commit is contained in:
Christian Decker
2022-12-30 13:25:09 +01:00
parent a1e3eb44d2
commit dc09f7d434
4 changed files with 0 additions and 215 deletions

View File

@@ -1,47 +0,0 @@
# Http Invoice Request Server plugin
This plugin starts a minimal, rate limited HTTP Server and returns a invoice on the following GET request:
``/invoice/<amount>/<description>``
```
$ lightning-cli invoiceserver start
started server successfully on port 8089
$ curl http://localhost:8809/invoice/100000/some-text-here
{"bolt11":"lnbc100000n1p0yr9sxpp50t9rnvw5slcjn6m97fmujpp9xd6w0h26dpvajcv8xwhu42xk5vlqdq8vej8xcgxqyj...","expires_at":1581961350,"payment_hash":"7aca39b1d487f129eb65f277c904253374e7dd5a6859d9618733afcaa8d6a33e", ...}
```
The webserver is rate-limited, meaning that only a certain amount of request per minute is allowed (to prevent DoS attacks).
The json invoice can be used by other services, for example a service for tipping, donations, PoS devices, ...
Once the plugin is active you can run `lightning-cli help invoiceserver` to
learn about the command line API:
Commands: `start`/`stop`/`restart`/`status`.
In the file `.lightning/bitcoin/.env` the `port` can be set (default 8089).
##### Onion routing
Exposing the url using Onion routing is easy. Install tor and
add the service to `/etc/tor/torrc`
```
HiddenServiceDir /home/bitcoin/tor/request-invoice-service_v2/
HiddenServicePort 80 127.0.0.1:8809
```
and restart tor to create the url
```
$ systemctl stop tor && systemctl start tor
$ cat /home/bitcoin/tor/request-invoice-service_v2/hostname
fkfuvjrbj6cfqppq6xcgfwmp4p23wq2unzlnqmdi6ibqtg2aq7thp2qd.onion
```
Use tor browser to visit the url and create a invoice (and make a donation?).
http://fkfuvjrbj6cfqppq6xcgfwmp4p23wq2unzlnqmdi6ibqtg2aq7thp2qd.onion/invoice/1000/donation

View File

@@ -1,125 +0,0 @@
#!/usr/bin/env python3
from flask import Flask
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
from pathlib import Path
from pyln.client import Plugin
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from tornado.wsgi import WSGIContainer
import asyncio
import os
import threading
import uuid
plugin = Plugin()
app = Flask(__name__)
limiter = Limiter(
app,
key_func=get_remote_address,
default_limits=["2000 per day", "20 per minute"]
)
jobs = {}
@limiter.limit("20 per minute")
@app.route('/invoice/<int:amount>/<description>')
def getinvoice(amount, description):
global plugin
label = "ln-getinvoice-{}".format(uuid.uuid4())
invoice = plugin.rpc.invoice(int(amount)*1000, label, description)
return invoice
def worker(port):
asyncio.set_event_loop(asyncio.new_event_loop())
print('Starting server on port {port}'.format(
port=port
))
app.config['SECRET_KEY'] = os.getenv(
"REQUEST_INVOICE_SECRET",
default=uuid.uuid4())
http_server = HTTPServer(WSGIContainer(app))
http_server.listen(port)
IOLoop.instance().start()
def start_server(port):
if port in jobs:
raise ValueError("server already running on port {port}".format(port=port))
p = threading.Thread(
target=worker, args=(port,), daemon=True)
jobs[port] = p
p.start()
def stop_server(port):
if port in jobs:
jobs[port].terminate()
del jobs[port]
else:
raise ValueError("No server listening on port {port}".format(port=port))
@plugin.method('invoiceserver')
def invoiceserver(request, command="start"):
"""Starts a server for requestiong invoices.
A rate limited HTTP Server returns a invoice on the following GET request:
/invoice/<amount>/<description>
where amount is in Satoshis.
The plugin takes one of the following commands:
{start/stop/status/restart}.
"""
commands = {"start", "stop", "status","restart"}
port = os.getenv("FLASKPORT", default = 8809)
# if command unknown make start our default command
if command not in commands:
command = "start"
if command == "start":
try:
start_server(port)
return "Invoice server started successfully on port {}".format(port)
except Exception as e:
return "Error starting server on port {port}: {e}".format(
port=port, e=e
)
if command == "stop":
try:
stop_server(port)
return "Invoice server stopped on port {}".format(port)
except Exception as e:
return "Could not stop server on port {port}: {e}".format(
port=port, e=e
)
if command == "status":
if port in jobs:
return "Invoice server active on port {}".format(port)
else:
return "Invoice server not active."
if command == "restart":
stop_server(port)
start_server(port)
return "Invoice server restarted"
@plugin.init()
def init(options, configuration, plugin):
port = os.getenv("REQUEST_INVOICE_PORT", default = 8809)
start_server(port)
plugin.run()

View File

@@ -1,6 +0,0 @@
python-dotenv>=0.13.0
flask==1.1.4
flask-limiter
tornado
pyln-client
requests

View File

@@ -1,37 +0,0 @@
import os
from pyln.testing.fixtures import * # noqa: F401,F403
import requests
from subprocess import check_output
plugin_path = os.path.join(os.path.dirname(__file__), "requestinvoice.py")
def test_requestinvoice_starts(node_factory):
l1 = node_factory.get_node()
# Test dynamically
l1.rpc.plugin_start(plugin_path)
l1.rpc.plugin_stop(plugin_path)
l1.rpc.plugin_start(plugin_path)
l1.stop()
# Then statically
l1.daemon.opts["plugin"] = plugin_path
l1.start()
l1.daemon.logsearch_start = 0
l1.daemon.wait_for_log(r'Starting server on port 8809')
r = requests.get('http://localhost:8809/invoice/1000/text')
# check for hanging process if status_code = 500
assert(r.status_code == 200)
# returned valid invoice?
b = r.json()
assert(b['bolt11'][:8] == "lnbcrt10")
# test rate-limit
for i in range(0,20):
r = requests.get('http://localhost:8809/invoice/1000/text')
assert(r.status_code == 429)
assert("429 Too Many Requests" in r.text )