SatSale

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

commit 81d2a308c23cb4b81be32a071dc320a0ee765741
parent f217a4fa41bf0d686dff664c429dfdf3e93c8a76
Author: NicholasFarrow <nicholas.w.farrow@gmail.com>
Date:   Tue, 22 Dec 2020 20:50:57 +1100

Refactored code, improved invoice loading, status and response verbosity, and decreased code repetitiveness

Diffstat:
Mdemo.py | 90++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Minvoice/__init__.py | 10++++++++++
Mpay/bitcoind.py | 10+++-------
Mserver.py | 11+++++------
Mtemplates/index.html | 8++++----
5 files changed, 81 insertions(+), 48 deletions(-)

diff --git a/demo.py b/demo.py @@ -8,7 +8,6 @@ import config import invoice from pay import bitcoind - async_mode = None app = Flask(__name__) app.config['SECRET_KEY'] = 'secret!' @@ -16,69 +15,98 @@ socket_ = SocketIO(app, async_mode=async_mode) # thread = None # thread_lock = Lock() - @app.route('/') def index(): return render_template('index.html', async_mode=socket_.async_mode) @socket_.on('initialise', namespace='/pay') def test_message(message): - emit('my_response', {'time_left': config.payment_timeout, 'response': message['data']}) + emit('payresponse', {'time_left': -1, 'response': message['data']}) @socket_.on('payment', namespace='/pay') -def make_payment(message): - print("Requesting payment for {}".format(message['amount'])) +def make_payment(payload): + print("Requesting payment for {}".format(payload['amount'])) # Check the amount is a float - amount = message['amount'] + amount = payload['amount'] try: amount = float(amount) except: - emit('my_response', {'status' : '', 'address' : '', 'amount' : '', 'time_left': 0, 'response': "Invalid payment mount.".format(unconf_paid)}) + # emit('payresponse', {'status' : '', 'address' : '', 'amount' : '', 'time_left': 0, 'response': "Invalid payment mount.".format(unconf_paid)}) amount = None return # Validate amount is a positive float if not (isinstance(amount, float) and amount >= 0): - emit('my_response', {'status' : '', 'address' : '', 'amount' : '', 'time_left': 0, 'response': "Invalid payment mount.".format(unconf_paid)}) + # emit('payresponse', {'status' : '', 'address' : '', 'amount' : '', 'time_left': 0, 'response': "Invalid payment mount.".format(unconf_paid)}) amount = None return + # Need to check this is safe! + label = payload['label'] + # Initialise this payment - payment = create_invoice(amount, "USD", "wee") - emit('my_response', {'status' : 'Awaiting payment.', 'address' : payment.address, 'amount' : payment.value, 'time_left': config.payment_timeout, 'response' : 'Awaiting payment.'}) + payment = create_invoice(amount, "USD", label) + + make_payment(payment) + + if payment.paid: + payment.status = 'Payment finalised.' + payment.response = 'Payment finalised.' + update_status(payment) + + ### DO SOMETHING + # Depends on config + # Get redirected? + # Nothing? + # Run custom script? + +def update_status(payment, console_status=True): + if console_status: + print(payment.status) + + emit('payresponse', {'status' : payment.status, 'address' : payment.address, 'amount' : payment.value, 'time_left': payment.time_left, 'response': payment.response}) + return + +def make_payment(payment): + payment.status = 'Awaiting payment.' + payment.response = 'Awaiting payment.' + update_status(payment) # Track start_time for payment timeouts - start_time = time.time() - while (time_left := config.payment_timeout - (time.time() - start_time)) > 0: - conf_paid, unconf_paid = payment.check_payment() - print(conf_paid, unconf_paid) + payment.start_time = time.time() + while (time_left := config.payment_timeout - (time.time() - payment.start_time)) > 0: + payment.time_left = time_left + payment.confirmed_paid, payment.unconfirmed_paid = payment.check_payment() - if conf_paid > payment.value: - print("Invoice {} paid! {} BTC.".format(payment.label, conf_paid)) + if payment.confirmed_paid > payment.value: payment.paid = True + payment.status = "Payment successful! {} BTC".format(payment.confirmed_paid) + payment.response = "Payment successful! {} BTC".format(payment.confirmed_paid) + update_status(payment) break - elif unconf_paid > 0: - emit('my_response', {'status' : 'Discovered {} BTC payment... Waiting for {} confirmations.'.format(config.required_confirmations), 'address' : payment.address, 'amount' : payment.value, 'time_left': time_left, 'response': "Discovered {} BTC payment, waiting for {} confirmations.".format(unconf_paid, config.required_confirmations)}) - socket_.sleep(15) + elif payment.unconfirmed_paid > 0: + payment.status = "Discovered {} BTC payment. Waiting for {} confirmations...".format(payment.unconfirmed_paid, config.required_confirmations) + payment.response = "Discovered {} BTC payment. Waiting for {} confirmations...".format(payment.unconfirmed_paid, config.required_confirmations) + update_status(payment) + socket_.sleep(config.pollrate) else: - emit('my_response', {'status' : 'Awaiting payment.', 'address' : payment.address, 'amount' : payment.value, 'time_left': time_left, 'response': 'Awaiting {} BTC payment...'.format(payment.value)}) - socket_.sleep(15) + payment.status = "Awaiting {} BTC payment...".format(payment.value) + payment.response = "Awaiting {} BTC payment...".format(payment.value) + update_status(payment) + socket_.sleep(config.pollrate) else: - emit('my_response', {'status' : 'EXPIRED', 'address' : payment.address, 'amount' : payment.value, 'time_left': 0, 'response':'INVOICE EXPIRED'}) - print("Invoice {} expired.".format(payment.label)) - payment.paid = False + payment.status = "Payment expired." + payment.status = "Payment expired." + update_status(payment) - if payment.paid: - print("PAID") - emit('my_response', {'status' : 'Paid!', 'address' : payment.address, 'amount' : payment.value, 'time_left': time_left, 'response': 'Payment finalised.'}) + return -def create_invoice(amount, currency, label): - inv = invoice.invoice(amount, currency, label) - payment = bitcoind.btcd() - payment.load_invoice(inv) +def create_invoice(amount, currency, label): + payment_invoice = invoice.invoice(amount, currency, label) + payment = bitcoind.btcd(payment_invoice) payment.get_address() return payment diff --git a/invoice/__init__.py b/invoice/__init__.py @@ -1,8 +1,18 @@ +import uuid + +import config from .price_feed import get_btc_value + class invoice(): def __init__(self, dollar_value, currency, label): self.dollar_value = dollar_value self.currency = currency self.value = get_btc_value(dollar_value, currency) self.label = label + self.id = str(uuid.uuid4) + self.status = 'Payment initialised.' + self.response = '' + self.time_left = config.payment_timeout + self.confirmed_paid = 0 + self.unconfirmed_paid = 0 diff --git a/pay/bitcoind.py b/pay/bitcoind.py @@ -2,7 +2,9 @@ import config import subprocess class btcd: - def __init__(self): + def __init__(self, invoice): + self.__dict__ = invoice.__dict__.copy() + from bitcoinrpc.authproxy import AuthServiceProxy connection_str = "http://{}:{}@{}:{}".format(config.username, config.password, config.host, config.rpcport) @@ -21,12 +23,6 @@ class btcd: except Exception as e: print(e) - def load_invoice(self, invoice): - self.value = invoice.value - self.label = invoice.label - self.paid = False - return - def check_payment(self): self.address = "bc1qwxlwghumfmhwdc2deyn7h42syp2t496penax2y" transactions = self.rpc.listtransactions() diff --git a/server.py b/server.py @@ -1,4 +1,5 @@ from flask import Flask, request, url_for, jsonify, render_template +from flask_socketio import SocketIO from markupsafe import escape import time @@ -8,13 +9,9 @@ import invoice from pay import bitcoind app = Flask(__name__) +socketio = SocketIO(app) -@app.route('/') -def index(): - return render_template('payment.html') - - -app.route('/invoice', methods=['GET']) +@app.route('/invoice', methods=['GET']) def invoice(): amount = request.values.get('amount') @@ -92,6 +89,8 @@ def payment(amount, currency, label): return False +if __name__ == "__main__": + socketio.run(app, debug=True) #with app.test_client() as c: # resp = c.post('/pay', data=dict(amount=69)) diff --git a/templates/index.html b/templates/index.html @@ -10,10 +10,10 @@ var socket = io(namespace); socket.on('connect', function() { - socket.emit('initialise', {data: 'initialising payment...'}); + socket.emit('initialise', {'data': 'initialising payment...'}); }); - socket.on('my_response', function(msg, cb) { + socket.on('payresponse', function(msg, cb) { console.log(msg.response); $('#status').text(msg.status).html(); $('#address').text(msg.address).html(); @@ -25,7 +25,7 @@ }); $('form#pay').submit(function(event) { - socket.emit('payment', {amount: $('#pay_data').val()}); + socket.emit('payment', {'amount': $('#pay_data').val(), 'label' : null}); return false; }); }); @@ -40,8 +40,8 @@ document.getElementById('timer').innerHTML = Math.round(currentTime - 1); }, 1000) </script> - </head> + <body style="background-color:white;"> <h1 style="background-color:white;">BTCPyServer</h1>