-
Notifications
You must be signed in to change notification settings - Fork 4
rewrite #10
base: master
Are you sure you want to change the base?
rewrite #10
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from flask import Flask | ||
from config import Config | ||
from flask_bootstrap import Bootstrap | ||
|
||
app = Flask(__name__) | ||
bootstrap = Bootstrap(app) | ||
app.config.from_object(Config) | ||
|
||
from app import routes | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from flask_wtf import FlaskForm | ||
from wtforms import StringField, SubmitField, DecimalRangeField | ||
from wtforms.validators import DataRequired | ||
|
||
class RequestForm(FlaskForm): | ||
amount = DecimalRangeField('Slide left/right to enter amount in sats', validators=[DataRequired()]) | ||
submit = SubmitField('Submit') | ||
|
||
class PayForm(FlaskForm): | ||
invoice = StringField('Enter BOLT11 string', validators=[DataRequired()]) | ||
submit = SubmitField('Submit') |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import os | ||
from app import app | ||
from flask import render_template, flash, redirect, url_for | ||
from app.forms import RequestForm, PayForm | ||
import random | ||
|
||
from flask_qrcode import QRcode | ||
from flask import Flask, render_template, request | ||
from lightning import LightningRpc | ||
from lightning.lightning import RpcError | ||
|
||
from json2html import * | ||
|
||
rpc = LightningRpc(os.environ['RPC_SOCKET']) | ||
connect_str = os.environ['CONNECT_INFO'] | ||
QRcode(app) | ||
|
||
|
||
@app.route('/pay', methods=['GET', 'POST']) | ||
def pay(): | ||
form = PayForm() | ||
pay_result = None | ||
if form.validate_on_submit(): | ||
try: | ||
result = rpc.pay(form.invoice.data) | ||
except RpcError as e: | ||
print(e.error["message"], e) | ||
flash('Error with LN Pay: {}'.format(e.error["message"])) | ||
return redirect('/index') | ||
flash('Invoice {}'.format(form.invoice.data)) | ||
pay_result = json2html.convert(json=result) | ||
return render_template('pay.html', title='Pay Invoice', form=form, pay_result=pay_result) | ||
|
||
|
||
@app.route('/request', methods=['GET', 'POST']) | ||
def request(): | ||
form = RequestForm() | ||
invoice = None | ||
if form.validate_on_submit(): | ||
amount = int(form.amount.data) | ||
try: | ||
invoice = rpc.invoice(amount, str(random.random()), str( | ||
int(random.random()*100)))['bolt11'] | ||
except RpcError as e: | ||
print(e.error["message"], e) | ||
flash('Error with LN Request: {}'.format(e.error["message"])) | ||
return redirect('/index') | ||
return render_template('request.html', title='Request Invoice', form=form, invoice=invoice) | ||
|
||
|
||
@app.route('/') | ||
@app.route('/index') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why make this also |
||
def index(): | ||
return render_template('index.html', title='Home', connect_str=connect_str) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
{% extends 'bootstrap/base.html' %} | ||
|
||
{% block title %} | ||
{% if title %}{{ title }} - Fedimint Faucet {% else %} Welcome to Fedimint{% endif %} | ||
{% endblock %} | ||
|
||
{% block navbar %} | ||
<link rel="stylesheet" href="{{ url_for('static', filename='main.css') }}"> | ||
<nav class="navbar navbar-default"> | ||
<div class="container"> | ||
<div class="navbar-header"> | ||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" | ||
data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> | ||
<span class="sr-only">Toggle navigation</span> | ||
<span class="icon-bar"></span> | ||
<span class="icon-bar"></span> | ||
<span class="icon-bar"></span> | ||
</button> | ||
<a class="navbar-brand" href="{{ url_for('index') }}">Fedimint</a> | ||
</div> | ||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> | ||
<ul class="nav navbar-nav"> | ||
<li><a href="{{ url_for('pay') }}">Pay</a></li> | ||
<li><a href="{{ url_for('request') }}">Request</a></li> | ||
</ul> | ||
</div> | ||
</div> | ||
</nav> | ||
{% endblock %} | ||
|
||
{% block content %} | ||
<div class="container"> | ||
{% with messages = get_flashed_messages() %} | ||
{% if messages %} | ||
{% for message in messages %} | ||
<div class="alert alert-info" role="alert">{{ message }}</div> | ||
{% endfor %} | ||
{% endif %} | ||
{% endwith %} | ||
|
||
{# application content needs to be provided in the app_content block #} | ||
{% block app_content %}{% endblock %} | ||
</div> | ||
{% endblock %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{% extends "base.html" %} | ||
|
||
{% block content %} | ||
<h1>Join Us!</h1> | ||
<img style="height: 200px; width: 200px;" src="{{ qrcode(connect_str) }}"> | ||
<br> | ||
<pre>{{ connect_str }}</pre> | ||
<br> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add some description back in about what this is and how to use it. |
||
<div> | ||
<p>Helpful Links</p> | ||
<ul> | ||
<li><a href="https://fedimint.org">Website</a></li> | ||
<li><a href="https://github.com/fedimint">Github</a></li> | ||
<li><a href="https://discord.gg/Aa2GCWAb">Discord</a></li> | ||
</ul> | ||
</div> | ||
{% endblock %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
{% extends "base.html" %} | ||
|
||
{% block content %} | ||
<meta> | ||
<script src="/static/qr-scanner.legacy.min.js"></script> | ||
</meta> | ||
<div id="video-container"> | ||
<video id="video"></video> | ||
</div> | ||
|
||
<button id="scan" type="submit">Scan</button> | ||
<button id="stop" type="submit">Stop</button> | ||
<h1>Paste Invoice</h1> | ||
|
||
<form action="" method="post" novalidate> | ||
{{ form.hidden_tag() }} | ||
<p> | ||
{{ form.invoice.label }}<br> | ||
{{ form.invoice(size=32) }}<br> | ||
{% for error in form.invoice.errors %} | ||
<span style="color: red;">[{{ error }}]</span> | ||
{% endfor %} | ||
</p> | ||
{% if pay_result %} | ||
<pre>{{ pay_result | safe }}</pre> | ||
{% endif %} | ||
|
||
<p>{{ form.submit() }}</p> | ||
</form> | ||
|
||
<script type="module"> | ||
var scan = document.getElementById('scan'); | ||
var stop = document.getElementById('stop'); | ||
var video = document.getElementById('video'); | ||
var invoice = document.getElementById('invoice'); | ||
var videoContainer = document.getElementById('video-container'); | ||
|
||
function stopCamera() { | ||
qrScanner.stop() | ||
stop.style.display = "none" | ||
scan.style.display = "block" | ||
videoContainer.style.display = "none" | ||
} | ||
|
||
scan.addEventListener('click', function () { | ||
qrScanner.start() | ||
stop.style.display = "block" | ||
scan.style.display = "none" | ||
videoContainer.style.display = "block" | ||
}) | ||
stop.addEventListener('click', stopCamera) | ||
|
||
const qrScanner = new QrScanner( | ||
video, | ||
result => { | ||
let parsed = result.replace("lightning:", "") | ||
invoice.value = parsed; | ||
stopCamera() | ||
}, | ||
); | ||
|
||
</script> | ||
|
||
<style> | ||
#video { | ||
width: 400px; | ||
} | ||
|
||
#video-container { | ||
display: none; | ||
} | ||
|
||
#stop { | ||
display: none; | ||
} | ||
</style> | ||
{% endblock %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
{% extends "base.html" %} | ||
{% import 'bootstrap/wtf.html' as wtf %} | ||
|
||
{% block content %} | ||
<h1>Request</h1> | ||
<hr> | ||
<script> | ||
function outputUpdate(amount) { | ||
document.querySelector('#selected-amount').value = amount; | ||
} | ||
</script> | ||
<form action="" method="post" novalidate> | ||
{{ form.hidden_tag() }} | ||
<p> | ||
{{ form.amount.label }}: | ||
{{ form.amount(min=0, max=1000, oninput="outputUpdate(value)") }} | ||
<output for="amount" id="selected-amount">{{ form.amount.data }}</output> | ||
{% for error in form.amount.errors %} | ||
<span style="color: red;">[{{ error }}]</span> | ||
{% endfor %} | ||
</p> | ||
<p>{{ form.submit() }}</p> | ||
</form> | ||
{% if invoice %} | ||
<a href="#" onClick="clip_div('copyme')">Copy Invoice</a> | ||
<div id="copyme">{{ invoice | safe }}</div> | ||
<script> | ||
function clip_text(a_string) { | ||
var input = document.createElement('input') | ||
input.id = "__copyText__"; | ||
input.value = a_string; // OOPS! document.getElementById(divId).innerText; | ||
document.body.appendChild(input); | ||
input.select(); | ||
document.execCommand("copy"); | ||
var txt = input.value | ||
input.remove() | ||
console.log("OK COPIED: '" + txt + "'") | ||
} | ||
function clip_div(divId) { | ||
return clip_text(document.getElementById(divId).innerText) | ||
} | ||
</script> | ||
{% endif %} | ||
|
||
{% endblock %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import os | ||
|
||
class Config(object): | ||
SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is needed because you aren't using the session at all |
||
RPC_SOCKET = os.environ.get('RPC_SOCKET') or 'you-will-never-guess' | ||
CONNECT_INFO = os.environ.get('CONNECT_INFO') or 'you-will-never-guess' | ||
Comment on lines
+5
to
+6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The app should probably fail if these aren't set. It just won't work. So let's not set defaults here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It does fail, the |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1 @@ | ||
import os | ||
import random | ||
import json | ||
|
||
from flask_qrcode import QRcode | ||
from flask import Flask, render_template, request | ||
from lightning import LightningRpc | ||
|
||
rpc = LightningRpc(os.environ['RPC_SOCKET']) | ||
connect_str = os.environ['CONNECT_STRING'] | ||
app = Flask(__name__) | ||
QRcode(app) | ||
|
||
@app.route('/', methods=['GET', 'POST']) | ||
def index(): | ||
invoice = None | ||
pay_result = None | ||
|
||
if request.method == 'POST': | ||
# create invoice | ||
if 'amount' in request.form: | ||
# convert to sats | ||
amount = int(request.form['amount']) * 1000 | ||
invoice = rpc.invoice(amount, str(random.random()), 'test')['bolt11'] | ||
# pay invoice | ||
if 'invoice' in request.form: | ||
pay_result = str(rpc.pay(request.form['invoice'])) | ||
|
||
return render_template('index.html', name='justin', | ||
invoice=invoice, pay_result=pay_result, connect_str=connect_str) | ||
|
||
from app import app | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be good to have something like the following here: if __name__ == "__main__":
app.run(port = 3000) so that it can be started without some weird other component I never got to run on Nix (I know you aren't supposed to, but don't want to waste more time on this). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was passing the port in as an option because the default port was conflicting with fedimint (5000) Yes I can take a look at the nix and get it to work. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An option would be great! This is just what I did so far. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,23 @@ | ||
Flask-QRcode | ||
Flask | ||
Jinja2 | ||
MarkupSafe | ||
Pillow | ||
Werkzeug | ||
click | ||
importlib-metadata | ||
itsdangerous | ||
pylightning | ||
qrcode | ||
zipp | ||
wheel | ||
autopep8==1.7.0 | ||
click==8.1.3 | ||
dominate==2.7.0 | ||
Flask==2.2.2 | ||
Flask-Bootstrap==3.3.7.1 | ||
Flask-DotEnv==0.1.2 | ||
Flask-QRcode==3.1.0 | ||
Flask-WTF==1.0.1 | ||
importlib-metadata==4.12.0 | ||
itsdangerous==2.1.2 | ||
Jinja2==3.1.2 | ||
json2html==1.3.0 | ||
MarkupSafe==2.1.1 | ||
Pillow==9.2.0 | ||
pycodestyle==2.9.1 | ||
pylightning==0.0.7.3 | ||
python-dotenv==0.21.0 | ||
qrcode==7.3.1 | ||
toml==0.10.2 | ||
visitor==0.1.3 | ||
Werkzeug==2.2.2 | ||
WTForms==3.0.1 | ||
zipp==3.8.1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should come from config instead