Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ElementsProject/paypercall
Charge for HTTP APIs on a pay-per-call basis with Bitcoin and Lightning :zap:
https://github.com/ElementsProject/paypercall
apis bitcoin lightning lightning-charge micropayments nanopayments pay-per-call
Last synced: 2 months ago
JSON representation
Charge for HTTP APIs on a pay-per-call basis with Bitcoin and Lightning :zap:
- Host: GitHub
- URL: https://github.com/ElementsProject/paypercall
- Owner: ElementsProject
- License: mit
- Created: 2018-03-05T15:27:54.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2021-09-20T12:56:32.000Z (over 3 years ago)
- Last Synced: 2024-10-11T13:36:57.239Z (3 months ago)
- Topics: apis, bitcoin, lightning, lightning-charge, micropayments, nanopayments, pay-per-call
- Language: JavaScript
- Homepage: https://www.blockstream.com/2018/03/25/paypercall-shows-the-full-power-of-lightning-charge.html
- Size: 68.4 KB
- Stars: 148
- Watchers: 14
- Forks: 17
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-lightning-network - paypercall - Charge for HTTP APIs on a per-per-call basis with Lightning (Developer Resources / Libraries)
- awesome-lightning-network - paypercall - Charge for HTTP APIs on a per-per-call basis with Lightning (Developer Resources / Libraries)
README
# paypercall
[![npm release](https://img.shields.io/npm/v/paypercall.svg)](https://www.npmjs.com/package/paypercall)
[![MIT license](https://img.shields.io/github/license/shesek/paypercall.svg)](https://github.com/shesek/paypercall/blob/master/LICENSE)
[![Pull Requests Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com)
[![IRC](https://img.shields.io/badge/chat-on%20freenode-brightgreen.svg)](https://webchat.freenode.net/?channels=lightning-charge)Charge for HTTP APIs on a pay-per-call basis with Bitcoin and Lightning.
Want to require a payment when users take some programmatic action, such as sending an SMS or running imaging processing?
That's what `paypercall` is for.Available as an express middleware (where a node.js app makes charges directly)
or as a reverse proxy (where a reverse proxy requires payment before providing access to an app).Powered by :zap: [Lightning Charge](https://github.com/ElementsProject/lightning-charge).
## Install
```bash
$ npm install paypercall
```## Server Setup
### As a middleware
`paypercall` can be used as an express middleware to charge payments directly in your node.js apps.
Below is an example app that charges 0.1 USD to send SMS messages:#### app.js
```js
const pay = require('paypercall')({ chargeUrl: ..., chargeToken: ... })
, twi = require('twilio')(twilioSid, twilioToken)
, app = require('express')()app.use(require('body-parser').urlencoded())
app.post('/sms', pay(0.1, 'USD'), (req, res, next) =>
twi.messages.create({ from: 'paypercall', to: req.body.to, body: req.body.message })
.then(msg => res.send({ success: true, sid: msg.sid }))
.catch(next))app.listen(4000, _ => console.log('HTTP server running on localhost:4000'))
```See [`ifpaytt`](https://github.com/shesek/ifpaytt) for a more full-fledged application using `paypercall` as a middleware.
### As a reverse proxy
Alternatively, you can develop your HTTP server with no payments awareness
and use `paypercall` as a reverse proxy to handle payments.
Below is an example using a python app:#### app.py
```python
from flask import Flask, request
from twilio.rest import Client as Twilioapp = Flask(__name__)
twi = Twilio(twilioSid, twilioToken)@app.route("/sms", methods=['POST'])
def sms():
msg = twi.messages.create(from='paypercall', to=request.form['to'], body=request.form['message'])
return { 'success': True, 'sid': msg.sid }@app.run(Port=4001)
```Run the python app and the `paypercall` proxy:
```bash
$ FLASK_APP=app.py flask run
* Running on http://localhost:4001/$ paypercall --charge-token mySecretToken --upstream-url http://localhost:4001 \
--port 4000 --rates-yaml '{ POST /sms: 0.1 USD }'
HTTP reverse proxy running on http://localhost:4000, proxying to http://localhost:4001
```You will now have the python app running on port 4001 (providing API calls free of charge)
and the `paypercall` reverse proxy running on port 4000 (charging on a per-call basis).## Paying for API calls
Users can access `paypercall`-enabled API endpoints in three steps:
1. Send an empty request (no body) to the `paypercall`-enabled endpoint to get the BOLT11 payment request and the `X-Token` header:
```bash
$ curl -i -X POST http://localhost:4000/smsHTTP/1.1 402 Payment Required
Content-Type: application/vnd.lightning.bolt11
X-Token: lmbdmJeoSQ0ZCB5egtnph.af1eupleFBVuhN2vrbRuDLTlsnnUPYRzDWdL5HtWykYlnbcrt8925560p1pdfh7n2pp54g5avyupe70l988h30u0hy8agpj2z7qsveu7ejhys97j98rgez0...
```2. Make the payment:
```bash
$ lightning-cli pay lnbcrt8925560p1pdfh7n2pp54g5avyupe70l988h30u0hy8agpj2z7qsveu7ejhys97j98rgez0...
```3. Send the request again, this time with the request body and with the `X-Token` header echoed back:
```bash
$ curl -i -X POST http://localhost:4000/sms \
-H 'X-Token: lmbdmJeoSQ0ZCB5egtnph.af1eupleFBVuhN2vrbRuDLTlsnnUPYRzDWdL5HtWykY' \
-t to=+972-789456123 \
-d message='I got lightning working and all I got was this sms!'HTTP/1.1 200 OK
Content-Type: application/json{"success":true,"sid":"SMf34fe622a8fe7565fc15be3ce8bc437e"}
```## Documentation
### Middleware
```js
const pay = require('paypercall')(options)
```Returns a new payment middleware factory. `options` can contain the following fields:
- `chargeUrl`: Lightning Charge server URL (optional, defaults to `http://localhost:9112`)
- `chargeToken`: Lightning Charge access token (**required**)
- `dbPath`: Path to sqlite database (optional, defaults to `./paypercall.db`)
- `currency`: Default currency if none is specified (optional, defaults to `BTC`)
- `secret`: Secret key used for HMAC tokens (optional, generated based on `chargeToken` by default)
- `invoiceExp`: How long should invoices be payable for (optional, defaults to 1 hour)
- `accessExp`: How long should paid access tokens remain valid for (optional, defaults to 1 hour)```js
const payware = pay(amount[, currency])
```Returns an express middleware that requires a payment of `amount` units of `currency`
(or the default currency if none provided) before letting requests pass through.Can be used as following:
```js
const pay = require('paypercall')({ chargeToken: 'myToken', currency: 'EUR' })
, app = require('express')// charge requests to a specific route
app.post('/sms', pay(0.15), (req, res) => { /* send SMS */ })// charge all requests to /paid-apis/*
app.use('/paid-apis', pay(0.25))// dynamic pricing (should only be based on the method and path)
app.post('/ocr/:type', (req, res, next) => {
pay(getPriceForType(req.params.type))(req, res, (err) => {
if (err) return next(err)
// payment succesfull, run OCR
// (the paid invoice is accessible at `req.invoice`)
})
})
```### Reverse proxy
```bash
$ paypercall --helpCharge for HTTP APIs on a pay-per-call basis with Bitcoin and Lightning
Usage
$ paypercall [options]Options
-c, --charge-url lightning charge server url [default: http://localhost:9112]
-t, --charge-token lightning charge access token [required]-u, --upstream-url the upstream server to reverse proxy [required]
-r, --rates-path path to YAML file mapping from endpoints to rates [default: ./rates.yaml]
-y, --rates-yaml YAML string to use instead of reading from {rates-path}
-x, --currency default rate currency if none is specified [default: BTC]
-d, --db-path path to store sqlite database [default: ./payperclick.db]--invoice-expiry how long should invoices be payable for [default: 1 hour]
--access-expiry how long should paid access tokens remain valid for [default: 1 hour]
--token-secret secret key used for HMAC tokens [default: generated based on {charge-token}]-p, --port http server port [default: 4000]
-i, --host http server listen address [default: 127.0.0.1]
-e, --node-env nodejs environment mode [default: production]
-h, --help output usage information
-v, --version output version numberExample
$ payperclick -t myAccessToken -u http://upstream-server.com/ \
-y '{ POST /sms: 0.0001 BTC, PUT /page/:id: 0.0002 BTC }'
```## License
MIT