Initial push

This commit is contained in:
cryptosharks131 2021-03-13 18:06:59 -05:00
commit 94be0fcdeb
15 changed files with 307 additions and 0 deletions

7
.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
__pycache__
db.sqlite3
lndg/settings.py
gui/migrations
gui/rpc_pb2.py
gui/rpc_pb2_grpc.py

0
gui/__init__.py Normal file
View file

3
gui/admin.py Normal file
View file

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

5
gui/apps.py Normal file
View file

@ -0,0 +1,5 @@
from django.apps import AppConfig
class GuiConfig(AppConfig):
name = 'gui'

3
gui/models.py Normal file
View file

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

18
gui/static/style.css Normal file
View file

@ -0,0 +1,18 @@
html {
font-family: helvetica, arial, sans-serif;
}
table {
table-layout: fixed;
width: 100%;
border-collapse: collapse;
border: 3px solid black;
}
th, td {
padding: 20px;
}
tbody td {
text-align: center;
}

116
gui/templates/home.html Normal file
View file

@ -0,0 +1,116 @@
<!DOCTYPE html>
<html>
<style>
</style>
<head>
{% load static %}
{% load humanize %}
<link href="{% static 'style.css' %}" rel="stylesheet" type="text/css">
</head>
<body>
<br></br>
<h1>Overview</h1>
<br></br>
<h2>Total Wallet Balance: {{ balances.total_balance|intcomma }}</h2>
<br></br>
<h2>Confirmed Wallet Balance: {{ balances.confirmed_balance|intcomma }}</h2>
<br></br>
<h2>Total Fees Paid: {{ paid|intcomma }}</h2>
<br></br>
<h2>Total Fees Earned: {{ earned|intcomma }}</h2>
<br></br>
<br></br>
<h2>Payments Sent</h2>
<table>
<tr>
<th>Timestamp</th>
<th>Hash</th>
<th>Value</th>
<th>Fee Paid</th>
<th>Status</th>
</tr>
{% for payment in payments %}
<tr>
<td>{{ payment.creation_date }}</td>
<td>{{ payment.payment_hash }}</td>
<td>{{ payment.value|intcomma }}</td>
<td>{{ payment.fee }}</td>
<td>{% if payment.status == 2 %}Success{% elif payment.status == 1 %}Payment Status=1 (unknown){% else %}Error{% endif %}</td>
</tr>
{% endfor %}
</table>
<br></br>
<br></br>
<h2>Payments Routed</h2>
<table>
<tr>
<th>Timestamp</th>
<th>Channel In</th>
<th>Channel Out</th>
<th>Amount In</th>
<th>Amount Out</th>
<th>Fees Earned</th>
</tr>
{% for forward in forwards %}
<tr>
<td>{{ forward.timestamp }}</td>
<td>{{ forward.chan_id_in }}</td>
<td>{{ forward.chan_id_out }}</td>
<td>{{ forward.amt_in|intcomma }}</td>
<td>{{ forward.amt_out|intcomma }}</td>
<td>{{ forward.fee_msat }}</td>
</tr>
{% endfor %}
</table>
<br></br>
<br></br>
<h2>Active Channels</h2>
<table>
<tr>
<th width=30%>Peer PubKey</th>
<th>Channel Alias</th>
<th>Channel ID</th>
<th>Capacity</th>
<th>Local Balance</th>
<th>Remote Balance</th>
<th>Initiated By Me</th>
</tr>
{% for channel in active_channels %}
<tr>
<td>{{ channel.remote_pubkey }}</td>
<td>{{ channel.alias }}</td>
<td>{{ channel.chan_id }}</td>
<td>{{ channel.capacity|intcomma }}</td>
<td>{{ channel.local_balance|intcomma }}</td>
<td>{{ channel.remote_balance|intcomma }}</td>
<td>{{ channel.initiator }}</td>
</tr>
{% endfor %}
</table>
<br></br>
<br></br>
<h2>Inactive Channels</h2>
<table>
<tr>
<th width=30%>Peer PubKey</th>
<th>Channel Alias</th>
<th>Channel ID</th>
<th>Capacity</th>
<th>Local Balance</th>
<th>Remote Balance</th>
<th>Initiated By Me</th>
</tr>
{% for channel in inactive_channels %}
<tr>
<td>{{ channel.remote_pubkey }}</td>
<td>{{ channel.alias }}</td>
<td>{{ channel.chan_id }}</td>
<td>{{ channel.capacity|intcomma }}</td>
<td>{{ channel.local_balance|intcomma }}</td>
<td>{{ channel.remote_balance|intcomma }}</td>
<td>{{ channel.initiator }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>

3
gui/tests.py Normal file
View file

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

7
gui/urls.py Normal file
View file

@ -0,0 +1,7 @@
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
]

69
gui/views.py Normal file
View file

@ -0,0 +1,69 @@
from django.shortcuts import render, redirect
from . import rpc_pb2 as ln
from . import rpc_pb2_grpc as lnrpc
import grpc
import os
import codecs
# Create your views here.
def home(request):
if request.method == 'GET':
with open(os.path.expanduser('admin.macaroon'), 'rb') as f:
macaroon_bytes = f.read()
macaroon = codecs.encode(macaroon_bytes, 'hex')
def metadata_callback(context, callback):
callback([('macaroon', macaroon)], None)
os.environ["GRPC_SSL_CIPHER_SUITES"] = 'HIGH+ECDSA'
cert = open(os.path.expanduser('tls.cert'), 'rb').read()
cert_creds = grpc.ssl_channel_credentials(cert)
auth_creds = grpc.metadata_call_credentials(metadata_callback)
creds = grpc.composite_channel_credentials(cert_creds, auth_creds)
channel = grpc.secure_channel('localhost:10009', creds)
stub = lnrpc.LightningStub(channel)
balances = stub.WalletBalance(ln.WalletBalanceRequest())
payments = stub.ListPayments(ln.ListPaymentsRequest(include_incomplete=True)).payments
total_paid = 0
for payment in payments:
total_paid += payment.fee
forwards = stub.ForwardingHistory(ln.ForwardingHistoryRequest(start_time=1614556800)).forwarding_events
total_earned = 0
for forward in forwards:
total_earned += forward.fee_msat/1000
active_channels = stub.ListChannels(ln.ListChannelsRequest(active_only=True)).channels
detailed_active_channels = []
for channel in active_channels:
detailed_channel = {}
alias = stub.GetNodeInfo(ln.NodeInfoRequest(pub_key=channel.remote_pubkey)).node.alias
detailed_channel['remote_pubkey'] = channel.remote_pubkey
detailed_channel['chan_id'] = channel.chan_id
detailed_channel['capacity'] = channel.capacity
detailed_channel['local_balance'] = channel.local_balance
detailed_channel['remote_balance'] = channel.remote_balance
detailed_channel['initiator'] = channel.initiator
detailed_channel['alias'] = alias
detailed_active_channels.append(detailed_channel)
inactive_channels = stub.ListChannels(ln.ListChannelsRequest(inactive_only=True)).channels
detailed_inactive_channels = []
for channel in inactive_channels:
detailed_channel = {}
alias = stub.GetNodeInfo(ln.NodeInfoRequest(pub_key=channel.remote_pubkey)).node.alias
detailed_channel['remote_pubkey'] = channel.remote_pubkey
detailed_channel['chan_id'] = channel.chan_id
detailed_channel['capacity'] = channel.capacity
detailed_channel['local_balance'] = channel.local_balance
detailed_channel['remote_balance'] = channel.remote_balance
detailed_channel['initiator'] = channel.initiator
detailed_channel['alias'] = alias
detailed_inactive_channels.append(detailed_channel)
context = {
'balances': balances,
'payments': payments,
'paid': total_paid,
'forwards': forwards,
'earned': round(total_earned, 3),
'active_channels': detailed_active_channels,
'inactive_channels': detailed_inactive_channels
}
return render(request, 'home.html', context)
else:
return redirect('home')

0
lndg/__init__.py Normal file
View file

16
lndg/asgi.py Normal file
View file

@ -0,0 +1,16 @@
"""
ASGI config for lndg project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'lndg.settings')
application = get_asgi_application()

22
lndg/urls.py Normal file
View file

@ -0,0 +1,22 @@
"""lndg URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('gui.urls')),
]

16
lndg/wsgi.py Normal file
View file

@ -0,0 +1,16 @@
"""
WSGI config for lndg project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'lndg.settings')
application = get_wsgi_application()

22
manage.py Normal file
View file

@ -0,0 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'lndg.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()