Coder Social home page Coder Social logo

djmelik / lndash Goto Github PK

View Code? Open in Web Editor NEW
118.0 9.0 16.0 1.91 MB

A simple web dashboard for lnd.

Home Page: https://lightninglayer.com

License: GNU General Public License v3.0

Python 1.98% CSS 50.46% JavaScript 46.47% HTML 1.08% Makefile 0.01% Nix 0.01% Dockerfile 0.01%

lndash's Introduction

lndash

Build Status

lndash is a simple read-only web dashboard for lnd - Lightning Network Daemon

Features

  • Peer view
  • Channel view
  • Forwarding Events (routed payments) view
  • Looking Glass Tool (route/path lookup)
  • Lightning Network Graph

Installation

This guide was written on a Debian system.

  1. Clone lndash repository and enter the project directory:
git clone https://github.com/djmelik/lndash.git
cd lndash
  1. Install required dependencies for virtualenv, set it up and activate:
sudo apt-get install python3-pip python3-virtualenv virtualenv
virtualenv -p python3 venv
source venv/bin/activate

Make sure you have installed Python 3 virtualenv, not Python 2 as this is not supported.

  1. Install python libs & dependencies into running virtualenv:
pip install -r requirements.txt
  1. Copy the tls certificate and readonly macaroon from lnd to lndash config directory:
cp ~/.lnd/tls.cert config/tls.cert
cp ~/.lnd/data/chain/bitcoin/mainnet/readonly.macaroon config/readonly.macaroon
  1. (Optional) If lnd is installed on a remote host, define an environment variable pointing to that host:
export LNDASH_LND_SERVER="127.0.0.1:10009"
  1. Run the application:
gunicorn main:app

If you want gunicorn to listen on all interfaces and/or change the port, run the application using the following:

gunicorn main:app -b 0.0.0.0:8080

Docker

Four things need to be configured on the host to run the lndash docker container:

  1. The path to the TLS certificate (ex. $HOME/.lnd/tls.cert)
  2. The path to the readonly macaroon (ex. $HOME/.lnd/data/chain/bitcoin/mainnet/readonly.macaroon)
  3. The port on which the web app should listen (ex. 8000)
  4. The LND server's RPC address (ex. 192.168.1.2:10009)

The easy way

Run the following command in your terminal (replace all local paths with your own):

docker run -d --rm \
  -v=$HOME/.lnd/tls.cert:/usr/src/app/config/tls.cert \
  -v=$HOME/.lnd/data/chain/bitcoin/mainnet/readonly.macaroon:/usr/src/app/config/readonly.macaroon \
  -p 8000:8000 \
  -e LNDASH_LND_SERVER="192.168.1.2:10009" \
  djmelik/lndash:latest

And open http://localhost:8000 in your browser.

Protip: You can skip -d in the command above to get all the logs in your terminal.

The manual way

Build the docker container

Run the following command in the lndash directory:

docker build -t lndash:latest .

This will build the docker container and give it the tag lndash.

Run the built container

Run the following command in your terminal:

docker run -d --restart \
  -v=$HOME/.lnd/tls.cert:/usr/src/app/config/tls.cert \
  -v=$HOME/.lnd/data/chain/bitcoin/mainnet/readonly.macaroon:/usr/src/app/config/readonly.macaroon \
  -p 8000:8000 \
  -e LNDASH_LND_SERVER="192.168.1.2:10009" \
  lndash:latest

The above command line assumes tls.cert and readonly.macaroon are stored at these locations and that the LND server is available on port 10009 at IP address 192.168.1.2. It makes the lndash server available on port 8000. Change these values as needed.

Now you can open http://localhost:8000 in your browser.

Nginx reverse proxy

You can set up an nginx reverse proxy and publicly expose your lndash instance.

Note: need to write these instructions.

lndash's People

Contributors

djmelik avatar hpbock avatar lra avatar meedamian avatar opinionatedgeek avatar pierrerochard avatar prusnak avatar tiero avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lndash's Issues

Map view doesn't seem to work

Hey, Nice project!

The map view doesn't seem to work.

There's few errors in the console:

Uncaught ReferenceError: jQuery is not defined semantic.min.js:11

And tree.js complaining about a shader error:

3d-force-graph.min.js:2 THREE.WebGLProgram: shader error: 0 35715 false gl.getProgramInfoLog

Idea: Node well-connectedness index

Let's introduce the "Node well-connectedness index" - a scalar value that indicates how well-connected a node is.

WCI could be computed as this pseudocode:

wci = 0
for node in all_nodes_in_the_network:
    wci += how_many_networks_hops_are_there_between_me_and(node)

We'd need to add channel capacities into the computation, because apparently if one channel is used as a network hop to reach lots of nodes, this is not optimal.

Once we establish the WCI, we can do to do the following:

  1. identify top 10 nodes that would be the best to open channel with to have the best WCI increase
  2. identify top 10 channels which we can close with the lowest WCI decrease

The WCI index and top 10 nodes/channels from above should be a separate tab, as this computation might take some time (we are iterating all nodes in the network, not just the ones we have open channels to).

Proxying LNDash with Nginx in server subpath

I tried to setup lndash behind Nginx reverse-proxy. However I could not identify reasonable way to run it from subpath, i.e. having lndash app running at server.mydomain.net/lndash.

Gunicorn docs provide nginx configuration for standalone server.

I found this hack, but it requires passing the main app object through a kind of application proxy that would require main.py changes.

Then, e.g. Django handles this situation using settings parameter.

This issue is meant as a place to think of if such enhancement make sense and what could be the best approach. Personally I see this as a pretty common requirement e.g. in a situation when node operator has some public site with node information but wants to keep full lndash under some sort of auth.

UI is broken on mobile

UI is not responsive, so it is broken on mobile.

I guess this is low priority, but I am putting it here so maybe someone from the community can fine-tune this to make this work correctly.

Mouseover explainers of "base fee", "fee rate", "min HTLC" and "timelock delta" (in the "channels" tab)

Referencing the "channel" section (https://lightninglayer.com/channels):

It would be cool if there was a brief explanation popping up when mouse hovering (or clicking) over the fields mentioned in the title ("base fee" etc), especially that they already look like they're activating (becoming grey) when hovered over and it just feels like there oughta be some additional info/menu :)

I think it also would contribute to a better understanding of how channel management works, as there is not much documentation around at this moment (although perhaps most people interested in running the dashboard are already familiar with those terms?).

Push image to Docker Hub

Since Dockerfile is already provided, why not also push it to Docker Hub to make using it easier?

Note that both Docker Hub and Travis are able to build and push it automatically on a push to master or git tag.

edge not found error on GET /channels

It breaks at line 129 in main.py, when calling the /channels endpoint

Here the tracelog:

ERROR in app: Exception on /channels [GET]
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/usr/local/lib/python2.7/site-packages/flask_caching/__init__.py", line 366, in decorated_function
    rv = f(*args, **kwargs)
  File "/Users/tiero/projects/experiment/bitcoin/lndash/main.py", line 129, in channels
    chan_info = stub.GetChanInfo(ln.ChanInfoRequest(chan_id=channel.chan_id))
  File "/usr/local/lib/python2.7/site-packages/grpc/_channel.py", line 547, in __call__
    return _end_unary_response_blocking(state, call, False, None)
  File "/usr/local/lib/python2.7/site-packages/grpc/_channel.py", line 466, in _end_unary_response_blocking
    raise _Rendezvous(state, None, None, deadline)
_Rendezvous: <_Rendezvous of RPC that terminated with:
	status = StatusCode.UNKNOWN
	details = "edge not found"
	debug_error_string = "{"created":"@1546905157.687484000","description":"Error received from peer","file":"src/core/lib/surface/call.cc","file_line":1036,"grpc_message":"edge not found","grpc_status":2}"
>

Improve query page

The query page is more or less a simple shell at the moment.

We need to improve the page. At the moment, I'd like to do the following:

  1. Add additional information when returning routes, eg. source, destination, amount.
  2. Add an input box for user to enter the number of paths to return.
  3. Add a graph showing paths (/w hops) from source to destination for visualization.
  4. Translate node public keys to aliases so that it is more intelligible.

Open to all suggestions and recommendations.

Cannot start

Following the instruction on Fedora Linux, I get:

(venv) โžœ  lndash git:(master) gunicorn main:app -b 0.0.0.0:8080
[2019-01-27 17:28:28 +0000] [9890] [INFO] Starting gunicorn 19.9.0
[2019-01-27 17:28:28 +0000] [9890] [INFO] Listening at: http://0.0.0.0:8080 (9890)
[2019-01-27 17:28:28 +0000] [9890] [INFO] Using worker: sync
[2019-01-27 17:28:28 +0000] [9894] [INFO] Booting worker with pid: 9894
[2019-01-27 17:28:30 +0000] [9894] [ERROR] Exception in worker process
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker
    worker.init_process()
  File "/usr/lib/python2.7/site-packages/gunicorn/workers/base.py", line 129, in init_process
    self.load_wsgi()
  File "/usr/lib/python2.7/site-packages/gunicorn/workers/base.py", line 138, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/usr/lib/python2.7/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/usr/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 52, in load
    return self.load_wsgiapp()
  File "/usr/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 41, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/usr/lib/python2.7/site-packages/gunicorn/util.py", line 350, in import_app
    __import__(module)
  File "/home/bitcoin/lndash/main.py", line 4, in <module>
    import views
  File "/home/bitcoin/lndash/views.py", line 17, in <module>
    macaroon = open(config.macaroon_path, "rb").read().hex()
AttributeError: 'str' object has no attribute 'hex'
[2019-01-27 17:28:30 +0000] [9894] [INFO] Worker exiting (pid: 9894)
[2019-01-27 17:28:30 +0000] [9890] [INFO] Shutting down: Master
[2019-01-27 17:28:30 +0000] [9890] [INFO] Reason: Worker failed to boot.

Cannot copy readonly.macaroon

I am trying to install lndash and was following the instructions in README.md. But when I got to this step:

cp ~/.lnd/data/chain/bitcoin/mainnet/readonly.macaroon config/readonly.macaroon

bash replied:
cp: cannot stat '/home/admin/.lnd/data/chain/bitcoin/mainnet/readonly.macaroon': No such file or directory

Where else could this file be? I have LND up and running on mainnet.

Thanks.

Failed building wheel for Pillow

Hello,
I m trying to set up the dashboard on my lnd raspibolt.
When I execute pip install -r requirements.txt
I end up with the following error message :
Failed building wheel for Pillow * and then, after some lines
Command "/home/admin/lndash/venv/bin/python2 -u -c "import setuptools, tokenize;file='/tmp/pip-install-l_R2Aw/Pillow/setup.py';f=getattr(tokenize, 'open', open)(file);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, file, 'exec'))" install --record /tmp/pip-record-HfnMfI/install-record.txt --single-version-externally-managed --compile --install-headers /home/admin/lndash/venv/include/site/python2.7/Pillow" failed with error code 1 in /tmp/pip-install-l_R2Aw/Pillow/

I tried to go until the end of the tutorial hoping that was not a big deal but I got that :
[2019-01-06 14:38:37 +0000] [21155] [INFO] Starting gunicorn 19.9.0
[2019-01-06 14:38:37 +0000] [21155] [INFO] Listening at: http://127.0.0.1:8000 (21155)
[2019-01-06 14:38:37 +0000] [21155] [INFO] Using worker: sync
[2019-01-06 14:38:37 +0000] [21167] [INFO] Booting worker with pid: 21167
[2019-01-06 14:38:37 +0000] [21167] [ERROR] Exception in worker process
Traceback (most recent call last):
File "/home/admin/lndash/venv/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker
worker.init_process()
File "/home/admin/lndash/venv/local/lib/python2.7/site-packages/gunicorn/workers/base.py", line 129, in init_process
self.load_wsgi()
File "/home/admin/lndash/venv/local/lib/python2.7/site-packages/gunicorn/workers/base.py", line 138, in load_wsgi
self.wsgi = self.app.wsgi()
File "/home/admin/lndash/venv/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 67, in wsgi
self.callable = self.load()
File "/home/admin/lndash/venv/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 52, in load
return self.load_wsgiapp()
File "/home/admin/lndash/venv/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 41, in load_wsgiapp
return util.import_app(self.app_uri)
File "/home/admin/lndash/venv/local/lib/python2.7/site-packages/gunicorn/util.py", line 350, in import_app
import(module)
File "/home/admin/lndash/main.py", line 2, in
import libs.rpc_pb2 as ln
File "/home/admin/lndash/libs/rpc_pb2.py", line 6, in
from google.protobuf.internal import enum_type_wrapper
ImportError: No module named google.protobuf.internal
[2019-01-06 14:38:37 +0000] [21167] [INFO] Worker exiting (pid: 21167)
[2019-01-06 14:38:37 +0000] [21155] [INFO] Shutting down: Master
[2019-01-06 14:38:37 +0000] [21155] [INFO] Reason: Worker failed to boot.

Any ideas ?

Thank you

Cannot open Events page, probably due to not having any inbound events?

First off, love the dashboard! Nice to have a simple way to locally visualize my node. I did run into one issue though -- when I try to go to the "Events" tab, it fails with a 500 every time. I'm wondering if it's because I have never routed payments through my node, but merely used it for outbound payments so far? This is the error I get each time:

Traceback (most recent call last):
  File "/home/xmr/build/lndash/venv/lib/python2.7/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/xmr/build/lndash/venv/lib/python2.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/xmr/build/lndash/venv/lib/python2.7/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/xmr/build/lndash/venv/lib/python2.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/xmr/build/lndash/venv/lib/python2.7/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/xmr/build/lndash/main.py", line 274, in events
    return render_template('events.html', **content)
  File "/home/xmr/build/lndash/venv/lib/python2.7/site-packages/flask/templating.py", line 135, in render_template
    context, ctx.app)
  File "/home/xmr/build/lndash/venv/lib/python2.7/site-packages/flask/templating.py", line 117, in _render
    rv = template.render(context)
  File "/home/xmr/build/lndash/venv/lib/python2.7/site-packages/jinja2/environment.py", line 1008, in render
    return self.environment.handle_exception(exc_info, True)
  File "/home/xmr/build/lndash/venv/lib/python2.7/site-packages/jinja2/environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/xmr/build/lndash/templates/events.html", line 2, in top-level template code
    {% extends "layout.html" %}
  File "/home/xmr/build/lndash/templates/layout.html", line 45, in top-level template code
    {% block body %}
  File "/home/xmr/build/lndash/templates/events.html", line 73, in block "body"
    range: [0, {{ events_stats.maximum.events * 2 }}],
UndefinedError: 'int object' has no attribute 'events'

channel is in state TRANSIENT_FAILURE

I receive this error in the log

lnd-web_1   | [2019-01-07 19:50:34,402] ERROR in app: Exception on / [GET]
lnd-web_1   | Traceback (most recent call last):
lnd-web_1   |   File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 2292, in wsgi_app
lnd-web_1   |     response = self.full_dispatch_request()
lnd-web_1   |   File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
lnd-web_1   |     rv = self.handle_user_exception(e)
lnd-web_1   |   File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1718, in handle_user_exception
lnd-web_1   |     reraise(exc_type, exc_value, tb)
lnd-web_1   |   File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
lnd-web_1   |     rv = self.dispatch_request()
lnd-web_1   |   File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1799, in dispatch_request
lnd-web_1   |     return self.view_functions[rule.endpoint](**req.view_args)
lnd-web_1   |   File "/usr/local/lib/python2.7/site-packages/flask_caching/__init__.py", line 366, in decorated_function
lnd-web_1   |     rv = f(*args, **kwargs)
lnd-web_1   |   File "/opt/lndash/main.py", line 63, in home
lnd-web_1   |     node_info = stub.GetInfo(ln.GetInfoRequest())
lnd-web_1   |   File "/usr/local/lib/python2.7/site-packages/grpc/_channel.py", line 547, in __call__
lnd-web_1   |     return _end_unary_response_blocking(state, call, False, None)
lnd-web_1   |   File "/usr/local/lib/python2.7/site-packages/grpc/_channel.py", line 466, in _end_unary_response_blocking
lnd-web_1   |     raise _Rendezvous(state, None, None, deadline)
lnd-web_1   | _Rendezvous: <_Rendezvous of RPC that terminated with:
lnd-web_1   | 	status = StatusCode.UNAVAILABLE
lnd-web_1   | 	details = "channel is in state TRANSIENT_FAILURE"
lnd-web_1   | 	debug_error_string = "{"created":"@1546890634.401809686","description":"channel is in state TRANSIENT_FAILURE","file":"src/core/ext/filters/client_channel/client_channel.cc","file_line":2918,"grpc_status":14}"
lnd-web_1   | >

Any plans for python3?

I no longer use python2 on any my systems. It would be awesome to have native support for python3 in lndash.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.