import uuid from datetime import datetime import requests from flask import request, redirect, render_template, url_for, flash, make_response, send_from_directory, jsonify from flask_yoloapi import endpoint, parameter import json import settings from funding.factory import app, db, cache from funding.orm import Address, Slate, Cancel import secp256k1 import base58 @app.route('/') def index(): return redirect(url_for('about')) @app.route('/about') def about(): return "" @app.route('/postSlate', methods=['POST']) @endpoint.api( parameter('receivingAddress', type=str, required=True), parameter('slate', type=str, required=True), ) def postSlate(receivingAddress, slate): try: if receivingAddress is None or slate is None: return make_response(jsonify({'status': 'failure', 'error': str("missing correct arguments")})) try: Address.add(address=receivingAddress) except Exception as ex: print(f'{ex}') try: Slate.add(slate=slate, receivingAddress=receivingAddress) except Exception as ex: print(f'{ex}') return make_response(jsonify({'status': 'success'})) except Exception as ex: print(f'{ex}') return make_response(jsonify({'status': 'failure', 'error': str(ex)})) @app.route('/getSlates', methods=['POST']) @endpoint.api( parameter('receivingAddress', type=str, required=True), parameter('signature', type=str, required=True) ) def getSlates(receivingAddress, signature): try: if receivingAddress is None or signature is None: return make_response(jsonify({'status': 'failure', 'error': str("missing correct arguments")})) # Deserialize the base-58 address to an internal public key format # NOTE: This assumes that the network version (which is not part of the key) is exactly 2 bytes public_key = secp256k1.PublicKey(base58.b58decode_check(receivingAddress)[2:], raw=True) # Prepare the message bound to the signature: a domain separator and the encoded address # For some reason, the original client code calls this the "challenge" message = 'SubscribeRequest_' + receivingAddress # Deserialize and verify the provided signature against the message and address public key if not public_key.ecdsa_verify(message.encode(), public_key.ecdsa_deserialize(bytes(bytearray.fromhex(signature)))): return make_response(jsonify({'status': 'failure', 'error': str("bad signature")})) slates = Slate.find_slates(address=receivingAddress) return make_response(jsonify({'status': 'success', 'slates': slates})) except Exception as ex: print(f'{ex}') return make_response(jsonify({'status': 'failure', 'error': str(ex)})) @app.route('/deleteSlate', methods=['POST']) @endpoint.api( parameter('receivingAddress', type=str, required=True), parameter('signature', type=str, required=True), parameter('slate', type=str, required=True) ) def deleteSlate(receivingAddress, signature, slate): try: if slate is None or signature is None or receivingAddress is None: return make_response(jsonify({'status': 'failure', 'error': str("missing correct arguments")})) # Deserialize the base-58 address to an internal public key format # NOTE: This assumes that the network version (which is not part of the key) is exactly 2 bytes public_key = secp256k1.PublicKey(base58.b58decode_check(receivingAddress)[2:], raw=True) # Prepare the message bound to the signature: a domain separator and the encoded address # For some reason, the original client code calls this the "challenge" message = 'SubscribeRequest_' + receivingAddress # Deserialize and verify the provided signature against the message and address public key if not public_key.ecdsa_verify(message.encode(), public_key.ecdsa_deserialize(bytes(bytearray.fromhex(signature)))): return make_response(jsonify({'status': 'failure', 'error': str("bad signature")})) is_deleted = Slate.delete_slate(address=receivingAddress, slate=slate) return make_response(jsonify({'status': 'success', 'is_deleted': is_deleted})) except Exception as ex: print(f'{ex}') return make_response(jsonify({'status': 'failure', 'error': str(ex)})) @app.route('/postCancel', methods=['POST']) @endpoint.api( parameter('receivingAddress', type=str, required=True), parameter('signature', type=str, required=True), parameter('slate', type=str, required=True), parameter('sendersAddress', type=str, required=True), ) def postCancel(receivingAddress, signature, slate, sendersAddress): try: if sendersAddress is None or slate is None or signature is None or receivingAddress is None: return make_response(jsonify({'status': 'failure', 'error': str("missing correct arguments")})) # Deserialize the base-58 address to an internal public key format # NOTE: This assumes that the network version (which is not part of the key) is exactly 2 bytes public_key = secp256k1.PublicKey(base58.b58decode_check(sendersAddress)[2:], raw=True) # Prepare the message bound to the signature: a domain separator and the encoded address # For some reason, the original client code calls this the "challenge" message = 'SubscribeRequest_' + sendersAddress # Deserialize and verify the provided signature against the message and address public key if not public_key.ecdsa_verify(message.encode(), public_key.ecdsa_deserialize(bytes(bytearray.fromhex(signature)))): return make_response(jsonify({'status': 'failure', 'error': str("bad signature")})) try: Cancel.add(receivingAddress=receivingAddress, slate_id=slate, sendersAddress=sendersAddress) except Exception as ex: print(f'{ex}') return make_response(jsonify({'status': 'success'})) except Exception as ex: print(f'{ex}') return make_response(jsonify({'status': 'failure', 'error': str(ex)})) @app.route('/getCancels', methods=['POST']) @endpoint.api( parameter('receivingAddress', type=str, required=True), parameter('signature', type=str, required=True), ) def getCancels(receivingAddress, signature): try: if receivingAddress is None or signature is None: return make_response(jsonify({'status': 'failure', 'error': str("missing correct arguments")})) # Deserialize the base-58 address to an internal public key format # NOTE: This assumes that the network version (which is not part of the key) is exactly 2 bytes public_key = secp256k1.PublicKey(base58.b58decode_check(receivingAddress)[2:], raw=True) # Prepare the message bound to the signature: a domain separator and the encoded address # For some reason, the original client code calls this the "challenge" message = 'SubscribeRequest_' + receivingAddress # Deserialize and verify the provided signature against the message and address public key if not public_key.ecdsa_verify(message.encode(), public_key.ecdsa_deserialize(bytes(bytearray.fromhex(signature)))): return make_response(jsonify({'status': 'failure', 'error': str("bad signature")})) slates = Cancel.find_slate_ids(address=receivingAddress) return make_response(jsonify({'status': 'success', 'canceled_slates': slates})) except Exception as ex: print(f'{ex}') return make_response(jsonify({'status': 'failure', 'error': str(ex)})) @app.route('/deleteCancels', methods=['POST']) @endpoint.api( parameter('receivingAddress', type=str, required=True), parameter('signature', type=str, required=True), parameter('slate', type=str, required=True) ) def deleteCancels(receivingAddress, signature, slate): try: if slate is None or signature is None or receivingAddress is None: return make_response(jsonify({'status': 'failure', 'error': str("missing correct arguments")})) # Deserialize the base-58 address to an internal public key format # NOTE: This assumes that the network version (which is not part of the key) is exactly 2 bytes public_key = secp256k1.PublicKey(base58.b58decode_check(receivingAddress)[2:], raw=True) # Prepare the message bound to the signature: a domain separator and the encoded address # For some reason, the original client code calls this the "challenge" message = 'SubscribeRequest_' + receivingAddress # Deserialize and verify the provided signature against the message and address public key if not public_key.ecdsa_verify(message.encode(), public_key.ecdsa_deserialize(bytes(bytearray.fromhex(signature)))): return make_response(jsonify({'status': 'failure', 'error': str("bad signature")})) is_deleted = Cancel.delete_slate_id(address=receivingAddress, slate_id=slate) return make_response(jsonify({'status': 'success', 'is_deleted': is_deleted})) except Exception as ex: print(f'{ex}') return make_response(jsonify({'status': 'failure', 'error': str(ex)}))