Package wall contains all paywall-related code.

This is the package you need to use for creating a middleware for one of the supported handlers / routers / frameworks. For creating a middleware you only need to call one of the provided factory functions, but all functions require a storage client (an implementation of the wall.StorageClient interface) as parameter. You can either pick one from the storage package (, or implement your own.


Here's one example of a web service implemented with Gin. For more examples check out the "examples" directory in the GitHub repository of this package (

package main

import (


func main() {
	r := gin.Default()

	// Configure middleware
	invoiceOptions := wall.DefaultInvoiceOptions // Price: 1 Satoshi; Memo: "API call"
	lndOptions := ln.DefaultLNDoptions           // Address: "localhost:10009", CertFile: "tls.cert", MacaroonFile: "invoice.macaroon"
	storageClient := storage.NewGoMap()          // Local in-memory cache
	lnClient, err := ln.NewLNDclient(lndOptions)
	if err != nil {
	// Use middleware
	r.Use(wall.NewGinMiddleware(invoiceOptions, lnClient, storageClient))

	r.GET("/ping", func(c *gin.Context) {
		c.String(http.StatusOK, "pong")

	r.Run() // Listen and serve on



This section is empty.


View Source
var DefaultInvoiceOptions = InvoiceOptions{
	Price: 1,
	Memo:  "API call",

DefaultInvoiceOptions provides default values for InvoiceOptions.


func NewEchoMiddleware

func NewEchoMiddleware(invoiceOptions InvoiceOptions, lnClient LNclient, storageClient StorageClient, skipper middleware.Skipper) echo.MiddlewareFunc

NewEchoMiddleware returns an Echo middleware in the form of an echo.MiddlewareFunc.

func NewGinMiddleware

func NewGinMiddleware(invoiceOptions InvoiceOptions, lnClient LNclient, storageClient StorageClient) gin.HandlerFunc

NewGinMiddleware returns a Gin middleware in the form of a gin.HandlerFunc.

func NewHandlerFuncMiddleware

func NewHandlerFuncMiddleware(invoiceOptions InvoiceOptions, lnClient LNclient, storageClient StorageClient) func(http.HandlerFunc) http.HandlerFunc

NewHandlerFuncMiddleware returns a function which you can use within an http.HandlerFunc chain.

func NewHandlerMiddleware

func NewHandlerMiddleware(invoiceOptions InvoiceOptions, lnClient LNclient, storageClient StorageClient) func(http.Handler) http.Handler

NewHandlerMiddleware returns a function which you can use within an http.Handler chain.


type InvoiceOptions

type InvoiceOptions struct {
	// Amount of Satoshis you want to have paid for one API call.
	// Values below 1 are automatically changed to the default value.
	// Optional (1 by default).
	Price int64
	// Note to be shown on the invoice,
	// for example: "API call to".
	// Optional ("" by default).
	Memo string

InvoiceOptions are the options for an invoice.

type LNclient

type LNclient interface {
	// GenerateInvoice generates a new invoice based on the price in Satoshis and with the given memo.
	GenerateInvoice(int64, string) (ln.Invoice, error)
	// CheckInvoice checks if the invoice was settled, given an LN node implementation dependent ID.
	// For example lnd uses the payment hash a.k.a. preimage hash as ID, while Lightning Charge
	// uses a randomly generated string as ID.
	CheckInvoice(string) (bool, error)

LNclient is an abstraction of a client that connects to a Lightning Network node implementation (like lnd, c-lightning and eclair) and provides the methods required by the paywall.

type StorageClient

type StorageClient interface {
	// Set stores the given invoiceMetaData for the given preimage hash.
	Set(string, interface{}) error
	// Get retrieves the invoiceMetaData for the given preimage hash
	// and populates the fields of the object that the passed pointer
	// points to with the values of the retrieved object's values.
	// If no object is found it returns (false, nil).
	Get(string, interface{}) (bool, error)

StorageClient is an abstraction for different storage client implementations. A storage client must be able to store and retrieve invoiceMetaData objects.