SatSale

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 658f291febba9796bcacaa510bcd475ebc850fc8
parent f0f520d17e65ed1dfccc44d6002a2fcde5313ffa
Author: NicholasFarrow <nicholas.w.farrow@gmail.com>
Date:   Thu, 17 Dec 2020 01:30:36 +1100

Improved jQuery, probably need to switch to flask-socketio

Diffstat:
Mmain.py | 35+++++------------------------------
Mpay/bitcoind.py | 13++++++-------
Mserver.py | 75++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Mtemplates/payment.html | 51++++++++++++++++++++++++++++++++++++++++++---------
4 files changed, 119 insertions(+), 55 deletions(-)

diff --git a/main.py b/main.py @@ -5,47 +5,22 @@ from pay import bitcoind import time import subprocess + # If tunnel is required (might make things easier) try: if config.tunnel_host is not None: - command = ['ssh', config.tunnel_host, '-L', '{}:localhost:{}'.format(config.rpcport, config.rpcport), '-q'] + command = ['ssh', config.tunnel_host, '-q', '-N', '-L', '{}:localhost:{}'.format(config.rpcport, config.rpcport)] print("Opening tunnel to {}.".format(' '.join(command))) - tunnel_proc = subprocess.Popen(['ssh', config.tunnel_host, '-L', '{}:localhost:{}'.format(config.rpcport, config.rpcport)]) + tunnel_proc = subprocess.Popen(command) else: tunnel_proc = None except Exception: tunnel_proc = None pass + def close_tunnel(): if tunnel_proc is not None: tunnel_proc.kill() - -def payment(amount, currency, label): - #inv = invoice.invoice(1.8, "USD", "test invoice232") - inv = invoice.invoice(amount, "USD", "test invoice232") - payment = bitcoind.btcd() - payment.load_invoice(inv) - payment.get_address() - - start_time = time.time() - while time.time() - start_time < config.payment_timeout: - conf_paid, unconf_paid = payment.check_payment() - print(conf_paid, unconf_paid) - - if conf_paid > payment.value: - print("Invoice {} paid! {} BTC.".format(payment.label, conf_paid)) - payment.paid = True - break - else: - time.sleep(15) - else: - print("Invoice {} expired.".format(payment.label)) - - if payment.paid: - print("Returning paid to site.") - else: - print("Reload page, etc. need to create new invoice") - + print("Tunnel closed.") return - diff --git a/pay/bitcoind.py b/pay/bitcoind.py @@ -4,20 +4,20 @@ import subprocess class btcd: def __init__(self): from bitcoinrpc.authproxy import AuthServiceProxy - + connection_str = "http://{}:{}@{}:{}".format(config.username, config.password, config.host, config.rpcport) print("Attempting to connect to {}.".format(connection_str)) try: self.rpc = AuthServiceProxy(connection_str) - info = self.rpc.getblockchaininfo() - info = self.rpc.help() - + # info = self.rpc.getblockchaininfo() + # info = self.rpc.help() + print("Successfully contacted bitcoind.") print("-"*10) print(info) print("-"*10) - + except Exception as e: print(e) @@ -44,5 +44,4 @@ class btcd: def get_address(self): self.address = self.rpc.getnewaddress(self.label) - return - + return diff --git a/server.py b/server.py @@ -1,7 +1,11 @@ from flask import Flask, request, url_for, jsonify, render_template from markupsafe import escape +import time import main +import config +import invoice +from pay import bitcoind app = Flask(__name__) @@ -9,32 +13,85 @@ app = Flask(__name__) def index(): return render_template('payment.html') + +app.route('/invoice', methods=['GET']) +def invoice(): + amount = request.values.get('amount') + + try: + amount = float(amount) + except: + print("Amount could not be interpreted as float {}".format(amount)) + amount = None + return + + payment = create_invoice(amount, currency, label) + + + @app.route('/pay', methods=['GET', 'POST']) def pay(): + start_time = time.time() + if True: #request.method == 'POST': print("CALLING BITCOIND MAIN") - + amount = request.values.get('amount') try: amount = float(amount) except: - print("Amount could not be interpreted as float") + print("Amount could not be interpreted as float {}".format(amount)) amount = None return if (isinstance(amount, float) and amount >= 0): print("Calling main payment function for {}".format(amount)) - main.payment(amount, "USD", "wee") - + + if payment(amount, "USD", "wee"): + print("PAID") + return jsonify(paid=True) + else: - return "BROKE" - - print("Passing amount : {}".format(amount)) - return jsonify(amount=amount) + return jsonify(paid=False) else: - return "INVALID PAYMENT POST" + return jsonify(paid=False) + + +def create_invoice(amount, currency, label): + inv = invoice.invoice(amount, currency, label) + + payment = bitcoind.btcd() + payment.load_invoice(inv) + payment.get_address() + return payment + + +def payment(amount, currency, label): + payment = create_invoice(amount, currency, label) + + start_time = time.time() + while time.time() - start_time < config.payment_timeout: + conf_paid, unconf_paid = payment.check_payment() + print(conf_paid, unconf_paid) + + if conf_paid > payment.value: + print("Invoice {} paid! {} BTC.".format(payment.label, conf_paid)) + payment.paid = True + return True + else: + time.sleep(15) + else: + print("Invoice {} expired.".format(payment.label)) + + if payment.paid: + print("Returning paid to site.") + else: + print("Reload page, etc. need to create new invoice") + + return False + #with app.test_client() as c: # resp = c.post('/pay', data=dict(amount=69)) diff --git a/templates/payment.html b/templates/payment.html @@ -13,16 +13,49 @@ <script type=text/javascript> $(function() { $('a#calculate').bind('click', function() { - $.getJSON($SCRIPT_ROOT + '/pay', { - amount: $('input[name="amount"]').val() - }, function(data) { - $("#result").text(data.result); - }); - return false; - }); - }); + + + // Check for payment + // If paid, show confirmation message + // If unpaid, wait x seconds before checking again. + // Continue counting down until an expiry, this expiry will be refreshed + // in the javascript to remain in sync. + // + setInterval( + $.ajax({ + url: '/pay', + type: 'get', + data: {'amount' : $('input[name="amount"]').val(), + 'unique_id' : uuidv4()}, + success: function(response) { + console.log(response); + $("#result").html(response["paid"]); + }, + error: function(error) { + console.log(error); + }}), + + sleep(5)); + + }; + })}) + + // + // + // $.ajax({ + // url: "$SCRIPT_ROOT + '/pay'", + // type: + // { + // amount: $('input[name="amount"]').val() + // }, function(data) { + // $("#result").text(data.result); + // }); + // return false; + // }); + // }); </script> -<h1>jQuery Example</h1> + +<h1>Pay {{ amount }}</h1> <p><input type=text size=5 name=amount> + <span id=result>?</span> <p><a href=# id=calculate>calculate server side</a>