Last active
October 26, 2019 07:34
-
-
Save adrienemery/0506f487da101a0e81e77c6e860cb502 to your computer and use it in GitHub Desktop.
Revisions
-
adrienemery revised this gist
Mar 28, 2018 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -28,7 +28,7 @@ # Setup the Flask-JWT-Simple extension JWT_SECRET_KEY = os.getenv('JWT_SECRET_KEY') app.config['JWT_SECRET_KEY'] = JWT_SECRET_KEY jwt = JWTManager(app) # Setup the grpc stub -
adrienemery revised this gist
Mar 28, 2018 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,9 +7,9 @@ But for now I just wanted to show how simple it could be to add a paywall to an api service. To use this api: 1. Make a POST request to get a new token and invoice at `/token` 2. Pay the invoice that comes along with the token on the lightning network 3. Make a GET request to `/payme` """ import os import binascii -
adrienemery revised this gist
Mar 28, 2018 . 1 changed file with 6 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,6 +5,11 @@ imagined (bulk payments/pay per call etc). But for now I just wanted to show how simple it could be to add a paywall to an api service. To use this api: 1. Make a POST request to get a new token and invoice at `/token` by 2. pay the invoice that comes along with the token on the lightning network 3. make a GET request to `/payme` """ import os import binascii @@ -73,7 +78,7 @@ def obtain_token(): return jsonify(data), 200 @app.route('/payme', methods=['GET']) @jwt_required @invoice_paid def protected(): -
adrienemery created this gist
Mar 28, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,84 @@ """ This app is an example of how you could charge for access to an API using the lightning network and LND. The example uses a JWT token that grants 1-hour access (the default jwt token expirey) but many different payment schemes could be imagined (bulk payments/pay per call etc). But for now I just wanted to show how simple it could be to add a paywall to an api service. """ import os import binascii from functools import wraps import grpc import rpc_pb2 as ln import rpc_pb2_grpc as lnrpc from flask import Flask, jsonify, request from flask_jwt_simple import JWTManager, jwt_required, create_jwt, get_jwt_identity os.environ["GRPC_SSL_CIPHER_SUITES"] = 'HIGH+ECDSA' app = Flask(__name__) # Setup the Flask-JWT-Simple extension JWT_SECRET_KEY = os.getenv('JWT_SECRET_KEY') app.config['JWT_SECRET_KEY'] = 'secret' jwt = JWTManager(app) # Setup the grpc stub with open(os.path.expanduser('~/Library/Application Support/Lnd/tls.cert'), 'rb') as f: cert = f.read() with open(os.path.expanduser('~/Library/Application Support/Lnd/admin.macaroon'), 'rb') as f: macaroon_bytes = f.read() macaroon_hex = binascii.hexlify(macaroon_bytes).decode() creds = grpc.ssl_channel_credentials(cert) channel = grpc.secure_channel('127.0.0.1:10009', creds) stub = lnrpc.LightningStub(channel) def invoice_paid(fn): """Decorator to ensure invoice has been paid Raises: HTTP 402 Error if payment not settled """ @wraps(fn) def wrapper(*args, **kwargs): r_hash_str = get_jwt_identity() rpc_request = ln.PaymentHash(r_hash_str=r_hash_str) invoice = stub.LookupInvoice(rpc_request, metadata=[('macaroon', macaroon_hex)]) if invoice.settled is False: return jsonify({"msg": "Payment required"}), 402 return fn(*args, **kwargs) return wrapper @app.route('/token', methods=['POST']) def obtain_token(): """Create a JWT with the r_hash of a lightning invoice encoded as the indentity """ # geneate a lightning invoice rpc_request = ln.Invoice(value=100, memo='api access') response = stub.AddInvoice(rpc_request, metadata=[('macaroon', macaroon_hex)]) r_hash_str = binascii.hexlify(response.r_hash).decode() # use the r_hash as the itentity data = { 'jwt': create_jwt(identity=r_hash_str), 'invoice': response.payment_request } return jsonify(data), 200 @app.route('/protected', methods=['GET']) @jwt_required @invoice_paid def protected(): return jsonify({'msg': "You Paid!"}), 200 if __name__ == '__main__': app.run()