diff --git a/12-offline-data-transmission.md b/12-offline-data-transmission.md new file mode 100644 index 000000000..e59d62195 --- /dev/null +++ b/12-offline-data-transmission.md @@ -0,0 +1,46 @@ +# BOLT #12: Offline Data Transmission + +Some specific features (e.g. offline payments) require the devices of the sender and receipient of a payment to be able to communicate with each other. As those devices oftentimes are not lightning nodes, this communication cannot be done through lightning messaging as described in BOLT-1. Thereofore, BOLT-12 defines how such devices can exchange messages directly while being offline / not connected to the lightning network. + + +## Transfer Medium +The devices may support various mediums in order to transmit data. Therefore, it is important that sender and receiver device can choose a medium which is supported by both sides. This is done using feature bits. + +The following mediums are supported: + + +| Feature Bit | Name | Description | +| ----------- | ------- | ------------------------------------------------------------------------------------------------------- | +| `129` | QR Code | Data is transmitted by showing a QR Code. The code consists of a HEX-string of the message to transfer. | + +Feature bits corresponding to supported offline data transmission mediums SHOULD always be odd as a single medium supported by both parties is sufficient for a successful data transmission. + +### Requirements + +The recipient device +* MUST set the feature bits corresponding to its supported data transmission mediums in the invoice. +* MUST be ready to receive messages through offline data transmission through all of the supported transmission mediums at any time. + +The sender +* if offline data transmission is required: + * SHOULD only pay an invoice if it supports one of the data transmission mediums defined by the invoice feature bits. + +## Message Format +All offline messages are of the form: +1. `type`: a 1-byte big-endian field indicating the type of message. +1. `payload`: a variable-length payload that comprises the remainder of the message and that conforms to a format matching the `type`. + +### Requirements + +A receipient of an offline message +* MUST not break when a message of an unknown type is received. +* MAY show a warning or error when a message of an unknown type is received. + +## Message Types + +As offline messages correspond to specific features, every message type is described in a dedicated BOLT of the corresponding feature. The following table gives an overview of already reserved types: + +| Type | Name | BOLT | +| ----- | ------------------------------- | ------- | +| `0x0` | Deputy Payment Preimage Message | BOLT-13 | +| `0x1` | Payment Authorization Message | BOLT-14 | diff --git a/13-deputy-payment-processing.md b/13-deputy-payment-processing.md new file mode 100644 index 000000000..b3c026777 --- /dev/null +++ b/13-deputy-payment-processing.md @@ -0,0 +1,190 @@ +# BOLT #13: Deputy Payment Processing + +Some use cases require a third party (e.g. an offline point of sale) to issue valid invoices and verify whether they have been paid. This BOLT defines how such invoices can be generated and paid using `deputy payment processing`. + +`deputy payment processing` relies on a deterministic preimage generation process. This allows a point of sale to generate valid invoices and validate whether they have been paid without the necessity of communicating with the recipient node at any time of the payment process. + +## Requirements + +The point of sale supporting `deputy payment processing` +* MUST issue a valid invoice corresponding to BOLT-11 +* if it requires `deputy payment processing`: + * MUST set the feature bit `22` in the invoice. +* otherwise: + * MUST set the feature bit `23` in the invoice. +* MUST set a non-existing node ("deputy node") as a recipient node. +* MUST add the recipient node as last routing hint. +* MUST deterministically generate the preimage based on + * a random nonce of 32 bytes ("preimage nonce"). + * the requested amount corresponding tho the `amount` field of the invoice. +* MUST ensure that no one else except the recipient node is able to reconstruct the generated preimage. +* MUST expose preimage nonce as field `0` in the invoice. +* MUST expose its supported offline data transmission mediums using odd feature bits according to BOLT-12. +* if the generated preimage is presented through offline data transmission: + * MUST grant access to the purchase. +* otherwise: + * MUST NOT grant access to the purchase. + +The sender +* if the recipient requires `deputy payment processing`: + * if it supports `deputy payment processing`: + * MUST use `deputy payment processing`. + * otherwise: + * MUST NOT initiate the payment. +* if the recipient optionally supprts `deputy payment processing`: + * if it supports `deputy payment processing`: + * MAY use `deputy payment processing`. + * otherwise: + * MAY use regular payment processing. + +If the payment shall be processed using `deputy payment processing`, the sender +* if it supports none of the offline data transmission mediums supported by the receiver: + * MUST NOT initiate the payment using `deputy payment processing`. +* if no routing hint was specified: + * MUST NOT initiate the payment using `deputy payment processing`. +* if the invoice does not specify a field `0`: + * MUST NOT initiate the payment using `deputy payment processing`. +* otherwise: + * MUST add a `dpp` onion record to the hop of the last routing hint with + * `preimagenonce` set to the value of field `0` of the invoice. + * `invoiceamount` set to the amount requested by the invoice in msat; `0` if the invoice does not specify a minimal amount. +* if the payment was successful: + * MAY present the preimage using offline data transmission and the `deputy payment preimage message`. + +A recipient node supporting `deputy payment processing`: +* MUST set the feature bit `23` in its `init` and `node_announcement` message +* if the `dpp` onion payload is set: + * if the received amount is less than the `invoiceamount` specified in the `dpp` payload: + * MUST fail the payment with `incorrect_or_unknown_payment_details` + * if the preimage can be successfully reconstructed: + * MUST claim the payment + * otherwise: + * MUST fail the payment with `incorrect_or_unknown_payment_details` + + + +## Payload for the last Routing Hint + +For the recipient node to be able to reconstruct the preimage of a `dpp` payment, additional information is required. This is transmitted using the `dpp` onion payload with type number `12`. + +A`dpp` onion payload consists of the following parts: +* [`2*byte` : `preimagenonce`]: set to the preimage nonce exposed as field `0` in the invoice +* [`u64` : `invoiceamount`]: set to the amount in msat requested by the invoice + +## Proof of Payment + +In order to prove a successful payment and get access to the purchase, the `deputy payment preimage message` is used. This is an offline data transmission message (see BOLT-12) sent by the payer to the point of sale using a transmission medium supported by both parties. + +The message consists of the following parts: +* [`2*byte`:`type`]: set to `0x0` +* [`32*byte`:`preimage`]: the preimage of the payment + +## Deterministic preimage generation + +As only the point of sale and the recipient node MUST use the same preimage generation process, this process itself shall not be part of the LN specification. However, there are certain things to consider when implementing such a process: + +* The minimal requested amount SHOULD be used as input parameter for the preimage generation. Thereby it is ensured that the recipient node will generate a wrong preimage and therefore fail the payment when a fraudulent sender specifies a different amount in the `invoiceamount` part of the `dpp` onion payload. +* The preimage generation process SHOULD ensure that two invoices with the same amount do not have the same preimage. The random generated preimage nonce (field `0` in the invoices / `preimagenonce` part of the `dpp` onion payload) MAY be used for this. +* Only the point of sale and the recipient node SHOULD be able to generate the same preimage. In order to achieve this, some sort of shared secret MAY be used as an input parameter for the preimage generation. + +## Data Flow + +The following diagram shows the data flow of a DPP payment: + +``` + ┌────────────────┐ + │Recipient Device│ ┌─────────────┐ ┌───────────┐ ┌─────────────────┐ ┌──────────────┐ + │(offline) │ │Sender Device│ │Sender Node│ │Lightning Network│ │Recipient Node│ + └───────┬────────┘ └──────┬──────┘ └─────┬─────┘ └────────┬────────┘ └──────┬───────┘ + │────┐ │ │ │ │ + │ │ generate invoice │ │ │ │ + │<───┘ │ │ │ │ + │ │ │ │ │ + │ present invoice │ │ │ │ + │ ────────────────────────────> │ │ │ + │ │ │ │ │ + │ │ send invoice │ │ │ + │ │ ──────────────────────> │ │ + │ │ │ │ │ + │ │ │ initiate dpp payment │ │ + │ │ │ ────────────────────────> │ + │ │ │ │ │ + │ │ │ │ route payment │ + │ │ │ │ (with dpp record) │ + │ │ │ │ ─────────────────────────> + │ │ │ │ │ + │ │ │ │ │────┐ + │ │ │ │ │ │ re-generate preimage + │ │ │ │ │<───┘ (using dpp record) + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ preimage │ + │ │ │ │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ + │ │ │ │ │ + │ │ │ preimage │ │ + │ │ │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ + │ │ │ │ │ + │ │ preimage │ │ │ + │ │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │ + │ │ │ │ │ + │ request preimage │ │ │ │ + │ (through a supported offline│ │ │ │ + │ data transfer medium) │ │ │ │ + │ ────────────────────────────> │ │ │ + │ │ │ │ │ + │ preimage │ │ │ │ + │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │ │ + ┌───────┴────────┐ ┌──────┴──────┐ ┌─────┴─────┐ ┌────────┴────────┐ ┌──────┴───────┐ + │Recipient Device│ │Sender Device│ │Sender Node│ │Lightning Network│ │Recipient Node│ + │(offline) │ └─────────────┘ └───────────┘ └─────────────────┘ └──────────────┘ + └────────────────┘ +``` + + +### Example +The following preimage formula meets all of the above requirements: + +`preimage = sha256( concat( s, n, a))` + +Whereas the parameters are defined as follows: +* `s`: shared secret only known by the point of sale and the recipient node +* `n`: preimage nonce (field `0` in the invoices / `preimagenonce` part of the `dpp` onion payload) +* `a`: minimal requested amount in msat (`amount` in the invoices / `invoiceamount` part of the `dpp` onion record) + +`sha256` is used to always get a preimage of `32 * byte` length. + +#### Point of Sale: Invoice generation example in JavaScript +```javascript +const sharedSecret = toUtf8Bytes('Sup3rS3cur3!'); +const preimageNonce = crypto.randomBytes(32); +const amountMsat = 1000; + +const preimage = sha256.create(); +preimage.update( + sharedSecret + .concat(Array.from(preimageNonce)) + .concat(this.amountInMiliSatoshisBytes) +); +``` + +#### recipient Node: Preimage reconstruction example in Go +```go +secret := []byte("Sup3rS3cur3!") +var amount = make([]byte, 8) +binary.BigEndian.PutUint64( + amount, + payload.DeputyPaymentProcessing().InvoiceAmount(), +) +nonce := payload.DeputyPaymentProcessing().PreimageNonce() + +preimageBase := secret +preimageBase = append(preimageBase, nonce[:]...) +preimageBase = append(preimageBase, amount...) + +preimageInput := sha256.Sum256(preimageBase) +preimage, err := lntypes.MakePreimage(preimageInput[:]) +``` + + +## Example Invoices +TODO diff --git a/14-authorized-payment-initiation.md b/14-authorized-payment-initiation.md new file mode 100644 index 000000000..22a99e3ef --- /dev/null +++ b/14-authorized-payment-initiation.md @@ -0,0 +1,150 @@ +# BOLT #14: Authorized Payment Initiation + +Some use cases require the ability to directly request a payment from a specific node. This BOLT defines how such payments can be initiated using `authorized payment initiation`. + +`authorized payment initiation` relies on token based authorization. Any node can request a payment from another node using the `initiate_payment` message described in this BOLT and by presenting a valid authorization token. + + +### The `initiate_payment` message + +An `initiate_payment` message MUST have the following format: + +1. type: 45001 (`initiate_payment`) +1. data: + * [`u16`:`tlen`] + * [`tlen*byte`:`token`] + * [`u16`:`ilen`] + * [`ilen*byte`: `invoice`] + +### Requirements + +The sending node: +* MUST set `invoice` to a valid payment request / invoice. +* MUST set `token` to the received authorization token. + + +The receiving node: +* if the `invoice` is not valid according to BOLT-11 + * SHOULD NOT initiate the payment. + * SHOULD respond with a `reject_payment` message. +* otherwise, if the `token` is valid for `invoice` + * SHOULD initiate the payment. +* otherwise + * SHOULD NOT initiate the payment. + * SHOULD respond with a `reject_payment` message. + +### The `reject_payment` message + +1. type: 45003 (`reject_payment`) +1. data: + * [`32*byte`:`tokenhash`] + * [`u16`:`ilen`] + * [`ilen*byte`: `invoice`] + +The sending node: +* if no peer connection is established: + * MUST establish a peer connection before sending. + * SHOULD terminate the peer connection after sending +* otherwise: + * MUST use the already existing peer connection. + * SHOULD NOT terminate the peer connection after sending. +* MUST set `invoice` to the invoice received by the `initiate_payment` message. +* MUST set `tokenhash` to the sha256 hash of the authorization token received by the `initiate_payment` message. + +The receiving node: +* MAY retry initiating the payment using a different token. + +## Token Transfer using Offline Data Transmission + +Authorization Tokens MAY be transmitted through Offline Data Transmission according to BOLT-12 using the `payment authorization` message. + + +The message consists of the following parts: +* [`2 * byte`:`type`]: set to `0x1` +* [`u16`:`ulen`]: the length of `uri` +* [`ulen*byte`:`uri`]: the URI of the node where to request the payment in the format `pubkey`@`host`:`port` +* [`u16`:`tlen`]: the lenght of `token` +* [`tlen*byte`:`token`]: the autorization token + + +### Requirements + +A message sender +* MUST set `uri` to a valid node URI, specifiying the node where the payment MAY be requested. +* MUST set `token` to a valid token. + +A message receiver +* MUST know which payment the token is intended for. +* MAY use the token to initiate the corresponding payment. +* SHOULD request the payment from no different node than the one specified in the `uri` part. + + +## Token Validity +As the receiving node of a `initiate_payment` message is the only one which MUST be able to validate authorization tokens, their concrete characteristics is not part of this specification. Therefore, node implementations are free to choose their own way(s) on deciding whether a token is valid. For example, one could require the token to be a trusted ECC signature of the respective invoice. Another approach could be limiting the tokens usage by the invoice amount or its usage frequency. + + +## Data Flow + +The following diagram shows the data flow of a payment using Authorized Payment Initiation: + +``` + ┌─────────────┐ + │Sender Device│ ┌────────────────┐ ┌──────────────┐ ┌───────────┐ ┌─────────────────┐ + │(offline) │ │Recipient Device│ │Recipient Node│ │Sender Node│ │Lightning Network│ + └──────┬──────┘ └───────┬────────┘ └──────┬───────┘ └─────┬─────┘ └────────┬────────┘ + │ request invoice │ │ │ │ + │────────────────────────────> │ │ │ + │ │ │ │ │ + │present invoice │ │ │ │ + │(through a supported offline│ │ │ │ + │data transfer medium) │ │ │ │ + │<─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │ │ + │ │ │ │ │ + ────┐ │ │ │ │ + │ generate auth token │ │ │ │ + <───┘ │ │ │ │ + │ │ │ │ │ + │send token │ │ │ │ + │(through a supported offline│ │ │ │ + │data transfer medium) │ │ │ │ + │────────────────────────────> │ │ │ + │ │ │ │ │ + │ │ send token │ │ │ + │ │ ─────────────────────────> │ │ + │ │ │ │ │ + │ │ │ open peer connection │ │ + │ │ │ (if necessary) │ │ + │ │ │ ──────────────────────────>│ │ + │ │ │ │ │ + │ │ │ feature bits │ │ + │ │ │ <─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │ + │ │ │ │ │ + │ │ │────┐ │ │ + │ │ │ │ validate feature bits │ │ + │ │ │<───┘ │ │ + │ │ │ │ │ + │ │ │ initiatate payment │ │ + │ │ │ (initiate_payment message) │ │ + │ │ │ ──────────────────────────>│ │ + │ │ │ │ │ + │ │ │ ────┐ │ + │ │ │ │ validate token │ + │ │ │ <───┘ │ + │ │ │ │ │ + │ │ │ │ │ + │ │ ╔══════╤═════════╪════════════════════════════╪═════════════════════════╪═════════════════╗ + │ │ ║ ALT │ token is valid │ │ ║ + │ │ ╟──────┘ │ │ │ ║ + │ │ ║ │ │ initiate payment │ ║ + │ │ ║ │ │────────────────────────>│ ║ + │ │ ╠════════════════╪════════════════════════════╪═════════════════════════╪═════════════════╣ + │ │ ║ [token is not valid] │ │ ║ + │ │ ║ │ reject payment │ │ ║ + │ │ ║ │ (reject_payment message) │ │ ║ + │ │ ║ │ <──────────────────────────│ │ ║ + │ │ ╚════════════════╪════════════════════════════╪═════════════════════════╪═════════════════╝ + ┌──────┴──────┐ ┌───────┴────────┐ ┌──────┴───────┐ ┌─────┴─────┐ ┌────────┴────────┐ + │Sender Device│ │Recipient Device│ │Recipient Node│ │Sender Node│ │Lightning Network│ + │(offline) │ └────────────────┘ └──────────────┘ └───────────┘ └─────────────────┘ + └─────────────┘ +```