Skip to content

LUD-XX: Signed LNURLs#91

Open
chill117 wants to merge 1 commit into
lnurl:ludsfrom
chill117:lud-21-signed-lnurls
Open

LUD-XX: Signed LNURLs#91
chill117 wants to merge 1 commit into
lnurl:ludsfrom
chill117:lud-21-signed-lnurls

Conversation

@chill117

Copy link
Copy Markdown
Contributor

No description provided.

Comment thread 21.md
"encoding": "hex"
}
```
Possible values for `"encoding"`:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why do we need to support different encodings?
I think just going with hex is better to keep the protocol simpler.

@chill117 chill117 Sep 11, 2021

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Why do we need to support different encodings?
I think just going with hex is better to keep the protocol simpler.

Flexibility. The bleskomat-server, lnurl-node module (JS), lnurl-platformio (C++), and the bleskomat extension (python) for lnbits all support the three different secret key encodings described here.

Comment thread 21.md
* `"hex"` - Hexadecimal encoded
* `""` (empty-string) - Unencoded / plaintext (utf8)

The `"id"` should be a unique identifier so that an individual authorization key may be found by this value.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Isn't key already the identifier?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Isn't key already the identifier?

The identifier is needed to perform the authorization key look-up and signature check in the service side.

Comment thread 21.md
These steps are to be done by an authorized application.

1. __Build the base URL__ in the same way that your service would normally less the `k1` or secret value. For example, if your service generates withdraw links like https://example.com/lnurl?tag=withdraw&amount=5&currency=EUR&k1=0aa4a2285fb16207865c87c28bb0d78f42248f3077aba917c2f55b6be51e5e3d where `k1` is the secret that makes the link unique and acts as a secret (or password) which grants access to the URL. The `k1` can be left out here because we are using signing to authorize the creation of the URL in the server. So the example URL here would be as follows:
* https://example.com/lnurl?tag=withdraw&amount=5&currency=EUR

@hsjoberg hsjoberg Sep 10, 2021

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It looks like ¤ gets rendered as an HTML entity.
But AFAICT currency param is not the withdraw spec anyway so this could be removed.

@chill117 chill117 Sep 11, 2021

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It looks like ¤ gets rendered as an HTML entity.
But AFAICT currency param is not the withdraw spec anyway so this could be removed.

There are no explicitly required query parameters for the URL that ends up serving an LNURL response object. That's why I made this a simple example using only the tag, amount, and currency. The example URL here is not the callback URL as described in the other LUDs. This is the URL for the initial request, which will contain the callback URL in its response object.

Comment thread 21.md
* If the signature __does not__ match, then fail the request.
* If the signature matches, then continue with the service's normal LNURL flow.

_Optional_ steps to generate a deterministic value to be used as the `k1` or identifier of an LNURL record:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think this can be optional. This makes LUD-21 incompatible with the base withdraw spec LUD-03.

Specifically:

  1. Once accepted by the user, LN WALLET sends a GET to LN SERVICE in the form of
 <callback>
     <?|&> // either '?' or '&' depending on whether there is a query string already in the callback
      k1=<k1> // the k1 specified in the response above
     &pr=<lightning invoice> // the payment request generated by the wallet

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's optional because you don't need to deterministically generate the k1 from the signed URL. The service can randomly generate the k1 and use that in the response object. This would mean that your service will accept any and all valid, signed LNURL and never check for re-use. Or you could find some other way to prevent re-use of signed LNURLs.

@fiatjaf

fiatjaf commented Sep 10, 2021

Copy link
Copy Markdown
Collaborator

I like this thing very much, it's what Bleskomat uses, right?

But I don't understand how it fits in a LUD, since it's not something a wallet should, can or need to implement. It just works today already with existing wallets, right?

And services like Bleskomat already use it today. Also, I don't see any benefits to standardization of this scheme. If someone makes a Bleskomat clone that uses a different signing algorithm, for example, is that worse than if they used this?

@chill117

chill117 commented Sep 11, 2021

Copy link
Copy Markdown
Contributor Author

I like this thing very much, it's what Bleskomat uses, right?

Yes, this is the signing scheme that Bleskomat uses to create signed lnurl-withdraw URLs that are then encoded as QR codes.

But I don't understand how it fits in a LUD, since it's not something a wallet should, can or need to implement. It just works today already with existing wallets, right?

And services like Bleskomat already use it today. Also, I don't see any benefits to standardization of this scheme. If someone makes a Bleskomat clone that uses a different signing algorithm, for example, is that worse than if they used this?

The LUDs describe the LNURL protocol as to be implemented by both services and wallets. Services implement parts of the spec and wallets implement other parts. In the case of this new LUD, only the service will have to implement any changes. The wallet will request the URL the same as it would any other LNURL.

I used the term "authorized application" in the context of this document to describe a third, more general group of applications - i.e. not just wallet applications. This group can implement the signing scheme which can then work with any service that supports it.

I created a LUD because it could be a useful thing to standardize so that others could make their service or "authorized application" compatible with each other.

Comment thread 21.md
* https://example.com/lnurl?tag=withdraw&amount=5&currency=EUR
2. Add the authorization key's identifier to the URL's query string as follows:
* https://example.com/lnurl?tag=withdraw&amount=5&currency=EUR&id=935e30a7
3. Generate a unique, random nonce and add it to the query string:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Unique is enough, doesn't need to be random. (And actually just incrementing a number by one and storing in persistent memory may be safer - no RNG vulnerabilities possible.)

@andrerfneves andrerfneves added stale No activity for 12+ months. Will be closed in 30 days if no further action. idea Early-stage proposal or discussion, no spec written yet new-lud Brand new protocol extension proposal labels May 25, 2026
@andrerfneves andrerfneves changed the title LUD-21: Signed LNURLs LUD-XX: Signed LNURLs May 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

idea Early-stage proposal or discussion, no spec written yet new-lud Brand new protocol extension proposal stale No activity for 12+ months. Will be closed in 30 days if no further action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants