Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Podcast] Add support for LSAT for HTTP requests #1010

Open
bumi opened this issue Dec 4, 2022 · 12 comments
Open

[Podcast] Add support for LSAT for HTTP requests #1010

bumi opened this issue Dec 4, 2022 · 12 comments

Comments

@bumi
Copy link

bumi commented Dec 4, 2022

LSAT is a HTTP based authentication scheme that defines a protocol to exchange lightning payment information on the HTTP level. It is intended to communicate a payment request from the server to the client and to allow the client to authenticate requests using the lightning payment information (preimage).

Thanks to the protocol client and server do not need to know of each other before the request and payments an be incorporated in the HTTP request flow (for the feed and episode files)

This protocol fits perfectly for the podcasting world where a player talks to various hosters and requests the feed and the episode files through HTTP.

Adding support for LSAT gives podcasters an additional monetization option.
It is an open, flexible alternative for example for some podcasters publishing special episodes on tools like patreon or provide special private RSS feeds to a paying user community.
Using LSAT this can be handled with the normal feed and gives the user the choice within the player (no need to go to third-party apps like Patreon before hand)

Simple example flow (sorry for the lazy diagram):

(user could configure to prefer the payment authenticate content per podcast or globally)
client ---> HTTP request indicating LSAT support ----> server
client <--- 402 status code with a payment request <--- server
(user could be prompted here, or a config option could allow auto payments like in the streams)
client ---> HTTP request with payment proof ---> server
client <--- actual requested resource <--- server
(client stores the authentication details for future requests)

If a client does not support LSAT the server simply returns the public response, but if the client supports LSAT (indicating this with the Accept-Authenticate: LSAT HTTP header) the server returns an authenticate response.

Here is an example JavaScript implementation to handle the LSAT handshake with fetch() and use webln to send the payment: https://github.com/getAlby/alby-tools/blob/master/src/lsat/fetch.js

Open for discussion:

  • How can this be integrated with the splits? Is the hoster/server responsible to handle this? How can the client provide payment details for multiple split payments and how can the server validate this (if needed?)?

Links

@kingonly
Copy link
Member

kingonly commented Dec 4, 2022

Thanks for opening the issue @bumi 🙏
In order to implement it for podcasting, I believe we need some kind of marker in the splits (to know which payment proof to send), right?

@bumi
Copy link
Author

bumi commented Dec 6, 2022

I think this must work without any adjustment on the value tag. Initially I thought of it completely independent (and it could be independent).
Can we assume that whoever hosts the feed/episode also knows about the splits? And I can not wrap my head around the keysend based verification right now, can you mention again your thoughts there?

(with an invoice the server would typically simply check the payment hash and does not need a node connection.)

@kingonly
Copy link
Member

kingonly commented Dec 6, 2022

My idea is simple: keysend works (at least in lnd, need to verify cln) by creating an invoice on-the-fly. It returns a preimage. We need to use the preimage that keysend returns and send it back in LSAT. However, we need to know which preimage from the splits to use, hence - a need for a marker in the split. Just an optional tag on one of the splits will do. It's backward compatible and shouldn't break anything.

@bumi
Copy link
Author

bumi commented Dec 12, 2022

What will the server use to lookup the invoice and validate the payment?

(The nice thing about the invoice is that the server does not need to connect to a node to do the validation - the preimage + the payment hash from the invoice is enough)

@kingonly
Copy link
Member

kingonly commented Dec 12, 2022

There's still a preimage. The only difference from a regular invoice is that the invoice is created on-the-fly when the payee receives the keysend. If you don't want to ask the node to validate, I can think of several solutions like sharing the hashes with the server prior to the payment or at settlement.

@adamc199
Copy link

  • I think the podcast GUID is a good way to locate the value block split details

@kiwiidb
Copy link

kiwiidb commented Dec 16, 2022

Which hash would the server use in the macaroon in the first step of the LSAT handshake? Would it need to return a macaroon at all, or would the first step even be skipped completely? Would the client just request the file with the preimage in the header without any macaroon?

My main problem with trying to make keysend fit into LSAT we would be throwing away the central idea of LSAT, namely the cryptographic link between invoice and macaroon.

@kingonly
Copy link
Member

The LSAT can contain the specific split that should be used.
It's not really trying to make keysend fit rather trying to keep the splits.
The client understand which split they should reference from the LSAT, they make the keysend, get the preimage and send it back. I think it works nicely, nothing added to the value block, and even maintains the WWW-Authenticate semantics imo.

@kiwiidb
Copy link

kiwiidb commented Dec 19, 2022

But which hash should the server use in the macaroon? See https://lsat.tech/macaroons . Using keysend would throw away the central idea of LSAT.
Screenshot 2022-12-19 at 09 14 44

The server would also need to store state to keep track of which preimages have been used for which files and check each request against this database, a pretty ugly setup in my eyes.

@kingonly
Copy link
Member

Why does the server need a state? It can just delegate the validation to the node.
Don't get wrong, I understand what's bothering you, but I thought the requirement here is to support the splits and the value block w/o making changes to it.

@kiwiidb
Copy link

kiwiidb commented Dec 20, 2022

lsat-flow

I have attached a diagram that can illustrate how we could change the flow to support keysend payments. Instead of an invoice the first call would return the node id for which the client would need to send over payment "proof" in the second part of the handshake. The macaroon in the first step would also not contain a payment hash.

For the client there wouldn't be that many differences, however the validating server would need to hash the preimage and then look up the payment with the node using the payment hash.

@kingonly
Copy link
Member

LGTM!

  1. Would you return the amount alongside the node id? Does the amount represents the amount to be sent to the specific node id or the expected total amount?
    I think it should represent the minimum amount to be sent to the specific node.
  2. Does it matter if the node id appears more than once ain the splits? Maybe we should should choose the highest split in this case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants