A lightning-based paywall middlware for Nodejs + Expressjs API services. Built with Typescript.
To run the test server, clone the repo, and from the directory run:
$ yarn install
$ yarn start
Your project must also use Expressjs
4.x as well as the cors
and body-parser
middleware.
To use as a middleware in an existing server, just install from npm into your project, and use before all routes that you want protected.
An example project can be seen in src/server.ts
. This is what is run when running yarn start
.
A very simple server file, with no special configurations, could look like this:
const express = require('express')
const cors = require('cors')
const bodyParser = require('body-parser')
const { boltwall } = require('boltwall')
const app = express()
// middleware
app.use(cors())
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.get('/', (_req, res) => {
return res.json({
message: 'Home route comes before boltwall and so is unprotected.',
})
})
app.use(boltwall())
app.get('/protected', (_req, res) =>
res.json({
message:
'Protected route! This message will only be returned if an invoice has been paid',
})
)
app.listen(5000, () => console.log('listening on port 5000!'))
Several environment variables are required when running boltwall
. These serve the purpose of connecting to your
lightning node and managing/signing macaroons for authentication/authorization.
The required environment variables are:
If you are connecting to a lightning node you will need the following in your project's .env
file
or in process.env
Learn how to find these values in this article by Will O'Beirne. You can also try this tool by lightning joule
LND_TLS_CERT=[BASE64 or HEX encoded cert here]
LND_MACAROON=[BASE64 or HEX encoded cert here]
LND_SOCKET=[address of node here, e.g. localhost:10006]
If you are using OpenNode for managing payments, create an OpenNode account, generate an API key and save it as:
OPEN_NODE_KEY=[API KEY HERE]
If you have both the lnd configs and open node, lnd will take precedence.
Finally, you will need a caveat key for enabling custom authorization schemes such as time-based auth and a SESSION_SECRET for securing macaroons.
CAVEAT_KEY=[ENTER PASSWORD]
SESSION_SECRET=[RANDOM STRING MINIMUM 32 BYTES IN LENGTH]
Boltwall allows for flexible authorization schemes. Effectively, this means that a server that is implementing Boltwall to protect content can dictate factors such as how long authorization is valid for based off of a payment or restrict access to only the originating IP.
As an example, the configuration in the example file src/server.ts
, sets up authorization that
is valid for a time where for each satoshi paid in the lightning invoice is equivalent to 1 second.
So if a user pays a 30 satoshi invoice, then access is allowed for 30 seconds.
The config object should be passed to boltwall
on initialization. e.g. app.use(boltwall(myConfig))
, where myConfig
provides the relevant properties. Currently, the config supports
three properties: caveatVerifier
(func), getCaveat
(func), and getInvoiceDescription
.
More information on the configs can be found in the API Documentation.
The use of macaroons for authorization allows for a lot of flexibility. Aside from the customization laid out
in the section above covering the configurations, boltwall
's API also enables authorization schemes with 3rd parties
or as a 3rd party.
Think of it like running your own oAuth service.
In the same way where Google's oAuth allows a 3rd party service to sign you in to their platform by verifying your Google account, with Boltwall, your API can act like Google, where instead of verifying your account, the service verifies payment. An example of how this can be implemented is in the Prism Reader app. Prism Reader hosts documents provided by users. Authors of content can optionally require payment to view that content. Rather than Prism acting as a custodian for the funds and issuing payouts, an author can run a boltwall instance, give Prism the url of your API and a shared secret key (caveat key), and users will then only be able to read your content once your server has acknowledged payment!
Boltwall exposes some default configs you can use in your own server. Simply import
them from the module and then pass them into boltwall when use
ing it in your express
server.
import { boltwall, TIME_CAVEAT_CONFIGS } from 'boltwall'
// ... rest of your server code
app.use(boltwall(TIME_CAVEAT_CONFIGS))
// ... protected routes and any other server code
Currently this is the only available default config. It creates a restriction that any authorization is only valid for a number of seconds equal to the number of satoshis paid.
Boltwall also supports custom configs. The properties that can be passed to boltwall are:
More indepth documentation for these properties can be found in the docs
The below image should give an idea of the authentication flow between the ln-builder api, lightning node,
3rd party App requesting the authentication, and the client being authenticated.
Check out the Swagger Docs for detailed API information. This details what to expect
at the various routes provided for by Boltwall
.
API documentation, with details on the code and API can be found at the documentation website.
Generated using TypeDoc