Building a Middleware Library Implementing the LSAT Spec

Building a Middleware Library Implementing the LSAT Spec

Middleware between Client and Server (taken from Jeff’s blog)

What is a Middleware?

A middleware comes in the middle of the request and response cycle. In simple words, it is the code that runs before handling the request to the server. It is mainly used for the verification of requests and routing them to the resource it is appropriate. A good use case for middleware can be the authentication of any user before serving any auth-required routes.

For our use case, we are leveraging middleware for:-

  1. Checking the preference of the user whether they need paid content or free content.
  2. Verifying the LSAT (Lightning Service Authentication Token — a standardized token for authentication and paid APIs) before serving paid content.
  3. Sending macaroon and invoice if the user prefers paid content and fails to present a valid LSAT.
The request-response flow taken from the previous blog post

You can read more about the LSAT authentication flow and request-response flow in the previous blog post.

Middleware library implementation

After sketching the use case, I have started implementing the middleware library for the Gin framework in Golang. As I had already implemented the LSAT proxy server to demonstrate the above features it became straightforward for me to implement it as a middleware library.

Here is the link to the gin-lsat middleware library I implemented:

It supports LND and LNURL natively for generating invoices but one can extend support and customize the LNClient interface easily.

LNClient interface taken from lnclient.go:

type LNClient interface {
	AddInvoice(ctx context.Context, lnReq *lnrpc.Invoice, httpReq *http.Request, options ...grpc.CallOption) (*lnrpc.AddInvoiceResponse, error)
}

The developers who don’t want to run their node can configure their Lightning Address easily to accept payments on it. The end user of the paid content/APIs can pay the invoice easily through WebLN client applications like Alby (a versatile open-source browser extension for the Bitcoin Lightning Network).

It also supports the regulation of amount in sats for different routes by injecting a function into the middleware. One can easily query the amount in sats by making requests to their database or even set the amount by calculating equivalent sats (satoshis) based on fiat currency value.

An example showing the calculation of equivalent sats dynamically based on fiat currency value:

const SATS_PER_BTC = 100000000

const MIN_SATS_TO_BE_PAID = 400

type FiatRateConfig struct {
	Currency string
	Amount   float64
}

func (fr *FiatRateConfig) FiatToBTCAmountFunc(req *http.Request) (amount int64) {
	if req == nil {
		return MIN_SATS_TO_BE_PAID
	}
	res, err := http.Get(fmt.Sprintf("https://blockchain.info/tobtc?currency=%s&value=%f", fr.Currency, fr.Amount))
	if err != nil {
		return MIN_SATS_TO_BE_PAID
	}
	defer res.Body.Close()

	amountBits, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return MIN_SATS_TO_BE_PAID
	}
	amountInBTC, err := strconv.ParseFloat(string(amountBits), 32)
	if err != nil {
		return MIN_SATS_TO_BE_PAID
	}
	amountInSats := SATS_PER_BTC * amountInBTC
	return int64(amountInSats)
}

func main() {
	...
 	fr := &FiatRateConfig{
		Currency: "USD",
		Amount:   0.1,
	}
  lsatmiddleware, err := ginlsat.NewLsatMiddleware(lnClientConfig, fr.FiatToBTCAmountFunc)
	if err != nil {
		log.Fatal(err)
	}
  
  ...
  
}

I have also implemented an application with the library that demonstrates the serving of static files and creating a paywall for paid resources.

Also, check out this demo app by Kwinten developed using gin-lsat.

It is a simple combination of LSAT and WebLN where one can upload images with their Lightning Address and get paid in sats for the downloads. An important thing to note here is the payment goes directly to the uploader, not to the platform. Though the platform verifies the proof of payment but does not receive the payment. This is a much better UX than similar setups where the money is held on the platform.

I have implemented a middleware library for the Echo framework as well. Here’s the link to the echo-lsat middleware library.

Future project goals

  1. Figure out different ways for the user to showcase their preference for the paid content and implement client-side libraries for it (a running discussion on it).
  2. Add native support for other nodes like Core-lightning and Eclair.
  3. Implement the library for other languages like Ruby On Rails.
  4. Implement the LSAT features on the API gateway or Load balancing layer to make it independent from the technologies used at the backend server. (Building plugins for reverse proxies like NGINX and Apache).

Thanks to my mentors Michael and Kwinten for helping me with the project. Thanks to Lightning Labs for the inspirational project aperture and the discussions on LSAT.

This article by Dhananjay Purohit, a Summer of Bitcoin intern at Alby, was originally written on Medium. Reshared here with permission.