lnurl / luds

lnurl specifications
584 stars 138 forks source link

Link wallet LUD #256

Open rav3r opened 5 months ago

rav3r commented 5 months ago

Hey,

We (THNDR Games) have one major UX issue when it comes to withdrawing sats from our games via Lightning Address, let me show you how it works right now:

IMG_0635

  1. Our user selects to which wallet they want to withdraw their prize (in my example ZBD)
  2. They must enter their lightning address for the first time setup.
  3. To get the lightning address our user must close the game, find the ZBD wallet on his phone, and somehow find it there.
  4. They must remember their address and find our game again on the phone
  5. Then they enter it manually

After interviewing users we found users had the following pain points with the manual process:

I propose to use LNURL to create a “One Click” solution to allow the user to auto-send their lightning address directly to the service from the wallet.

This way we can prevent human errors and jumping between apps = significantly improve UX of paying apps.

shocknet-justin commented 5 months ago

why not just use lnurl-withdraw here?

rav3r commented 5 months ago

@capitalistdog

lnurl-withdraw won't work for this use case - we don't want the receiver to manually confirm every incoming payment.

shocknet-justin commented 5 months ago

lnurl-withdraw won't work for this use case - we don't want the receiver to manually confirm every incoming payment.

gotchya... perhaps though the lnurl-p/address endpoint may be better simply as an extra parameter on the existing withdraw tag (similar to balanceNotify)

Where most wallets will already support withdraw, users will still be able to get funds out now, as opposed to an unsupported wallet not knowing the new tag at all

I think that would also be easier to implement wallet-side

rav3r commented 5 months ago

lnurl-withdraw won't work for this use case - we don't want the receiver to manually confirm every incoming payment.

gotchya... perhaps though the lnurl-p/address endpoint may be better simply as an extra parameter on the existing withdraw tag (similar to balanceNotify)

Where most wallets will already support withdraw, users will still be able to get funds out now, as opposed to an unsupported wallet not knowing the new tag at all

I think that would also be easier to implement wallet-side

Thanks this is very interesting, seems like it could be a much better solution (it would work even if someone changes his lightning address). I'll think and revise my LUD soon!

ok300 commented 5 months ago

I may be missing something, but the full flow is not clear to me:

First, the LN Wallet interacts with Service to associate a LN Address with a k1 value.

What does the other app (ZBD) do then to get or lookup the LN Address? It would need to call Service with k1 as arg, no? And if so, how does it get k1?

rav3r commented 5 months ago

What does the other app (ZBD) do then to get or lookup the LN Address? It would need to call Service with k1 as arg, no? And if so, how does it get k1?

There are two requests:

  1. LNURL
  2. Callback

The wallet calls LNURL and gets k1 and callback url, then calls the callback with k1 and the lightning address.

EDIT: Oh wait, I see what is the problem here - the service pays to the wallet, not the other way around!

arbadacarbaYK commented 5 months ago

lnurl-withdraw won't work for this use case - we don't want the receiver to manually confirm every incoming payment.

gotchya... perhaps though the lnurl-p/address endpoint may be better simply as an extra parameter on the existing withdraw tag (similar to balanceNotify)

Where most wallets will already support withdraw, users will still be able to get funds out now, as opposed to an unsupported wallet not knowing the new tag at all

I think that would also be easier to implement wallet-side

Smth similar to LUD19 (paylink discoverable from withdraw link) - but reverse. Also maybe nice within LNURLauth (lnaddress/lnurlp discoverable from lnurlauth) for login and recovery processes to be build upon.

rav3r commented 5 months ago

@capitalistdog @arbadacarbaYK

A fine-grained scheme for this use case would work better on iOS (as pointed out in LUD 17), for us this is a huge problem because people have multiple wallets and we never know which wallet will handle the link.

Now I believe the optimal solution is to combine two elements: a new lnurl scheme that enables requesting the wallet to send lnurl-withdraw to the service. Advantages of this strategy:

  1. Wallets that don't support Lightning Addresses can implement this
  2. Only wallets that support this feature will handle that scheme
  3. If the user changes their lightning address, the lnurl-withdraw can stay the same
  4. The wallet might use different lnurl-withdraws for various services, so in the future, wallets can impose distinct limits for different services.

What do you think?

shocknet-justin commented 5 months ago

I'm not clear on what the LUD17 conventions help with here, you're not using a QR so size isn't a concern, I'd think all this does it make it work with less wallets vs. LUD03

Are there any particularly popular iOS wallets that you're concerned with supporting lightning: but not LUD03? It might be easier just to get them supporting LUD03 then getting a bunch more wallets to support LUD17

Another thing to consider is that LNURL is probably not the future given it's pre-disposition to custodial solutions and only a handful of LUD's being used broadly. It's good for making things work with what exists today- not so much for getting wallets to incorporate new things.

I wont talk my stack in depth here, but mentioned to Jack that I'll reach out once I have a production demo of what we're doing for LightningVideo withdrawals since we're on the subject of new specs.

JssDWt commented 5 months ago

In general I like the idea of being able to share your address for automatic payouts this way.

About this spec: I think the k1 is not really necessary, because the initial link already has to uniquely identify the user. (if you share the same link with two users, how would you know which lightning address belongs to which user?)

In this scheme you could even put serviceName in the querystring of the initial link, so only one http request has to be made. lnurlp://...?s=my%20service. LN WALLET extracts the service name from the querystring, shows the message and then does a GET on the url with the lightning address attached.

Other idea: I also fancy the idea of the initial app giving an lnurl withdraw link. Then adding the lightning address to a newly defined query parameter to the lnurl withdraw callback for automatic handling of subsequent withdraws. The withdrawal link will work with existing wallets as well, but only those implementing the additional query parameter would be able to get the automatic payouts.

kaloudis commented 5 months ago

It would be really cool to be able to sign and prove you have control ownership of an LN address, to prevent user error, but AFAIK it's not possible - you can only prove ownership of your node pubkey

rav3r commented 5 months ago

@capitalistdog

I'm not clear on what the LUD17 conventions help with here, you're not using a QR so size isn't a concern, I'd think all this does it make it work with less wallets vs. LUD03

I meant fine-grained url schemes, not bech32 encoding.

Are there any particularly popular iOS wallets that you're concerned with supporting lightning: but not LUD03? It might be easier just to get them supporting LUD03 then getting a bunch more wallets to support LUD17

Assuming your approach (new tag with a callback to send lnurl in lnurl-withdraw) I am concerned about wallets that implement lightning: but not the new tag, so wallet A could "consume" the link even if wallet B is supporting all the features.

@JssDWt

About this spec: I think the k1 is not really necessary, because the initial link already has to uniquely identify the user. (if you share the same link with two users, how would you know which lightning address belongs to which user?)

Yes, you are right - this could work exactly like a fast withdraw.

@kaloudis

It would be really cool to be able to sign and prove you have control ownership of an LN address, to prevent user error, but AFAIK it's not possible - you can only prove ownership of your node pubkey

What is your top use case for this? Maybe we can somehow add such verification

positiveblue commented 5 months ago

Let me know if the constrains assumed here are correct:

Problem:

Current solution:

Proposed solution:

My 2 cents:

There is already a protocol that would allow this and many other use cases widely used in the industry: OAuth2. If Wallet providers implemented it (some already did, like Alby)

I think that is the road that we should follow as the industry matures: OAuth2 with a "standard" set of actions/permissions that the app can perform in the wallet (not only get the LN address's but things like load your app credit by spending from that wallet, etc..)

However, if we want something specific (simpler?) in LNURL we could copy a small part of the OAuth 2 flow.

I would keep it simple and only return "read only info". No token that can be used with the wallet api or anything like that.

The application A encoding the info in a QR may be useful if we want the user to use ANY wallet, not only the ones "approved" by the app.

Also notice that in this proposal, I can set serviceName to whatever I want to ("HI, I am Cash APP, trust me!") and the wallet will show exactly in the permissions request page. OAuth 2 solve this with a client_id/client_secret. But that means that apps need to register to be able to use the protocol with that OAuth provider. I think we need something to prevent this "attack". From well known public keys linked to well known apps to apps registering with the wallet.

jackeveritt commented 5 months ago

Data point from THNDR, in Jan '24, 84.5% of our payments went to Lightning Address enabled wallets. A one click solution to link a Lightning Address during onboarding for new users would be a great improvement!

rav3r commented 5 months ago

Let me know if the constrains assumed here are correct...

Yes, in our case we use deeplinks instead of QR codes, but the flow is exactly like you described.

  • The wallet A has an endpoint to request info about a user account (lnaddress, a bolt 12 invoice...)
  • The endpoint gets what the app is requesting and the callback URL

    • Case A) If the user IS logged in: it shows what app this is, what permissions is asking for and a button to accept/reject
    • Case B) If the user IS NOT logged in: registry/login flow with an end step redirecting to Case A

I need a small clarification here - how does the app know what is the user id? I think it must be somehow passed from the wallet to the app.

Also notice that in this proposal, I can set serviceName to whatever I want to ("HI, I am Cash APP, trust me!")...

This sounds like additional protection, I believe the whole lnurl spec needs something like this - imagine someone paying for stuff from Amazon using lnurlp, it would be cool if wallets could display a "verified" merchant badge on the invoice.

positiveblue commented 5 months ago

I need a small clarification here - how does the app know what is the user id? I think it must be somehow passed from the wallet to the app.

There is no need for the app to know what user is being linked a priory. It will basically be whoever logs in in the wallet (or is already logged in)

This sounds like additional protection

This is the first thing that pop out into my mind when I was reading the proposal. It's ok to not fix this proposal is ok, but it is good to keep in mind that this may be a security concern.

jackeveritt commented 2 months ago

We have implemented the service side of this LUD in our game "Club Bitcoin: Solitaire". Download on Apple or Google.

Here is an example of how the flow works.

Example flow

If you want to test this with your wallet or app as the withdrawal wallet, you will need to contact me so I can enable this feature on your THNDR account, as it is not available publicly.

andrerfneves commented 2 months ago

Ack

jackeveritt commented 2 months ago

Based on feedback in the telegram group. We updated the proposal to include an optional 'redirect' such that the Wallet can offer to send the user back to the Service.

We have updated our implementation to support this, if you wish to test.

Reminder: In our games, this is a hidden feature and you will need to contact me to get it activated for testing.