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

NIP-47: Nostr Wallet Connect Extensions #685

Merged
merged 1 commit into from
Jan 26, 2024

Conversation

benthecarman
Copy link
Contributor

Have gotten requests for things like this from various users. This handles the receive side of nostr wallet connect

@fiatjaf
Copy link
Member

fiatjaf commented Jul 27, 2023

@vitorpamplona @jb55 @bumi @v0l

@vitorpamplona
Copy link
Collaborator

I am not sure why you would receive via Wallet Connect instead of the usual lnurlp request from the profile, but sure.

We can also just update NIP-47 with these new instructions instead of creating a new NIP.

@benthecarman
Copy link
Contributor Author

I am not sure why you would receive via Wallet Connect instead of the usual lnurlp request from the profile, but sure.

because that requires a web server, this does not

@benthecarman
Copy link
Contributor Author

We can also just update NIP-47 with these new instructions instead of creating a new NIP.

yeah NIP-47 says they will be defined in other NIPs so i made another

@jb55
Copy link
Contributor

jb55 commented Jul 27, 2023 via email

@vitorpamplona
Copy link
Collaborator

vitorpamplona commented Jul 27, 2023

yeah NIP-47 says they will be defined in other NIPs so i made another

I think we meant in new PRs. At the time, it looked like each PR with something new was a new NIP. Thus the confusion. So, feel free to change NIP-47 directly.

@v0l
Copy link
Member

v0l commented Jul 27, 2023

How can we allow anybody to fetch an invoice though, NWC connection is secret, this would only allow the owner of the wallet to generate an invoice?

@jb55
Copy link
Contributor

jb55 commented Jul 27, 2023 via email

@benthecarman
Copy link
Contributor Author

benthecarman commented Jul 28, 2023

How can we allow anybody to fetch an invoice though, NWC connection is secret, this would only allow the owner of the wallet to generate an invoice?

you can have multiple connections for different use cases, NIP-47 already defines the info event to list out all the available functions

does it make sense to wrap this into the NWC nip? It seems standalone
and has different security properties.

I think it makes sense to keep together, no need to re-invent the wheel, all these permissions issues should be handled client side validating the requests. This should be done for invoices already (don't pay a 1 bitcoin invoice) so I don't see the added complexity if you want to have the receive functionality

@rolznz
Copy link

rolznz commented Jul 28, 2023

How can we allow anybody to fetch an invoice though, NWC connection is secret, this would only allow the owner of the wallet to generate an invoice?

you can have multiple connections for different use cases, NIP-47 already defines the info event to list out all the available functions

So you would create a new NWC connection that only has permissions for get_invoice, then give out the private key for it to those users who need to create an invoice? This is quite interesting, as long as users make sure to set the right permissions otherwise their wallet could be drained.

For example you could add the private key of the NWC connection in your nostr profile metadata and then you could receive lightning payments without needing a lightning address? (and then some further thought is needed on how to do zaps over NWC)

@benthecarman
Copy link
Contributor Author

For example you could add the private key of the NWC connection in your nostr profile metadata and then you could receive lightning payments without needing a lightning address? (and then some further thought is needed on how to do zaps over NWC)

Potentially, just want a way to request invoices over nostr

@vitorpamplona
Copy link
Collaborator

Maybe this is a new nip indeed. Requesting invoices shouldn't require authorization. The need looks more like a data vending machine that replies when a key is pinged than a nwc action.

@benthecarman
Copy link
Contributor Author

Maybe this is a new nip indeed. Requesting invoices shouldn't require authorization. The need looks more like a data vending machine that replies when a key is pinged than a nwc action.

you guys bike shedding so much more than needed. the wallet connect functionality should have the ability to receive, that is all this does

@benthecarman benthecarman changed the title NIP-48: Nostr Wallet Connect Extensions NIP-47: Nostr Wallet Connect Extensions Jul 28, 2023
@benthecarman
Copy link
Contributor Author

Updated to just add to NIP-47

@vitorpamplona
Copy link
Collaborator

vitorpamplona commented Jul 28, 2023

you guys bike shedding so much more than needed. the wallet connect functionality should have the ability to receive, that is all this does

All we want is actual use. The NWC could do a whole lot of things. But we later realized all people really wanted was a way to pay without leaving the app. Not even the wallet status event was actually needed.

The NWC is a local setup. Only the logged-in user will be able to call his own wallet connect service to get an invoice from his wallet. As it stands, the change alone doesn't seem to be a replacement for the public lnurlp resolution when asking for an invoice from somebody else's wallet.

@benthecarman
Copy link
Contributor Author

As it stands, the change alone doesn't seem to be a replacement for the public lnurlp resolution when asking for an invoice from somebody else's wallet.

you can build zaps on top of this, you can build a lightning address server on top of this, you can build a webstore on top of this.

the point of this is to allow the functionality of requesting invoices, not building a specific app/use case like zaps

@v0l
Copy link
Member

v0l commented Jul 28, 2023

A simple solution to enable everybody to request invoices is to use the public key of the secret key issued by the NWC service.

Same flow as before except you include an extra p tag:

{ 
  ...,
  "kind": 23194,
  "pubkey": "<requesting_persons_pubkey/any_random_key>",
  "content": nip04_encrypt(JSON.stringify({
      "method": "get_invoice",
      "params": {
          "amount": 123,
          "description": "some description", 
          "description_hash": "31afdf1..",
          "expiry": 3600,
      }
  })),
  "tags": [
    ["p", "<wallet_service>"],
    ["p", "<pubkey_of_NWC_secret>"]
  ]
}

Add profile entry:
"nip47": "nostr+nip47-zap:b889ff5b1513b641e2a139f661a661364979c5beee91842f8f0ef42ab558e9d4?relay=wss%3A%2F%2Frelay.damus.io&pubkey=71a8c14c1407c113601079c4302dab36460f0ccd0ad506f1f2dc73b5100e4f3c"

@benthecarman
Copy link
Contributor Author

@v0l why would you do that? That reduces privacy because it is no longer encrypted and is no longer compatible with NWC

@v0l
Copy link
Member

v0l commented Jul 28, 2023

@v0l why would you do that? That reduces privacy because it is no longer encrypted and is no longer compatible with NWC

I never said it wasnt encrypted

@benthecarman
Copy link
Contributor Author

what you posted is in raw json

Copy link
Member

@v0l v0l left a comment

Choose a reason for hiding this comment

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

There is no reason why this can't be merged already right?

@vitorpamplona
Copy link
Collaborator

I still don't see this working in the way people are discussing here, but if we have an implementation that is using it, it should be merged.

@jb55
Copy link
Contributor

jb55 commented Aug 3, 2023

so from what I understand, this is not an lnurl replacement, as that would need a different spec. this is just for fetching invoice from your own node?

@benthecarman
Copy link
Contributor Author

so from what I understand, this is not an lnurl replacement, as that would need a different spec. this is just for fetching invoice from your own node?

You could build that spec with this. This is just the core functionality of fetching the invoice

@bumi
Copy link

bumi commented Aug 3, 2023

A few thoughts on the naming:

get_invoice sounds to me a bit like it is looking up an invoice (similar to invoice_status)
I would also love to stick to existing namings e.g. make_invoice (which is for example used in webln)

so my proposal would be

  • make_invoice to request a bolt11 invoice and
  • lookup_invoice to get the invoice status

for some apps it would also be great to lookup an invoice based on the bolt11 invoice otherwise those apps would need to parse the bolt11 invoice and get the payment hash first (which in some environments is annoying)

generally I am +1 for this and I am with @benthecarman. (Going forward I could even imagine adding more wallet calls here.)

@benthecarman
Copy link
Contributor Author

@bumi good suggestions, added

I have implemented this in https://github.com/benthecarman/nostr-wallet-connect-lnd

@supertestnet
Copy link

supertestnet commented Aug 7, 2023

It looks like this spec-change has been approved and is now live in a popular NWC implementation. Can it be merged so that other client devs know how to interoperate? This would help ensure different implementations use the same api for the same functionality, and it would help client devs like me know what api methods to call if they want to use this functionality

@benthecarman
Copy link
Contributor Author

Changed the expires tag to expiration because it seems that is standardized for other applications

47.md Outdated Show resolved Hide resolved
47.md Show resolved Hide resolved
47.md Show resolved Hide resolved
@benthecarman benthecarman force-pushed the nwc-extensions branch 3 times, most recently from b65f871 to a0ae21c Compare December 22, 2023 06:24
@Egge21M
Copy link
Contributor

Egge21M commented Dec 26, 2023

Maybe we can use this PR to also clear up some inconsistencies that I have encountered while working on a NWC focussed project. Those changes mostly concern the documentation and not the protocol itself.

  • NIP provides an example URI without a proper authority component ("//" between host and scheme are missing), while implementations in the wild include it.

  • NIP does not have an opinion about URL-unsafe query parameters, which IMHO it should (e.g. taken from an Alby connection string "?relay=wss://..."

Let me know if this should be a separate PR or if you want to include these changes in this proposal.

@benthecarman
Copy link
Contributor Author

@Egge21M seems out of scope for this PR but I definitely think those would be good changes.

@Egge21M
Copy link
Contributor

Egge21M commented Dec 26, 2023

@benthecarman copy that and I am aligned. I'll suggest some clarifications in another PR.

@v0l
Copy link
Member

v0l commented Jan 2, 2024

@rolznz I see alby NWC is responding to list_transactions now, but all the timestamps are strings instead of numbers

{
    "type": "outgoing",
    "invoice": "xxx",
    "description": "sats for [email protected]",
    "description_hash": "",
    "preimage": "yyy",
    "payment_hash": "xxx",
    "amount": 5000,
    "fees_paid": 0,
    "created_at": "2024-01-02T15:52:49.963Z",
    "expires_at": "2024-01-02T16:07:47Z",
    "settled_at": "2024-01-02T15:52:49Z"
}

@rolznz
Copy link

rolznz commented Jan 4, 2024

list_transactions now, but all the timestamps are strings instead of numbers

@v0l sorry about that, I have created an issue here.

@benthecarman
Copy link
Contributor Author

benthecarman commented Jan 10, 2024

How close are we on merging this? Seems like we have 3 implementations in alby, snort/iris, and rust-nostr with no further comments

```

Errors:
- `PAYMENT_FAILED`: The payment failed. This may be due to a timeout, exhausting all routes, insufficient capacity or similar.
Copy link

Choose a reason for hiding this comment

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

This error could also apply to pay_keysend. Should we add it there?

@rolznz
Copy link

rolznz commented Jan 11, 2024

How close are we on merging this? Seems like we have 3 implementations in alby, snort/iris, and rust-nostr with no further comments

Alby has mostly finished the implementation except for multi_pay_invoice and some minor stuff like paging which we won't do now.

Regarding multi_pay_invoice, we also thought multi_pay_keysend makes sense, since many V4V podcasts have multiple splits (and having support for split payments in NWC would be great). Unfortunately the payment hash in individual responses cannot be used like in multi_pay_invoice (specifying preimage in the request is optional and we thought forcing the app to provide a preimage for each split is not a good solution. Returning an index for each response could be one possible way, unless there is a better idea).

Otherwise I think @bumi is happy to merge and already approved from the Alby side.

@aChrisYouKnow
Copy link

Have been lurking this thread, finding a way to do multi_pay_keysend would be really nice if there was a way to do it. I guess the alternative would be the podcast apps (clients) would send multiple requests, one for each split, and the wallet service would pay each one individually?

@benthecarman
Copy link
Contributor Author

Yeah we could do mutli pay keysend but instead of tagging the payment hash, do the pubkey

@rolznz
Copy link

rolznz commented Jan 11, 2024

Yeah we could do mutli pay keysend but instead of tagging the payment hash, do the pubkey

Unfortunately this will not be enough to work for mapping responses for keysend payments to custodial wallets that use the 696969 record

Would it be possible to add an extra optional 696969 tag in the response for that case along with the pubkey?

We are actively trying to push self-custody (and NWC helps make this migration much more seamless) but without able to get responses for all splits, podcasting clients might not use it (and end up using one request per split with the pay_keysend method).

@benthecarman
Copy link
Contributor Author

benthecarman commented Jan 11, 2024

The 696969 tag is kinda ugly, we could remove the payment hash stuff and just add an id or something to the params and put that in the tags

@benthecarman
Copy link
Contributor Author

Added the id tagging, think this is cleaner

47.md Show resolved Hide resolved
@benthecarman
Copy link
Contributor Author

image

@TonyGiorgio
Copy link

LGTM

@pablof7z pablof7z merged commit ff8e204 into nostr-protocol:master Jan 26, 2024
@benthecarman benthecarman deleted the nwc-extensions branch January 26, 2024 15:56
@pablof7z
Copy link
Member

We have two implementations of this (Mutiny.+ Alby); looks like this simply fell through the cracks so merging.

@rolznz
Copy link

rolznz commented Apr 6, 2024

I really wish the wallet service provided information in the kind 13194 instead of a request/response. The Nostr way is to simply subscribe to that event and the client will receive all updates when they happen. There is no need to make a separate request for that information.

It's similar to list_payments and list_invoices. We already have a filter API in Nostr. There is no need to recreate them as RPC calls.

I have created a PR for notifications which is based on this idea, for cases where it does not make sense or is inefficient to have to request first. #1164

I would love any feedback!

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.