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

LNURL Allowance #49

Closed
wants to merge 5 commits into from
Closed

LNURL Allowance #49

wants to merge 5 commits into from

Conversation

andrerfneves
Copy link

Notes

After much deliberation we're putting forward the first version of what we believe to be a good, yet very minimal, spec for a LNURL Allowance flow. On our side, the idea behind LNURL Allowances started with Christian's Lightning Network Gaming Hackathon demo, but it was also explored on Lightning Joule's Allowances feature. Since then we've been trying to create a more standardized approach to this new feature that would fit into the larger LNURL group of Lightning UX Specifications for Wallets and Services.

This PR is the first iteration of it after long discussions with @fiatjaf and @mandelmonkey. We're now looking for feedback/contributions on it, and hope to have some demo implementations on Wallets/Services in the coming weeks. On ZEBEDEE's side we're really excited about what this brings to the usability of Lightning in gaming environments. We plan to add this feature to both our Android/iOS mobile wallet, as well as our set of APIs, thus allowing Game Developers building on ZEBEDEE's set of APIs and SDKs to make use of this feature as well.

  • e.g. being able to scan a single QR at the beginning of your interaction/gameplay, stipulate a spending amount and then enjoy the experience without the burden of scanning QR codes for every interaction.

That being said, LNURL Allowance is meant to be a service-type-agnostic solution and does not ONLY solve our problems. We have seen interest to introduce similar functionality to Lightning services of various other types/characteristics.

Additional

I've added a Known Issues section at the very end given that maintaining WebSocket connections active on Mobile devices can be rather tricky.

I will also be adding a diagram similar to this one to the PR once it's been more finalized/worked out/modified due to community feedback. The diagram linked above was the very first iteration of this specification, and is not meant to be followed. These diagrams have helped me explain/illustrate the concept more clearly.

{
socket: String, // the URL from LN SERVICE which will accept the WebSocket connections from the WALLET
k1: String, // random or non-random string to identify the WALLET when receiving connection to socket
recommendedAllowanceAmount: Millsatoshis, // amount of satoshis the SERVICE recommends WALLET to ask user for this allowance/pairing
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could this be changed to minAllowanceAmount and maxAllowanceAmount, like with LNURL-withdraw?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the setup we put forward, the WALLET is constantly telling the SERVICE their balance through the balance message (which also serves as a PING). The reason we don't set a maximum amount is that if the WALLET runs out of funds, we'd need to have another message type to requestNewAllowance sort of thing. If the WALLET/user would like to increase their balance, we can let the WALLET handle that, and provide easy-to-use buttons/UI to handle the add 5000 sats to balance sort of thing. The SERVICE just needs to receive that value and know whether the balance is enough for given interaction/gameplay/whatever. By setting an upper bound limit, we also increase the amount of interaction the user would have to go through to increase it.

The idea behind a recommendedAllowanceAmount is that the SERVICE can let the WALLET know what they recommend: e.g. in a game scenario, let's say you usually/likely need 1000 sats to complete the given mission, therefore the SERVICE can suggest/recommend 1000 sats, and you as the WALLET owner can complete given mission before having to increase balance. If we don't set a minimum/recommended value, the WALLET could default to 50 sats for example, and then the user has to stop and increase their balance right away. The goal for this spec is to minimize the burden around user interactions for little microtransactions like this.

I'm not against the idea of recommending a lower bound and an upper bound, but it should be a recommendation, not a hard limit maxAllowanceAmount if that makes sense?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for explaining

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I'm thinking that since it is just a suggestion to the wallet maybe it could have a minAllowanceAmount/maxAllowanceAmount just to be similar to the other protocols, but this is a minor thing.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not against having an upper and a lower bound defined by the SERVICE. Some questions I have:

1 - Can the WALLET put an allowance value larger than the maxAllowanceAmount?
2 - Can the WALLET put an allowance value smaller than the minAllowanceAmount?

I understand these are recommendations, but should we have them be more than that? Such that the WALLET has to perform the allowance at the very least on the minAllowanceAmount and at the very most the maxAllowanceAmount? Given the WALLET is the one that handles the actual management of the funds in the allowance, this shouldn't be an issue either way.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think the wallet SHOULD enforce that on the user, but it remains the decision of the wallet + user, in whatever decision-making process these two agree on.

README.md Outdated Show resolved Hide resolved
socket: String, // the URL from LN SERVICE which will accept the WebSocket connections from the WALLET
k1: String, // random or non-random string to identify the WALLET when receiving connection to socket
recommendedAllowanceAmount: Millsatoshis, // amount of satoshis the SERVICE recommends WALLET to ask user for this allowance/pairing
image: Base64, // base64-encoded LN SERVICE image for LN WALLET to display to user when establishing connection
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the image mimetype? I think sometimes it is necessary to know that beforehand.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah good point. Should we enforce a mimetype, or do we want to add another property for it? At that point, we may want to follow the approach for the multi-property content metadata property present in LNURL Pay?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know. That property is only there in that specific format because it needed to be hashed and included in the invoice description. There are nicer ways to do it without that constraint.

Anyway, I'm implementing this assuming images will be PNG, but I think this only matters for Telegram, and we can add an optional parameter later.

k1: String, // random or non-random string to identify the WALLET when receiving connection to socket
recommendedAllowanceAmount: Millsatoshis, // amount of satoshis the SERVICE recommends WALLET to ask user for this allowance/pairing
image: Base64, // base64-encoded LN SERVICE image for LN WALLET to display to user when establishing connection
description: String, // LN SERVICE description that LN WALLET should showcase to user
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this field be more like lnurl-auth rather than lnurl-withdraw?
Maybe what's shown to the user needs to be pulled from domain to ensure the request comes from the actual website.
otherwise anyone can put a description with a popular game and immediately withdraw all the allowance.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I agree with this. As you can see, the WALLET is responsible for doing exactly what you mentioned: you can see that here

@jarret
Copy link

jarret commented Jul 21, 2020

Ross asked me to comment here, so I am doing so. I don't consider myself a stakeholder in LNURL and well-versed in its project goals, though this is probably a concept NACK.

I previous gave my feedback to @andrerfneves and @fiatjaf in-depth in a discussion in t.me/moneysocket

In summary, I think there are shortcomings in:

  1. not accommodating for the need for SERVICEs to connect to WALLETs in addition to the setup of WALLETs connecting to SERVICEs outlined here. Many WALLETs are full nodes with fixed infrastructure and likewise, potential SERVICEs working off of mobile, dedicated hardware or browser runtime instances are quite imaginable.

  2. covering the needs for overcoming challenges of network firewalls on both ends - not all SERVICE and WALLET use cases are able to provide a full, permanent, DNSed, routable websocket server and by structuring it one way, you are leaving out those use cases. Considering compatibility with other interconnects than websocket (WebRTC, bluetooth, NFC, etc.) as well as websocket relay infrastructure might be advisable.

  3. the proposal is built around giving permission to a SERVICE you don't control to move money. I suggest a better paradigm would enable you to give permission from YOUR spending wallet to a different piece of software YOU control to automate purchasing on your behalf. This setup would make the web service you are using a WALLET (that your software automation is deciding to send money to) rather than a SERVICE (that is pulling money from your wallet at its prerogative).

Also, I have previously observed in discussion that the REST call is unnecessary since that same data could be exchanged via websocket. This would avoid needing to provide REST client/server infrastructure to implement this proposal.

@andrerfneves
Copy link
Author

andrerfneves commented Jul 27, 2020

Thanks Jarret, some of my thoughts below (more for exposure to other reviewers/commentators, as we've discussed these points ourselves before on the telegram channel).

1 - not accommodating for the need for SERVICEs to connect to WALLETs in addition to the setup of WALLETs connecting to SERVICEs outlined here. Many WALLETs are full nodes with fixed infrastructure and likewise, potential SERVICEs working off of mobile, dedicated hardware or browser runtime instances are quite imaginable.

LNURL Allowance is not solving for SERVICEs that have to connect to WALLETs. Actually none of the LNURL protocols allow for that. They are simply a set of messaging standards such that both sides (SERVICE and WALLET) can understand one another's payloads. Every LNURL interaction begins at the WALLET side. The SERVICE provides a QR code, but the WALLET is who initiates the interactions.

2 - covering the needs for overcoming challenges of network firewalls on both ends - not all SERVICE and WALLET use cases are able to provide a full, permanent, DNSed, routable websocket server and by structuring it one way, you are leaving out those use cases. Considering compatibility with other interconnects than websocket (WebRTC, bluetooth, NFC, etc.) as well as websocket relay infrastructure might be advisable.

We've discussed this before, but I'm in the mindset that using multiple messaging protocols is NOT in our best interest. Even having support for them could be tricky. That means every SERVICE or WALLET that wishes to implement LNURL Allowance will have to spend time testing/fixing/maintaining and discovering/patching edge cases for each of these protocols. Additionally, NFC and Bluetooth are physical distance and hardware dependent. WebSockets are extremely well established in the web industry and have support in most modern web clients/server frameworks and environments. No need to over complicate here.

I'd also add that most SERVICEs are cloud-hosted / self-hosted standalone boxes/servers/hardware. While WALLETs are likely on-the-go mobile devices (as well as web clients of course). Without the overhead of an always-available intermediary software like you mention below, I fail to see how WALLETs would be firewalled open to accepting connections from any SERVICE that wishes it.

3 - the proposal is built around giving permission to a SERVICE you don't control to move money. I suggest a better paradigm would enable you to give permission from YOUR spending wallet to a different piece of software YOU control to automate purchasing on your behalf. This setup would make the web service you are using a WALLET (that your software automation is deciding to send money to) rather than a SERVICE (that is pulling money from your wallet at its prerogative).

Your approach has a large requirement which is this different piece of software you control. What exactly is that? Is that cloud hosted or do you need to host it yourself? Are there specific hardware requirements? Does the WALLET provider build and maintain that for its users? Also, help me understand: if you/your wallet are simply giving spending permission to this secondary software that you control to do the spending on your behalf, how is that different? Isn't this just another step that's added? Do you pay this secondary software the total allowance amount, and then the balance and payments are handled by that software? What sort of security measures would this secondary software have that would be an added bonus, and which simply cannot be part of the WALLET software itself? Apart from the example you've mentioned a few times of the pay-per-livestream scenario, I have yet to find a concrete use-case where a SERVICE would initiative the interaction with the WALLET. At that point, shouldn't there be some form of business logic that allows a external SERVICE to possibly send a push notification / alert / webhook to request action on the WALLET side (essentially asking for the WALLET to start the interaction)?

4 - Also, I have previously observed in discussion that the REST call is unnecessary since that same data could be exchanged via websocket. This would avoid needing to provide REST client/server infrastructure to implement this proposal.

While this is technically true, it also goes against the current paradigm for all LNURL protocols. The first GET call is for a give me the details and then follows a set of actions. We want LNURL Allowance to be low in development efforts and keep parity with the other LNURL protocols. It also allows for a clean way to provide properties/details of this Allowance, same way it does for Pay and Withdraw.

@rafaelpac
Copy link

A couple months ago I was thinking about something similar to this.
I have it half-written here somewhere, I called it LNURL-pre-pay.

I was thinking about IoT devices that need to charge a price, but the price is not yet known beforehand.
Examples: gasoline pump, rental bicycle... (any bulk purchase or rental machine service).
Instead of maintaining a connection between wallet and service, the wallet would know that this is a pre-payment and it would:

  • pay a regular LNURL-pay payment, plus
  • send, as the comment string, an amountless invoice (or its own LNURL-pay static string, Zebedee user id, lntxbot user...).

The service now receives that maximum amount and knows that it can use it.
There could be a suggested amount provided by the service, or max/min, as discussed above.
At the end, any change left is paid back to the wallet.
The end happens either when the funds end or when the user activates the end (the user signals to the service that it is enough of that product, service...).

Reading this proposal, I now just had the idea on embedding in it an option to quickly add more funds to the pre-payment, to prevent the service from stopping abruptly in case it uses all the funds.

@hsjoberg
Copy link
Collaborator

hsjoberg commented Oct 1, 2021

Closing this as we've moved to the LUD system. A new pull request can be opened.

@hsjoberg hsjoberg closed this Oct 1, 2021
@danarchos
Copy link

A new PR never seemed to open for this, what is the current status on allowances? @andrerfneves

@andrerfneves
Copy link
Author

We've yet to re-draft this, but someone else needs to champion it atm.

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

Successfully merging this pull request may close these issues.

None yet

8 participants