-
Notifications
You must be signed in to change notification settings - Fork 143
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 Over Nostr #203
base: luds
Are you sure you want to change the base?
LNURL Over Nostr #203
Conversation
What a cool idea 🤯 Some thoughts: |
XX.md
Outdated
* Wallet creates a new key for nostr and send a NIP4 to pubkey specified in nprofile, with empty content or a randomly generated string (to discuss) | ||
* Wallet watches for a reply to event id created in previous step from nprofile pubkey | ||
* Service creates a NIP4 event replying to wallet nostr event, with json parameters. In this case |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should have a custom kind instead of kind 4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking of reusing nip4 to mask usage of lnurl and make it appear as normal users messaging each other. That said, I was also debating if it should just be an ephemeral kind number and utilizing nip4 spec inside it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nip4 has in-envelope tags. just make a new tag..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nip4 has in-envelope tags. just make a new tag..
Not sure what you mean. Can you explain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nip4 defines 2 tags, "e" fir eventid and "p" for pubkey of receiver.
but yeah, a new kind is better.
relays should forward unknown kinds
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a new kind is used, one can quickly scrape how many times a specific lnurl is used, exposing sensitive business information. Tags are also unencrypted in nip4, so that would also leak such data
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tags can be encrypted im the payload instead. maybe i eas thinking of nip59
Also thought same for ages. Saves having to run server and doxing youself |
This nostr atm uses nip4 as well. The DM it says to send to specific npub in the QR includes This passing of additional data is usually done with url params, so a NostrLNURL would have to have the same ability! |
So the main drawback of profile is that it requires one more additional communication. The nevent/naddr provide an already available event with the lnurl protocol parameters. The callback is very useful as you would want to protect yourself from people analyzing all the calls to your pubkey. Competitors would know how many times your lnurl item is used very easily. Maybe we can simplify it to only point to a npub (no need for profile as relay is already connected for initial handshake) |
Id say support both. Npub is easier and will be more widely used. |
Been thinking about this a lot as well. What put me off was that you have two options:
None of it is ideal IMO. Thoughts? |
Why do social clients matter? They shoud not assume DMs are for only their platform |
A wallet could use a different npub, perhaps thats the answer, people should not use keys for both payments and messaging |
@callebtc @arcbtc I've greatly updated and simplified things by reducing many options that felt like feature creep. The way this is designed, every lnurl should be a unique nostr key. As a user consuming a lnurl, I would advise generating an ephemeral key for each call, as you don't need that metadata clutter, and everything becomes linked to your main identity otherwise (very ethereum account ish which is bad) |
Additionally, there is the callback section, where the lnurl can generate a unique key for the callback so that you can for example, send the |
working branch on implementing this |
Regarding We can do this too! The other party does not need to be online, they can simply create a filter to scan for matching events when they are back! |
Since this is an entirely different thing from LNURL I think this should be an opportunity for us to reevaluate things and fix the legacy crap LNURL has, maybe come up with something that is truly great. This, however, is just taking the crappy JSON from LNURL and putting it on Nostr. |
I'm open to it but what do you suggest to offer the least painful path to existing users and implementors? My current proposal is based on making this as minimal as possible (same structure and support for all lnurl sub specs) with the most amount of impact (no more HTTP endpoint requirement) |
This should use ephemeral-like events and should also require NIP-42 (AUTH) to prevent leakage of those events, encryption may not be required then. As with HTTP you can't guarantee that the server is up or the Nostr-LNURL service is listening nor that the requester will still be there later so there is no benefit in storing these events. |
That relies on trust on relays which is not sufficient. mandatory ephemeral events would completely remcve the ability for processing lnurl asynchronously which could be a new exciting way to do new things. A sender/receiver can have state to resume processing of even requests in mid flow. One can even use a master key for deterministic key generation for a flow so that one can store less data for such state |
I've been working on a new proposal for secure messaging over nostr with minimal public metadata. The main purpose I have in mind is secure DMs, but built in layers such that all kinds of application-specific messaging can use the same kind of messaging system and blend in with the rest. I think it would fit well with this use case. First draft PR, which just defines how such events should look to the public (includes a kind for ephemeral messages): nostr-protocol/nips#306 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The title for this document is LNURL over Nostr.
But it seems like it's really LNURL-pay over nostr.
Wouldn't it be better to support every LNURL subprotocol? They all see widespread usage.
And if not then I suggest making it clear that this is about LNURL-pay.
2. Derive its public key: `fce2b7c9aa3019e65e808f47fe8cf99ae465103737f294a0444e6c5b53dee0c7`. | ||
3. Create nprofile specifying `wss://r.x.com` as a relay hint: `nprofile1qqs0ec4hex4rqx0xt6qg73l73nue4er9zqmn0u555pzyumzm200wp3cpp4mhxue69uhhytnc9e3k7mgj4um4e`. | ||
4. Create a NIP-21 URI: `nostr:nprofile1qqs0ec4hex4rqx0xt6qg73l73nue4er9zqmn0u555pzyumzm200wp3cpp4mhxue69uhhytnc9e3k7mgj4um4e`. | ||
5. Encode it in bech32 as per [LUD-01](01.md) `lnurl1dehhxarj8fh8qun0ve5kcef3w9chxvr9vv6xsetcx3e8z7ps0p6rvut8xuekcdende6k2dr9wguh5utddcc82df4x4c857t4d4ax6v3sxpmhqvmrwpcrgmtg0p6k2d3ew45xs7t5de3njefndvmk6em2x36k6dr9ynmp4m` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we have a clean start, I suggest dropping LUD-01 and going only with LUD-17.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm good with that 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hsjoberg Coming back to this, how would this work as LUD 17 specifies the lnurl protocol over the scheme, while I use the scheme to signal it is a nostr endpoint?
"commentAllowed": 200 | ||
} | ||
``` | ||
Note that the `callback` property is optional in this variant. If specified, the next step is addressed to it; otherwise, it is addressed to the same Nostr LNURL. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like unnecessary asymmetry to make callback
optional.
Mandating it to be the same nprofile again probably better and will make hard-typed languages happy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It enhances privacy to be able to specify a completely different reply key.
I was assuming all lnurl was supported, which is how I can use for my atm. For the sanity of people implementing (although perhaps not optimal design), I cant help.thinking having it as similar as possible to LNURL the better, so they can just swap out the requests for nostr. ping pongs over ephemeral keys. |
I don't think Nostr can work as a dumb network layer that relies on other people's computer. This proposal can only work if it done in a way that makes relays a central part of it, such that users can interact only with relays that have agreed somehow to do this -- for example, the receiver of a payment may be running their own relay or may have a relationship with some other relay that allows them to use the relay for sending and receiving these messages. |
I think using Nostr has some clear extra features that HTTP doesn't have (while at the same time being worse than HTTP for some use cases), so if you just make HTTP-over-Nostr you'll just get the worst of both worlds, while if you do something that relies on Nostr properly you can get much better things. Also this poses an opportunity for us to merge lnurl-withdraw and lnurl-pay into the same thing. For example, the entire "withdraw from a service" flow could be done differently by having the service notify the user that their balance has updated instead of waiting for the user to scan a thing. Both lnurl-withdraw and lnurl-pay and also "zaps" could be condensed into a single "payment offer" For a service (or a person) that wants to sell stuff with lnurl or make lnurls that have stated purposes (i.e. they're not just donations or arbitrary payments, but they're actually tied to the delivery of some good or service) they can publish Nostr "sell offer" The entire flow can happen asynchronously over a long period of time if both parties are ok with that and the relay keeps messages around. Lightning Address in this scheme can be just a NIP-05 address. For example, I want to pay We can also have services selling stuff with Lightning Address (or nprofile/npub) by just having them publish their sell offers as events with |
No, it supports all sub-protocols, I just included a singular example. It should work for all, and if I missed something please let me know so we make sure it supports everything. I'll make it more clear it's for all. |
Why? Connecting to a public relay and sending nip4 events back and forth is equivalent to all these twitterlike clients. In any case, the use of nprofile allows the lnurl creator to advertise their own relay if need be. |
While I like a lot of this (and mentioned something similar in the first original commit and see here ), I think we should first focus on feature parity for minimum disruption. I think we can plan what you are saying as a separate...NIPLUD (🤒 what have we done). |
Yes, and they suck completely. They're completely non-scalable and they must change if Nostr is going to grow more. How on Earth are you going to know in which relay someone is publishing notes if there are a billion Nostr users? Or do you expect the top 10 relays to remain public and free and serving a billion users?
This is already an entirely new protocol with zero backwards-compatibility. Switching from the old LNURL to this will already require multiple man-hours on dozens of wallets and services. Calling Nostr relays is not as straightforward as calling HTTP endpoints. Everything is different, there are signatures, timeouts, event handling, different parsing. It makes no sense to think this will be a smooth change. We should at least make it a change worth doing by making a better protocol out of this.
I guess it should be just a NIP. There is nothing about "URLs" on it anymore. |
I expect relays to start pruning old (that was stored for free) data.
I disagree. This LUD adds an alternative communication layer and supports all current LUD interactions. Is LNURL perfect? No. Can we come up with a better protocol? Probably. But we have this with very good adoption rates, and this PR allows additional adoption to the restricted areas in the usual, ad hoc way where nothing existing breaks. I'm up for working on a better, brand new protocol in the future, but we need something now (as is evidenced by plenty of people trying to tape things together with no spec but in a very similar but uninteropable way) |
I expect relays to start pruning old (that was stored for free) data.
I disagree. This LUD adds an alternative communication layer and supports all current LUD interactions. Is LNURL perfect? No. Can we come up with a better protocol? Probably. But we have this with very good adoption rates, and this PR allows additional adoption to the restricted areas in the usual, ad hoc way where nothing existing breaks. I'm up for working on a better, brand-new protocol in the future, but we need something now (as is evidenced by plenty of people trying to tape things together with no spec but in a very similar but un-interopable way) |
Where is this happening? I am not aware know of any such efforts.
I don't see what you mean. Everything would break. A wallet supporting just HTTP-LNURL wouldn't work with a service supporting NOSTR-LNURL and vice-versa. Anyway, I see you're trying to be pragmatic, but I don't feel any desire to work on any of this if it doesn't look like a good solution to me, I just feel depressed. If the bolt12 people would stop doing their bolt12 things and unite everybody in a single protocol I could be motivated to work on this -- or if we knew of some latent use case that would be open by the implementation of this imperfect solution that would expand Bitcoin's reach, anything like that. But this I think will have no adoption, will confuse people, and get nothing done. |
Ok, well, can you NACK this then we can move on? |
I don't know how that NACK stuff works. I am just giving my opinion. |
I am going to start pushing this once more. Some points I'd like to discuss:
|
GOOD! |
IMO fiatjaf is right. Why not use NWC instead? Its nostr-native and covers LNURL-pay, LNURL-withdraw, even LNURL-check-balance. |
We're doing this more comprehensively at https://GitHub.com/shocknet/Lightning.Pub We use a proto-gen to make it both rest and nostr compatible rpc. An accounts solution is ultimately necessary as well to give it a full range of capabilities. We already power Lightning Video with it, and I welcome community involvement. |
The issue I see is that every lnurl spec would need to be re-implemented here into the new protocol. Replacing the communication line is "trivial", at least in comparison to the adoption of a whole new protocol. I also would like to reuse the same basis and potentially allow other payments to use it but signaling other payment options, so that one can do Payjoin over nostr, which functions in the same way.
I think this is beyond the scope of this feature, yours is basically a whole application stack for lightning |
Hello Regards |
@Sub7iam unfortunately I can't help. I just think you should stop dealing with these shitcoins. |
2. Derive its public key: `fce2b7c9aa3019e65e808f47fe8cf99ae465103737f294a0444e6c5b53dee0c7`. | ||
3. Create nprofile specifying `wss://r.x.com` as a relay hint: `nprofile1qqs0ec4hex4rqx0xt6qg73l73nue4er9zqmn0u555pzyumzm200wp3cpp4mhxue69uhhytnc9e3k7mgj4um4e`. | ||
4. Create a NIP-21 URI: `nostr:nprofile1qqs0ec4hex4rqx0xt6qg73l73nue4er9zqmn0u555pzyumzm200wp3cpp4mhxue69uhhytnc9e3k7mgj4um4e`. | ||
5. Encode it in bech32 as per [LUD-01](01.md) `lnurl1dehhxarj8fh8qun0ve5kcef3w9chxvr9vv6xsetcx3e8z7ps0p6rvut8xuekcdende6k2dr9wguh5utddcc82df4x4c857t4d4ax6v3sxpmhqvmrwpcrgmtg0p6k2d3ew45xs7t5de3njefndvmk6em2x36k6dr9ynmp4m` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This kind of URI misses the "route" information that lnurls contain. For example, two static lnurl-pay QR codes can refer to the same server: https://example.org/lnurlp/link1?hello=world , https://example.org/lnurlp/link2?size=big .
The current suggestion requires a new nsec/npub pair for every case.
I suggest not to use the NIP-21 URI. Instead, I suggest to encode a full url that could look like:
http://<nprofile...>.nostr1/<optional-route>?<optional-query-params>
This also goes along with @hsjoberg's suggestion to support LUD17 in the future, however I'm worried that LUD17 adoption could take a lot of time in general.
Clients already check the hostname's tld for ".onion" and use matching library for this case - so checking the tld for ".nostr1" and using another matching library will be pretty straight forward.
Notice that the tld is ".nostr1" and not just ".nostr". This will allow to support multiple protocols in the future. For example, NIP-04 for direct messages is already not-recommended and will probably be replaced by NIP-17.
For now, I think we should stick with the old direct-messages NIP-04, which is already implemented in many libraries.
3. The wallet creates a new key for Nostr and sends a NIP-4 to the public key specified in nprofile, with empty content or a randomly generated string. | ||
4. The wallet watches for a reply to the event ID created in the previous step from the nprofile public key. | ||
5. The service creates a NIP-4 event replying to the wallet Nostr event, with JSON parameters. For example: | ||
```json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the lnurl protocols already work over http - so my suggestion is simply to wrap the http requests and responses as jsons - like implemented in http2nostr and nostr2http:
A request will look like:
{
"id": "<unique-request-id>",
"url": "/route?queryparam=value",
"method": "GET",
"headers": { "user-agent": "...", "accept": "application/json" },
"bodyBase64": "..."
}
Notice that I removed the "Host" header (we don't have a hostname).
Also, it would be simple to always encode the body in base64, for simple handling and debugging in case of unexpected binary/unicode data.
The response should look like:
{
"id": "<same-unique-id>",
"status": 200,
"headers": { "content-type": "application/json", ... },
"bodyBase64": "..."
}
This is a very early draft of something I've been thinking of for a long time that allows LN wallets that are not on servers to offer LNURL endpoints.