Offline Lightning Payments Part 1: Offline Point of Sale

For a lightning payment to succeed, every involved lightning node has to be online at least at one point of the process. However, this does not necessarily apply to terminal devices. In this blogpost you will learn how a point of sale can accept and verify lightning payments while being completely offline.

During our last semester at the University of Applied Sciences and Arts Northwestern Switzerland (FHNW), Nicola Roten and I worked on enabling offline payments within the lightning network as part of our bachelor thesis. This blog series is all about our results and consists of the following parts:

  • Offline Lightning Payments Part 1: Offline Point of Sale
  • Offline Lightning Payments Part 2: Offline Payment Device
  • Offline Lightning Payments Part 3: Offline Terminal Device Data Transmission


First of all, we defined various scenarios in which different components of the sender and / or the recipient are offline. A distinction was made between LN node and terminal device because there are solutions where the LN node is operated on a dedicated device and the terminal device is exclusivley used for remote control (e.g. Zap App).

This blogpost will further explain our solution for the scenario where the terminal device of the recipient is offline as depicted in the following diagram. A typical use case is an offline point of sale as demonstrated in our Twitter post in August.

Offline Point of Sale – Scenario Scheme


Offline points of sale seem to represent a greater need, as it is much discussed in the LN community. Our approach is based on a deterministc preimage generation process and therefore an enhancement of the idea described by user ZmnSCPxj of the LN mailinglist. It introduces deputy payment processing (dpp) as an extension to the current lightning specification, which differs from regular payment processing in the following aspects:

Invoice Creation

The invoice is created locally on the recipient’s terminal device. In order for it to be settled correctly and the payment subsequently verified offline, it must have special characteristics:

  • Feature Bits: The sender must be informed that the payment can / must be verified offline. Therefore, the feature bit 22/23 must be set in the invoice.
  • Receipient: The target node exposed in the Invoice is not the actual recipient node, but a “deputy node” that does not exist in the LN. This can always be the same for each terminal device or can be generated anew for each invoice. The deputy node is only used to ensure that the invoice is correctly created according to BOLT-11 and can be signed without the terminal device having to know the private key of the actual recipient node.
  • Preimage Nonce: The preimage is to be generated to a part from a random value. This nonce should be 32 bytes large, because this corresponds to the size of a preimage. This allows to use the same random logic for nonce generation as for generating preimages of normal payments. As a result, the probability of generating the same preimage twice is no higher than for normal payments.
    Because the nonce is generated randomly, it must be communicated to the receiver node, so that it can reconstruct the preimage later. Therefore, the nonce is exposed in the invoice field 0.
  • Preimage: The preimage is generated using the following formula:

    preimage = sha256( concat( s, n, a))

    The parameters are defined as follows:
    • s: A shared secret only known by the recipient node and the point of sale
    • n: The randomly generated preimage nonce
    • a: The invoice amount in msat (8 bytes, big-endian); 0 if the invoice does not specify any amount
      The SHA-256 hash function is used because the preimage must have a length of 32 bytes according to BOLT-2.

Payment Initiation

In order for the recipient node to correctly reconstruct the preimage of the invoice, the nonce and invoice amount must be transmitted to it. This is done using the new dpp onion payload consisting of the following parts:

  • preimagenonce: the nonce created for the preimage
  • invoiceamount: the amount shown in the invoice in msat; 0 for a zero amount invoice

The invoice amount must be transmitted because BOLT-4 allows a higher amount to be transferred for obfuscation purposes. Per default, all data in the onion payload is encrypted by the sender so that it is only visible to the addressed node. For this reason, transmitting the invoice amount is compliant with the mentioned obfuscation feature.

Payment Routing

Due to the routing hint in the invoice, the payment is routed to the actual recipient node. At this point, the mentioned deputy node is declared as the next hop. As this node does not exist, the payment can not be forwarded to it. The actual recipient node recognizes this circumstance by the presence of the dpp onion record. With the additional data in this record and the corresponding shared secret, it can now reconstruct the preimage using the same formula which was initially used by the offline point of sale.
However, before publishing the preimage, the recipient node must check the following conditions:

  • received amount is sufficient: The amount received must be compared with the invoice amount stored in the dpp onion payload. If the former is smaller than the latter, less money was transferred than originally requested in the invoice. In this case, the payment must be rejected using update_fail_htlc and error code incorrect_or_unknown_payment_details according to BOLT-2 / BOLT-4. This corresponds to the behavior for regular payments with a too small amount.
  • reconstructed preimage is correct: Of course, the payment would also fail by publishing the wrong preimage. However, it is better practice to deliberately reject the payment using update_fail_htlc and error code incorrect_or_unknown_payment_details.

If these two conditions are met, the recipient node can claim and at the same time confirm the payment by publishing the reconstructed preimage within the lightning network.

Proof of Payment

Because of the mentioned publishing in the LN the sender knows the preimage as soon as the payment is completely processed. Therfore, the preimage can be presented to the recipient terminal as proof of payment. The recipient terminal has to validate the presented preimage against the payment hash of the issued invoice. If this is successful, the proof of payment is valid and the recipient device can grant access to the purchased product.


As a proof of concept, we have implemented the described approach by adapting the Zap App for Android and LND accordingly. Moreover, we have extended our lightning beer tap so that it supports deputy payment processing and therefore can be completely offline. See also the picture and video below.

Zap App extended by a proof of payment QR code
our LN beer tap, serving as an offline point of sale

We decided to use a different short channel id in the routing hint depending on the terminal device. This allows the use of different secrets per point of sale and thus reduces the impact of a compromised terminal device.
For this purpose we have adapted LND so that terminal devices („deputies“) can be configured as follows:

lncli adddeputy ${SHORT_CHANNEL_ID} -−secret=${SHARED_SECRET} −−name=${NAME}

${SHORT_CHANNEL_ID} corresponds to the short channel id used in the routing hint by the terminal device and ${SHARED_SECRET} is the secret used for the preimage generation. ${NAME} is a human friendly name used in the logs of LND.

Next Steps

Offline payments as described in this blogpost can only be used when a broad amount of LN nodes supports deputy payment processing. In order to achieve this, we have prepared a pull request to the LN specification.

Kommentare sind geschlossen.