Giter VIP home page Giter VIP logo

luds's People

Contributors

accumulator avatar akumaigorodski avatar arbadacarbayk avatar benthecarman avatar blazing-mike avatar cjc21 avatar darth-coin avatar fiatjaf avatar fittiboy avatar gcomte avatar git-sgmoore avatar hsjoberg avatar jb55 avatar kixunil avatar kukks avatar lnbc1qwfyb24 avatar merryoscar avatar michaelwuensch avatar moritzka avatar niteshbalusu11 avatar pete001 avatar prusnak avatar ramontayag avatar reneaaron avatar rolznz avatar samsamskies avatar shocknet-justin avatar torkelrogstad avatar yanascz avatar zzzhan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

luds's Issues

LUD-10: missing examples

LUD-10 doesn't clearly state what the expected structure of the decrypted content should look like. But it does say:

For message, a toaster or popup is sufficient. For url, the wallet should give the user a popup which displays description, url, and a 'open' button to open the url in a new browser tab.

From this, I infer that the decrypted content should be a proper successAction JSON object. For example, the cleartext could be:

{
  "tag": "message",
  "message": "Speakeasy passphrase: The duck quacks at daybreak."
}

However, in the example code, the cleartext is just the string: "Secret data".

Can we specify the expected structure of the cleartext ? And can we provide examples for message and url ?

about README.md

In the table of REAMD.md, why isn't there 'wallet of satoshi' at 12th category, "Comments in payRequest"??

Profesionalize RFC wordings

In order to avoid ambiguities we should check all documents and fix these things:

  • Use key words such as "MUST", "SHOULD"...
  • Make completely sure encoding of each item is defined as precisely as possible.
  • Avoid ambiguous names like "key" (private? public? symmetric? RSA? which curve? ...)
  • Mandate anything that is required for security, use "SHOULD" whenever there are privacy or other important implications.
  • Get someone not knowledgeable to proof-read the specs and get feedback on unclear things.

Somewhat related to #78 which contained multiple such errors.

payRequest multi-step overcomplicated

I went to implement LNURL-16 figuring it would be quite simple (ie request-invoice - get-invoice) but instead it requires a few hoops without any motivation for why. Specifically, the multiple requests to get an invoice may be fine, but multiple steps with server-side state required is a bunch of complication (not to mention DoS risk). Worse, using description_hash instead of description makes LNURL-payRequest/LNURL-16 harder to integrate with some standard tooling, and there doesn't seem to be any motivation listed for why the description_hash needs to match the first request (there doesn't appear to be any security motivation for it?) and without the metadata being passed back to the server.

Can we define an LNURL-21 that is just GET /.well-known/lnurlq/ that just returns an invoice. No JSON, no complexity, no server-side state, just an invoice? Or maybe remove the description_hash-matching requirement from the LNURL-payRequest requirements?

Client-side feature flags

Problem

We don't know the future how this protocol will evolve. It might occur that a change needs to be made that older clients would not understand but the server would be able to send conditional responses based on what the client supports. Without knowing if it's the case it can either not support the old clients or new features.

This problem occurred recently with allowing zero amounts in withdraw protocol.

Proposed solution

Introduce client-side feature flags. A client sends them proactively in the request to inform the server of the supported features. A server can determine how to respond based on presence or absence of flags.

Policy

Each flag is reasonably short, URL-safe, human-readable string. Protocols use special p- prefix and features that are not protocols MUST NOT use this prefix.

Feature flags are not intended to be added often. An effort must be made to find solutions to problems without introducing new flag when implementing a feature. Wallet that claims to implement a feature by sending a flag MUST implement it in it's entirety, exactly according to the spec. The flag MUST not be present if the wallet is unable to support the feature. Failing to do so may lead to various safety hazards and lost sats.

At the time of writing, these are known features (protocols):

  • p-channel
  • p-withdraw
  • p-pay
  • p-auth

Expected features to be added after accepting this proposal:

  • balance-check - this mandates that the wallet implements balance check and correctly handles zero amount as "no money available for withdraw yet"

If no flags are present the server MUST assume the wallet implements LNURL older than this spec. The client features can not be known and thus the server needs to fallback to whatever is reasonable in the context.

The wallet MAY omit p-withdraw if the inbound liquidity is zero, hinting the server that withdraw is impossible. However wallets SHOULD NOT change the features sent based on any other state o the wallet. Changing the fields can leak private information otherwise.

Implementation

The question remains how to actually send the features. These possibilities seem reasonable:

  • in query - e.g. &feat=p-channel,p-withdraw - probably simplest to implement
  • in headers - X-LNURL-features: p-channel,p-withdraw - most REST-idiomatic? Headers APIs may be bulkier and less-known
  • in payload - {"features": ["p-channel", "p-withdraw"]} - maybe good since client supports Json bodies already

I sorted them in order of my preference but I don't feel strongly about it, discussion is needed.

Concerns

Privacy

This decreases anonset of users, as the different LNURL implementations may be fingerprinted.

This should not be an issue in practice as long as the wallet used is reasonably popular. Further, differences in implementations probably exist today - different (order of) headers, fields in Json.

Not forcing wallets to implement the spec in full

There are concerns that wallets could just omit implementing some features leading to bad UX.

Firstly this is already possible:

  • wallet may choose to not implement LNURL at all, especially if it's perceived as complex
  • wallet may only implement some protocols
  • There already was an issue that a LNURL could be processed by BLW and couldn't be processed by WoS, first-hand experienced by me
  • There probably are other ways to support LNURL only partially that I can't remember now
  • Old specs can be seen in git and a lazy developer can just look them up. This works because of backcompat

Secondly, not having feature flags forces the server side to either drop support for old wallets if the new feature is more involved or not implementing new feature at all, leading to similar situation that "forcing" intended to avoid.

Thirdly, requiring a lot of features from compliant wallets makes implementation costly, leading to disincentive to implement at least a subset of LNURL. A well-defined subset is better than nothing or ill-defined subset. On the other hand, if a wallet developer has option to just write simple impl to see how well it works, he'll be more willing to do it and maybe add support later.

Finally, the surest way to add support of LNURL (or its new feature) to another wallet is by sending a PR. If the PR is ignored or rejected, the project may be dead or unreasonable and should be avoided.

Static payment method data in LUD-6

It seems like LUD-16 isn't complete without also being able to specify static invoice/invoiceless information in the LUD-6 object. It could be added easily, like so:

{
  "callback": "https://api.example.com/v1/lnurlp/dave/pay",
  "minSendable": 1000,
  "maxSendable": 1000000000000,
  "tag": "payRequest",
  "metadata": "[[\"text/plain\",\"Pay Dave Jones (@dave).\"]]",
  "staticPayment": {
    "method": "keysend",
    "address": "032f4ffbbafffbe51726ad3c164a3d0d37ec27bc67b29a159b0f49ae8ac21b8508",
    "customKey": "112111100",
    "customValue": "wal_ZmqFg135h71oek"
  }
}

This would allow for generating invoices, as normal, but also gives the staticPayment info in case the receiver also allows for static invoicing (keysend/amp/bolt12). The method would dictate the type of static info the object is describing. This is modeled off of the Value4Value spec in the podcast namespace:

https://github.com/Podcastindex-org/podcast-namespace/blob/main/value/value.md#lightning

...which has worked extremely well. Being able to use Lightning Addresses in the v4v payment blocks would need something like I'm describing here.

Misleading "supported" table for LUD-01 in README (fallback support)

Description

We've implemented the LNURL fallback scheme with URLs as outlined in LUD-01 but it seems like a number of wallets still haven't implemented this and there's no signal for which ones do.

Should we incorporate this sort of data into the compatibility table somehow as a signal to ones who don't support it yet that they should?

From my testing with the wallets I have access to I came up with the following:

Wallet Name Supports LUD-01 Fallbacks
Alby ✅ Yes
Blink (Bitcoin Beach Wallet) ✅ Yes
Blixt ✅ Yes
BlueWallet ✅ Yes
Breez ✅ Yes
coinos ❌ No (opened issue)
lnbits ❌ No (opened issue)
Muun ❌ No (opened issue)
OBW ✅ Yes
Phoenix iOS ✅ Yes
Phoenix Android ❌ No (opened issue)
Simple Bitcoin Wallet ✅ Yes
Valet ✅ Yes
Wallet of Satoshi ✅ Yes (tweeted, fixed)
Zap Android ❌ No (opened issue)
Zeus ✅ Yes

Implementation

I am trying to implement this but without luck. Found this JS implementation:
https://github.com/sipa/bech32/blob/master/ref/javascript/bech32.js
but it doesn't seem to work. I am comparing to the bech32 library and I am not receiving the same output with the same inputs.

Looking at the bottom off this python file: https://github.com/fiatjaf/bech32/blob/master/bech32/__init__.py, seems like I need to convert the data into a 5-bit array? Which isn't done by bech32.js

Found this code that should be able to convert to a 5-bit array... https://github.com/bitcoincashjs/cashaddrjs/blob/master/src/convertBits.js

It's all a mess and I'm not sure I can do anything on my own, I am not very familiar with bech32 and bit-operations in general.

I am not sure how your example works (https://gist.github.com/btcontract/a917d9b8b9b8fd53a87a81528e1274c5) because I am using the same library (I think). Installed with npm install bech32

Following the code... This line gives:
bech32.encode('LNURL', 'https://satoshis.games/withdrawal/confirmation?q=')

'lnurl1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqesxn47'

Help appreciated!

lud-16: User not found handling

Hi,
while implementing lud-16 I noticed that ln.tips and lntxbot.com both return a valid response no matter what name you input there.
zbd.gg returns an error stating "User not found".

My PR (#105 ) where it says that it should throw an error in the first json response was merged after those services implemented it.
ln.tips failed later when actually trying to make the payment.
But when sending 100 sats to a completely random lntxbot.com address the payment went through.
What do you think, should we contact them to change the behavior?

Move lnurl-auth out of the scope of lnurl, rename it

6 years ago, there was SQRL, and it was a beautiful thing which worked exactly like lnurl-auth today. Server would show a QR code with an URL containing a secret nonce, clients would scan or click, compute a public key specific for that domain, send a request to it containing the public key, the nonce and the signature.

Today, while I was reading that I couldn't help but to think lnurl-auth should actually be removed and BLW should become an SQRL client. The required changes would be minimal. The biggest contribution of BLW to the SQRL ecosystem would be linkage between the Bitcoin seed and the auth seed, which would solve a ton of problems, frankly.

However, the SQRL protocol has changed. Now it is a completely different thing with 80 pages of documentation and hundreds of different options and commands every client must send and servers must understand, it's completely crazy to expect anyone is going to implement that shit.

However, lnurl-auth is still a workable thing that could be useful in many many places, it's very easy to implement both the server and the client part, much easier than passwords.

But it shouldn't be tied to Lightning. It should be an open thing with no special restrictions on how the signing keys are to be created. They could be created from anything. There could be guidelines specific to Lightning or Bitcoin seeds, but these are not necessary for the protocol to work and shouldn't be enforceable or emphasized.

Having it in this repository is confusing, specially now that lnurl-withdraw and lnurl-login don't use the identities provided by lnurl-auth anyway (before it could make sense to keep it here) and that lnurl is going to be incorporated into the BOLTs and disappear.

Maybe it should be named "seed-auth" or something like that. Anyway, the name is not actually important as long as it doesn't imply it's part of something bigger ("lnurl") or strictly related to Lightning ("ln").

Mobile Wallets: Open LNURLs via a custom scheme such as a wallet name, e.g ZEBEDEE:

Problem
On iOS, if there are multiple wallets that support the lightning: scheme or LUD-17 then there is no mechanism for apps or games to offer a choice to the user on which wallet to open. The wallet that would open is undefined.

Idea
Wallets could publish their scheme for opening their wallet e.g. zebedee: and then apps/games can detect if the wallet exists.

If the user of the app/game wishes to open ZEBEDEE with the lnurl, the developer would be open the wallet with the following format:

zebedee:lnurlw:<insert lnurl here>

[side note, this format already works in ZEBEDEE wallet, not sure if this is by design]

The wallet could then process the lnurlw scheme as if it had been opened via lnurlw:<insert lnurl here>

This would be optional for wallets if they want to support it of course.

Change lightning: to lnurl: for App URL Schemes

By recommending that lightning: is used to open LNURLs for apps, it causes a clash with apps that don't or never will support LNURL, but use the lightning: scheme.

For example, Bottle Pay probably won't support LNURL (at least initially). And on iOS, if Bottle Pay is the last app that is installed with the lightning: scheme, any web pages or apps on the device will redirect to Bottle Pay by default, with no option to change the default behaviour in the operating system.

On Android the user can change default behaviour, but its buried in the OS settings and is a customer support issue that could be avoided.

Perhaps the scheme should be lnurl: to avoid this.

lnurl-auth IP address

I'm trying to implement this via ruby on rails. For testing, I'd like to use my laptops internal IP address. The wallets I've used so far, seem to view IP addresses as invalid LNURLs

Is there a lnurl-auth wallet I can use for IP addresses in place of domain names for development purposes?

Recurrent payments outline

Here are my thoughts on how this should look like before getting to PR:

SPEC SIDE:

  1. Recurrence points may happen MONTHLY (1st/2nd/3rd/last WEEKDAY) or YEARLY (1st/2nd/3rd/last WEEKDAY of MONTH), this is a subset of RRULE of iCal format.

  2. LNURL-PAY has an optional RECURRENCE_FIELD which contains "MONTHLY/YEARLY; PATIENCE_PERIOD_DAYS; SERVER_TIMEZONE" data. Recurrence point is determined by both WALLET and SERVICE on the day of the first successful payment (SERVER_TIMEZONE is provided to ensure that point is the same for server and client). PATIENCE_PERIOD_DAYS means "you have this many days to pay since next recurrence point until I do something about it on my side", what that something exactly is specific to service, wallet mainly needs this for grouping of events into batches and maybe warnings.

  3. metadata may contain a THIS_OCCURRENCE_NOTE field relevant for this particular occurrence which may contain free form text ("we're raising amount for you this time only because..." or "next payments will be happening annually" accompanied with MONTHLY -> YEARLY change in RECURRENCE_FIELD).

  4. Pay Json response may have an optional currentBalance field (similar to #76). If for example user has paid 3x of what was requested last time for some reason, it's up to wallet how to react to this, for example if pay Json returns 500 as payment amount but balance is 1500 then wallet may inform user that next payment is not due and allow to uncheck it for this one time. Or if user has tapped a stored pay link with recurrence, wallet may show server response along with warning that next payment is not due yet accompanied with balance, but allow user to pay anyway if user insists.

  5. Overall it is expected that WALLET re-queries a static LNURL-PAY after each recurrence point, how much is to be paid this time is defined by SERVICE each time (along with explanations in THIS_OCCURRENCE_NOTE if necessary), recurrence parameters can change (for example user has opted for YEARLY with discount whereas last time it was MONTHLY).

Recommendations for WALLET SIDE (does not go to spec but justifies spec decisions):

WALLET should convert recurrence points to days of month for each month (exact dates will differ from month to month), then try to group overlapping payments into batches such that there are as few monthly calendar reminders as possible, ideally one reminder for all recurrent events (guaranteed if all events have PATIENCE_PERIOD_DAYS=31days, but this is up to SERVICE). For example if there are two payments: first on 3rd of May with PATIENCE_PERIOD_DAYS=10days and second on 9th of May with PATIENCE_PERIOD_DAYS=5days then there will be one calendar reminder on 9th of May.

WALLET should store payment history and balance changes if applicable to provide user with context, so user can compare new info with history and for example see that "this time SERVICE wants 1000 SAT while last time it was 1100 SAT because we agreed a sum to be denominated in USD and I see that BTC has appreciated since then".

LUD-03: withdrawRequest k1 should be signed using same key derived from LUD-04

Hello. I think the k1 value used during withdrawRequest process should be signed using the same key derivation process outlined in LUD-04. That way, requests from the same domain are signed by the same key used in LUD-04, and a stored user session can also verify a wallet responding to a withdrawRequest.

This will solve the problem outlined in LUD-03 where anyone with the k1 value can submit their bolt11 invoice to be paid. With the proposed change above, sites could reuse a user's authenticated session from LUD-04 to verify a signed k1 value for processing a bolt11 withdraw.

Thank you for reading. Let me know what you think.

Allow HTTP URLs for lnurl-pay

While requiring HTTPS URLs for lnurl-pay is fine for any service offered over the internet, it sometimes make it very hard for small people who don't know or are unable to be running stuff on their own domain to accept payments in that way.

Without HTTP, it would be possible for people to use lnurl-pay inside LANs, through IPv6-powered home computers, or even to run lnurl-pay endpoints from their own phones, so easier for local merchants individuals to do this without relying on trusted third-parties.

Since lnurl-pay already relies on a final invoice issued by a Lightning server and that invoice is signed, one could optionally opt in to the HTTP verification by appending a ?pk=<lightning-node-pubkey> query string param to the initial URL that is shared with the payer.

Then, if the communication was done through HTTP and not HTTPS, the wallet would check if the initial pk matches the public key that signed the final invoice received as an extra check.

lnurl needs a way to work on the web

If your wallet is in your phone or watch, scanning a QR code and doing something with the lnurl is ok. But what if your wallet is running in your desktop or laptop? lnurl must be clickable, and it must redirect to the proper your computer somehow knows is capable of handling lightning stuff.

This isn't a big problem, but here's an issue for further reference.

Unspecified response status codes

As far as I can see this spec doesn't specify response status codes.

For example most LNURLp implementations I've come across return 200 after the call to /.well-known/lnurp/something.

I just found that this one from IBEX:

LNURL1DP68GURN8GHJ76TZV4UXSATZ9E5KYETCD4JHYCMPV3HJUCM0D5HKCMN4WFKZ7URP0YHKJMNKDA5KXEFDWFJHZATFWFJK6ETWW3EN76E385CKGCTRXCENGDPEXQURGCF5XSERWE3KVYMRXWF3VEJRWCMPVESNGVFKXY6XYCMPX4JNZD3NVCUNXDRX8P3K2ER9VCCRVVP5XGCRJEF3E60P6U

Returns 201. Understandable but there should be a clear spec.

Automatic withdrawals

Summary

I propose to specify a new protocol for automated user-friendly withdrawals. It's a smarter way to implement invoice-less sending.

Motivation

It often occurs that some kind of automated system of the payer can determine the obligation to pay. Examples include: ATMs (based on user inserting money), exchanges (based on automatic buys facilitating DCA), payroll software...

Currently the process is as follows:

  • The service must somehow notify the user about the balance (this is often, but not always during user interaction)
  • The user is requested to enter an invoice
  • The user manually creates the invoice and enters it into the system somehow
  • The system attempts to pay the invoice
  • If the attempt fails, refund needs to be processed
  • In theory, channel open with push (Turbo or not) could be offered via LNURL, which would require further manual interaction. I'm not aware of any service that provides this currently.

This process has several serious drawbacks:

  • It requires many manual steps, which isn't particularly user-friendly
  • It may be confusing for newbies
  • Amount must be correctly manually entered, amount-less invoices are insecure
  • The server has no way of determining if the wallet is compatible with LNURL protocol

As a solution I propose a new sub protocol to LNURL.

All this is based on real-life experience with various LN services, first-hand experience with customers and baristas in Paralelna Polis and discussion with Karel Kyovsky, CEO of General Bytes - Bitcoin ATM manufacturer.

Design goals

  • Sending over existing LN channels is preferred
  • The user should not be bothered with deciding which method to use
  • Provide a good fallback for scenarios where LN payment fails
  • The protocol should be well-usable for both mobile and "server" (always-online routing node) wallets
  • Specify minimum (but extensible) protocol according to current needs. The intent is to not over-specify

Disclaimer

I've read the documentation of Firebase and don't have a personal experience with it. It may happen that this specification is lacking something to actually allow push notifications.

Specification

The response message from the server is:

{
    "tag": "autoWithdraw",
    "k1" : "<RANDOM SECRET>",
    "capabilities": {
        "websocket": "wss://example.com/ws", // Websocket notification endpoint
        "fcm": "https://example.com/fcm", // Push notification registration endpoint
        "openChannel": { allowed: true, "uri": "<LN NODE URI>", "min" 100000, "fee": 1000, "spendUnconfirmedPush": true } // the server supports opening a channel. The fee is flat in satoshis
    },
    "callback": "https://example.com/withdraw",
    "singleUse": true, // if false - long-term business relationship exists, true - single interaction
    "allowPartial": false // the service may decide to allow or forbid partial withdraws
}

The wallet proceeds by subscribing to websocket or fcm providing ?k1=SECRET. In case of fcm, it provides full json that should be sent to the server in the body using POST method. The application may re-subscribe by POSTing again, which causes the json to be replaced by a new version. The server treats it as opaque data and just re-sends it when the user should be notified. The wallet can unsubscribe using DELETE method.

Websocket notifies the application by sending the same message that would be a reply of callback with action=poll (see bellow)

The callback has required parameters k1=SECRET&action=ACTION

Action may be:

  • reject - the wallet identified that the capabilities aren't appropriate and signals this to the server
  • poll - this should only be called after receiving a notification from FCM, not periodically, the server responds with message described bellow
  • invoice with additional pr=INVOICE parameter - requests withdraw, server responds with { "status": "OK" } or { "status": "ERROR", "reason": "..." } just like in case of lnurl-withdraw
  • channel - with remoteid=<local LN ID>&private=<1 or 0> parameters - request channel open like in case of lnurl-channel, the server replies with { "status": "OK" } or {"status" : "ERROR", "reason": "..." }

Response to poll:

{
 "maxWithdrawable": 10000000, // millisat
 "minWithdrawable": 1, // optional defaults to maxWithdrawable
 "defaultDescription": "<INVOICE DESCRIPTION>", 
}

The flow

  • When the user scans QR code, the wallet checks capabilities according to wallet internal policy.
  • If capabilities are fine, the wallet subscribes to updates
  • Whenever the wallet receives notification, it checks if it has enough incoming capacity for LN invoice
  • If the wallet has enough capacity, it attempts to withdraw using invoice, it attempts to open channel in case of failure
  • If the channel opening is allowed, the wallet attempts to open a channel
  • If channel open fails, the failure is presented to the user
  • If singleUse is true, the wallet discards k1 and other metadata after successful withdrawal. In case it's false, it keeps it stored and continues listening for notifications

How does this solve the situation above

  • The QR code is scanned once
  • Single QR code for invoice and channel - newbies not forced to decide
  • The protocol requires no further interaction from the user (but it might be reasonable for wallet to infomr the user about the cost of opening the channel)
  • Incompatible wallets will simply fail the protocol before any interaction is attempted
  • FCM makes sure mobile wallets can be notified
  • websocket protocol allows for "server" wallets to be notified (this doesn't need to be built-in to LN nodes - might be an external app)
  • setting allowPartial to false avoids refunding/accounting hell (as explained by Karel; big turbo channel is more practical anyway; splicing might be added in the future to avoid multiple channels)

lud-6 metadata still unclearly defined

Hi there,
lud-6 metadata is still unclearly defined, even after the last update.
Would the following "nonArrayEntry", be allowed?

[
  "nonArrayEntry",
  [
    "text/plain",
    "HfnJxZojptcreqTXkWPLT w"
  ],
  [
    "application/payer-ids",
    [
      "text/plain"
    ],
    [
      "application/pubkey"
    ],
    [
      "text/identifier"
    ],
    [
      "text/email"
    ],
    [
      "application/lnurl-auth",
      false,
      "d394e8f300e30d9aba0a1e8fc48a92a2252cfa3b215c5421b888d6884036a59b"
    ]
  ]
]

Adding encrypted/decrypted pin (used in LNURLPoS/LNURLVend) workflow to protocol?

LNURLPoS and LNURLVend encrypt a pin on each payment, which is passed to server through an LNURL-pay, then decrypted and sent back in the receipt upon completion of payment. The crypto was elegantly written by @stepansnigirev and using readily available bitcoin crypto.

On LNURLPoS the encrypted pin is added to LNURL here: https://github.com/arcbtc/LNURLPoS/blob/40cb199c4599d9f6c64b7e372a5c7938b75a83f0/LNURLPoS/LNURLPoS.ino#L232

On LNbits server side, it is decrypted and sent back as a receipt here:
https://github.com/lnbits/lnbits-legend/blob/a2bb34060102d049e07766436359e9526e3d8aab/lnbits/extensions/lnurlpos/lnurl.py#L37

Bleskomat uses practically the same method, but for LNURL-withdraws and their offline ATM.

If we made encrypting a confirmation pin and passing through LNURL, then sending back decrypted pin in the receipt, part of the LNURL protocol, then a service like OpenNode could support it directly and LNURLPoS, LNURLVend, Bleskomat, etc would be compatible native with their platform.

Telegram group

I tried to join your Telegram group on Android. I copied the ln invoice into Breez wallet and Breez showed a toast saying that I am sending 1 sat. After that 1 sat was not subtracted from my balance and I was banned from the group for a day. It's been 31 hours now and I am still banned.

Support of tags in LUD-16 static identifiers

The idea here is that, additionally to the <username>@<domainname> format of LUD-16 static internet identifiers, a SERVICE can offer multiple addresses resolving to the same user by using the format <username>+<tag>@<domainname>, e.g. [email protected] (see Plus signs ("+") in email addresses). The normal flow does not change: Upon seeing such an address, WALLET makes a GET request to https://<domain>/.well-known/lnurlp/<username>+<tag> endpoint.

It is upon the SERVICE to decide what to do. If it supports tags, it SHOULD strip the +<tag> part and continue as normal.
A SERVICE MAY subsequently include the tag in the metadata property of the response:

[
        "text/tag", // optional
        string // the tag that has been passed in `<username>+<tag>`
],

Currently, the <username> character set is limited to a-z0-9-_. which means the + sign has not been allowed yet and wallets that are not aware of it will either just deny it, or support this change and immediately use <username>+<tag> as <username>. I suppose that most wallets do not validate for a-z0-9-_. and will happily use everything up to @ as username. The only tested wallet is Zeus, which supports sending usernames with +.

Example of a service that already accept +tag: https://ln.tips/.well-known/lnurlp/fiatjaf+test (albeit without resolving to "fiatjaf" and a dedicated entry in metadata)
Example of a service that does not support +tag: https://stacker.news/.well-known/lnurlp/fiatjaf+test

With all that said, I propose adding +<tag> as an OPTIONAL feature with a suggestion for SERVICEs to handle them accordingly. No already existing SERVICE is forced to update and can continue to work as is.

Benefits

With this suggestion, a SERVICE can offers users a "standardized" way to use multiple identifiers. e.g. a user can include [email protected] in the description of the first episode of a podcast, [email protected] for the second and so on and so forth. For written text it might be [email protected], for code repositories it might be [email protected] or [email protected], etc.

Drawbacks

Since a user knows whether a SERVICE supports this scheme, an identifier with +<tag> is used only when this is the case - so there is no disadvantage on the SERVICE side. On the WALLET side, it might be that the GET request will not be performed if the wallet follows the current validation rules. In this case, a user SHOULD strip the tag manually - which is arguably not desirable.


Should this be an addition to LUD-16 or would you rather suggest this being a distinct LUD? Imho, an own LUD seemed overkill as the changes would be minimal and optional. What do you think?
Any and all suggestions are highly appreciated 🙏

LNURL-verify

LUD-[TBD]: verify base spec.

author: [TBD] discussion: [TBD]


The idea here is that a SERVICE can verify an invoice has been paid by contacting the LN SERVICE.

A SERVICE can verify a payment was made without access to the user's node. Users can give their LNURL or Lightning Address to a SERVICE and allow the SERVICE to create and verify invoices on their behalf.

This allows users to re-use existing wallets and SERVICEs to facilitate P2P payments without being an intermediary.

LNURL-verify

An optional field verify is added to the callback response:

{
  "status": "OK",
  "routes": [],
  "pr":     "lnbc10...",
+ "verify": "https://example.com/verify/894e7f7e...",
}

The field verify provides an URL to a SERVICE to check if the invoice has been settled:

https://example.com/verify/894e7f7e...

Response

{
  "status": "OK",
  "settled": true,
  "preimage": "123456...",
  "pr": "lnbc10..."
}
{
  "status": "OK",
  "settled": false,
  "preimage": null,
  "pr": "lnbc10..."
}

or

{
  "status": "ERROR",
  "reason": "Not found"
}

Looking forward to hear your feedback!

Proposal for LUD-03 spec addition: wallet must nod send an invoice with tag `h` in callback

  • In LUD-03 in the callback the LN WALLET send a Bolt11 Lightning payment request (invoice).

  • Bolt11 allows that a payment request might contain only a hash of the description (tag h)

  • Bolt11 specifies that if the tag h is present in a payment request a lightning node:

    - MUST check that the SHA2 256-bit hash in the `h` field exactly matches the hashed description.
    
  • To be able to do so, a lightning node must learn the preimage together with the bolt11 payment request (containing a hashed description) before it can initiate a payment.

Consequence:

  • The (receiving side) LN Wallet must also provide the pre-image of the hashed description used in the Bolt11 payment request (aka LN invoice).
  • Thus LUD-03 would need to be extended, so that if a LN WALLET uses tag h in the generated Bolt11 payment request, it also MUST return the preimage of tag h in its callback.
  • LUD-03 should make this mandatory and introduce an additional GET parameter for the callback (in addition to already existing k1 and pr).

"Smart custodial account" extension

I was thinking that it'd be useful to extend this specification for cases when the customer has a business relationship with other party and the other party might owe him some satoshis. This is different from the mere withdraw case, when it's only possible to withdraw over LN and actively scanning the QR code - in this case opening a (turbo) channel should be possible too. Further, I'd like to see a way to enable the users to withdraw without scanning anything.

Cases when this might be useful:

  • Exchange executed a buy order and the customer should be able to withdraw regardless if he has a channel already or not
  • An employer tops up the balance of employee and doesn't bother him with asking for invoice. The employee withdraws whenever it's comfortable or the wallet could withdraw automatically.
  • An ATM needs to know that customers wallet is compatible before accepting bills (because it can't spit them out)
  • A waiter is earning tips within POS in order to simplify the flow for the customers and tips are credited to his account automatically. His wallet could withdraw them without scanning anything.

Rough idea of extension:

A new fields "accountBalance" and "accountCapabilities" are added to login response object. Here's an example:

{
    #...
    # msat
    "accountBalance": 1000000000,
    "accountCapabilities": {
        # whether the service can open a channel in case of routing failure
        # MANDATORY (the field must be present even if false)
        "openChannel": true,
        # msat, not present if openChannel is false
        "openChannelFee": 1000000,
        # sat, the minimum amount for opening the channel
        "minChannelAmount": 100000
        # Indicates whether the opened channel supports spending zeroconf push - AKA "Turbo channels"
        "spendUnconfirmeddPush": true,
        # The wallet can GET this URL to retrieve current balance, MANDATORY
        "pollURL": "https://example.com/acount/poll",
        # Minimum delay between polls in seconds to prevent overloading
        "minPollPeriod": 30,
        # The wallet can use this URL for withdraws, MANDATORY
        "withdrawURL": "https://example.com/account/withdraw"
        # OPTIONAL, the wallet can use websocket to wait for balance changes
        "websocketURL": "https://example.com/account/listen"
        # OPTIONAL, the wallet can provide a callback that will be triggered whenever the balance changes
        "subscribeURL": "https://example.com/account/subscribe"
    }
    #...
}

Websocket sends same messages as poll response: JSON object with MANDATORY "accountBalance" field and OPTIONAL "accountCapabilities", which is same as above. If it's missing, the wallet assumes it didn't change since the last poll.

This is just the protocol, the wallet is responsible for all automation (if any). In the future, it should be extended with splicing in, if there's an open channel between the parties. The provider MAY use trusted third-party service for opening the channels.

Additional ideas: on-chain withdraw for larger amounts, topup (off and on-chain)

What do you think?

LNURL tag query parameter

The Readme mentions:

Once LNURL is decoded:

  • If tag query parameter is present then this LNURL has a special meaning, further actions will be based on tag parameter value.
  • Otherwise a GET request should be executed which must return a JSON object containing a tag field, further actions will be based on tag field value.

Does the first point mean the original URL encoded in the QR code can contain tag=withdrawRequest and then the wallet can skip the first HTTP GET and get all the other parameters from the original URL?

In this case the URL in the QR code would also have callback, k1, defaultDescription, minWithdrawable, maxWithdrawable query parameters?

So the withdraw flow would be:

  1. User scans a LNURL QR code and LN WALLET decodes LNURL.

LN WALLET gets callback, k1, defaultDescription, minWithdrawable, maxWithdrawable from url query params

  1. LN WALLET Displays a withdraw dialog where user can specify an exact sum to be withdrawn which would be bounded by:

[...]

This is not mentioned on the LNURL-withdraw page or the other pages. It would save one round trip of HTTP but is it actually supported by wallets?

LAPPURL - Communication between apps via 'lightning:' URL Scheme

LAPPURL

The LNURL flow describes that after the LNURL is decoded, a request is made to the LN SERVICE to attain the full transaction data in JSON format. The reason for this step is encoding transaction JSON into the LNURL directly would make it too large and impractical for QR codes.

However, when two apps communicate via the lightning: URL Scheme, size limitations are not relevant. For App to App communication, we could encode the transaction JSON in a LAPPURL, meaning the GET request to the service is no longer required.

This optimisation is specifically for the use case of app to app communications, intended to be hidden from the user. This change would have the following advantages to developers of Lapps who plan to use the lightning: URL Scheme only in their product;

  1. Less burden on the developer to maintain 'state' of their LNURLs in their LN SERVICE.
  2. Less customer support requests - if the LN SERVICE fails to deliver the transaction JSON for whatever reason, this is handled differently by different wallets.
  3. Faster transactions - If the wallet opens a LAPPURL they can immediately show the transaction interface instead of waiting for a response from an LN_SERVICE
  4. For wallet developers, there are less steps which require error handling

Here is an example of how a LAPPURL could be used for withdrawals

Withdrawing funds from a Lapp

Lapp to Wallet service interaction flow:

  1. User taps a withdrawal button in LN APP, which creates a LAPPURL - a bech32 encoded json:

    {
    	callback: String, // the URL which LN APP has defined as it's LN SERVICE, would accept a withdrawal Lightning invoice as query parameter
    	k1: String, // random or non-random string to identify the user's LN WALLET when using the callback URL
    	maxWithdrawable: MilliSatoshi, // max withdrawable amount for a given user on LN SERVICE
    	defaultDescription: String, // A default withdrawal invoice description
    	minWithdrawable: MilliSatoshi // An optional field, defaults to 1 MilliSatoshi if not present, can not be less than 1 or more than `maxWithdrawable`
    	tag: "withdrawRequest" // type of LAPPURL
    }
    
  2. LN APP opens LN WALLET with lightning:LAPPURL.. and LN WALLET decodes LAPPURL to retrieve the JSON.

  3. LN WALLET Displays a withdraw dialog where user can specify an exact sum to be withdrawn which would be bounded by:

    max can receive = min(maxWithdrawable, local estimation of how much can be routed into wallet)
    min can receive = max(minWithdrawable, local minimal value allowed by wallet)
    
  4. Once accepted by the user, LN WALLET sends an HTTPS GET to LN SERVICE in the form of

    <callback>?k1=<k1>&pr=<lightning invoice, ...>
    
  5. LN SERVICE sends a {"status":"OK"} or {"status":"ERROR", "reason":"error details..."} JSON response and then attempts to pay the invoices asynchronously.

  6. LN WALLET awaits for incoming payment if response was successful.

Implementing Lightning Address for lnsms.world

I've been implementing Lightning Address for lnsms.world the last few days and wanted to share my
experience and thoughts.

The idea was to allow users to simply specify [email protected] as a destination to be able to easily send a text message to the phone number NUMBER. On the surface it seemed like a perfect fit.

One major issue I have though is that due to the complexities of how SMS messages are encoded, it's impossible for me to know how many bytes a message will take up and consequently how much I need to charge for sending it without first seeing the complete message.

I could take a guess, but if i want to be completely safe the limit i would have to put on message size would be ridiculously restrictive in relation to the price.

Unfortunately, the way LA/LNURL currently works I need to give a price or a price range before I see the comment (which I my case will be the content of the message to send). So what I would like is a way of not having to give either a price or a price range (and ideally not a comment limit either), but just indicate that I would like the client software to give me a comment and in exchange I will give an invoice.

The second issue I had is that all information being exchanged is sent as request string parameters in a GET request. That means in a typical configuration it will be written to the webserver's access log, for example /var/log/nginx/access.log. So in my case both the recipient number and the full message contents ends up there, which I consider a big no-no. I'm very careful to not store that kind of information anywhere for obvious privacy reasons. Fortunately it was relatively straight-forward to use a custom log format + some regex matching to strip that out but I imagine this could be a problem for other services as well.

While working on this I got some ideas on how, in an ideal world, LA/LNURL would work to be 100% adapted to my use-case:

I imagine something like this:

There is only one endpoint. The client would repeatedly hit that endpoint until it gets an invoice. The first time, the client would not supply any data (same as now). If there is no data required, the server would simply respond with an invoice immediately. If any data is needed, the server would instead respond with a list of required fields. Those could include an exact amount (and in this case the server will provide an acceptable range) and it could also include a comment, with or without a max length. The client the asks the user for the required information and hits the endpoint again, this time with the data attached. (The client chooses wether to use a GET or POST for this and the server will respond to either.) The server once again either responds with an invoice, or again gives a list of additional data fields that are required. This goes on until the server is satisfied and responds with an invoice. When the client gets the invoice it asks the user for the final confirmation, using the amount in the invoice and then makes the payment.

In the vast majority of cases this will only involve one or two requests, but in some cases it could be three or even more. So there will basically be a kind simple dialogue between the server and the user. I think something like this would be flexible enough to cover most use-cases and at the same time save in one HTTP request in those cases where there is no need for the user to specify an amount.

I realize there are most likely reasons you have designed LA/LNURL they way you have and regardless it might be hard to change fundamental parts of it at this stage but I still wanted to share.

As it is now, using Lightning Address with lnsms is a terrible user experience.

Use lightning address to initiate a lnurl-auth login?

Feel free to close this if this has been discussed already.

I'm seeing 1 or more email sign up failures on SN per day from users attempting to use their lightning address as an email address.

It got me thinking it'd be nice if this initiated an lnurl-auth login without the QR crap. E.g. send the lnurl-auth challenge, callback, etc. to the domain of the lightning address, and have the service at domain go through the lnurl-auth flow from there.

This would be particularly nice for services that send tips to lightning addresses as the user could auth and specify their preferred receiving wallet simultaneously.


A few things occurred to me after posting this. lnurl-auth via lightning address will need prompting in the wallet. If we are okay with prompting via lightning address, perhaps we could also support lnurl-withdrawals via lightning address. In this way, you'd be able to provide most of a wallet's functionality through the lightning address alone.

Maybe this a dumb idea.

bech32-encoded QR codes are bigger than QR codes with normal URLs

Here's a QR code for https://charger.bigsun.xyz/lnurl-login?tag=login&k1=b58e7b599ac78aea4393a34f4250e3abbe31f9674ba28cf8db113de28de5efbe:
index

And now one for LNURL1DP68GURN8GHJ7CMGV9EXWETJ9E3XJEMNW4HZU7RE0GHKCMN4WFKZ6MR0VA5KU0M5V9NN6MR0VA5KUFNTXY7KYDFCV5MKYDFE89SKXDECV9JKZDPN8YEKZVE5VC6RYDFSV5EKZCNZV5ENZE3EXCMNGCNPXGUXXE3CV33RZVFNV3JNYWRYV56K2ENZV5ZUKEYM, the lnurl-bech32-encoded version of the above:
index

Apparently the uppercasing QR-reduction properties aren't so powerful as one would think initially.

Domain name used in LNURL-auth is not clear

According to the LNURL auth specs the key used by the wallet for signing the k1 secret should be specific to the service, using the service domain name. However the spec is not clear whether the key should be generated with the complete service domain name including subdomains, or the top domain name.

Wallet uses subdomains

The service may internally use a subdomain for everything LNURL related, like api.service.com. In that case the account will be forever coupled to whatever internal architecture the service is currently using. If the service architecture changes, the wallet will use a different signing key, effectively creating a new account and locking the user out of his previous one.

Wallet uses top domain only

If there are several services on the same top domain, then the signing key would be the same for all these services. Yet, regarding security, each service maintains its own k1 secrets and will reject any authentication attempts using k1 secrets it has not solicited. That is, if you have 2 services, one for testnet on api.testnet.service.com and one for mainnet on api.mainnet.service.com, one cannot sign-in to mainnet using a signature valid on testnet.

Regarding privacy, the account public key is the same for every services on a top domain, and someone operating 2 of those services would know that it's the same user. But that will happen anyway, even if we use subdomains, as soon as the user provide a LN invoice to the service (containing the node public key).

So, in any case I think the spec should be clear on this, and should recommend one option or the other. I think using top domain is the better option, with subdomains the risk of being locked out is too great.

What's the rationale for the 2-steps flow of LNURL-pay ?

Hello,

Commit d9f902c brought a significant change to the lnurl-pay flow: instead of having a single GET that would retrieve all the necessary data for the payment in one go, the client must now:

  1. GET payment metadata from the server
  2. Show meta to the user and wait for his input (spec mentions using a dialog)
  3. GET the actual BOLT11 invoice

I could only find the following rationale for this change, in issue #9 (comment):

1 is simpler and easier to implement as it involves less roundtrips but it doesn't allow for undefined-amount payments and it also leaks the customer privacy as he scans the QR code even if he didn't decide to pay.

Which does not make sense to me:

  • Server can provide an amount-less invoice even with a single GET flow.
  • The new flow still "leaks customer privacy" since the client WILL send a GET to some server as soon as the QR is scanned, even if that's only to retrieve some metadata.

Is there another rationale for this change? It seems to me that one of the key objective of LNURL-pay is to provide static invoices, that is, being able to generate a Lightning invoice from a fixed URI. Having a 2-steps flow breaks this, and makes the protocol harder to implement, so I may have missed something?

Sorry if this has already been discussed.

Lud-18 specification questions

In lud-18 there is no description at all how this should be handled on the wallet in regards to UX.
Is the wallet required to notify the user that it sends the pubkey as identity or does it do it without the users knowledge?
Does the user have to input email, identifier and a text, if SERVICE has all of these 3 identities as mandatory?
Does the wallet have to make sure valid data is inputted in email and identifier field?

Further more I have to admit that I don't really see a usecase for those loose identification methods.
Email, identifier, text and pubkey do not proof anything. The only method that proofs a identity is the "auth" method.
Do you have a specific example where the loose identification methods are needed or already used and why?

Implementing the UI for those loose methods in a wallet is quite a lot of work as it involves extra input fields

Why bech32? .well-known URLs and wallet-initiated interactions.

Why can't the lnurl have just query strings as normal URLs?

What about using /.well-known/whatever endpoints? Aside from handling the cases described in https://github.com/btcontract/lnurl-rfc/blob/61071a18453c3e8a99f65c1db94fdd1c2f2e1247/spec.md, LN services could have /.well-known/lnurl:withdraw URLs, for example, that would allow automatic withdrawing at the request of the wallet, without user interaction (so a wallet could programmatically withdraw funds from a custodial site every day or week, for example).

Other interesting cases are /.well-known/ln:deposit for depositing money on websites from the wallet itself, without the user even having to scan a QR code or deal with an invoice. This could also be used by individuals who want to be paid and have a webserver (or a variant, /.well-known/ln:pay).

All these cases are doable with the lnurl scheme described, I'm just suggesting .well-known because it is a (sort of) standard.

<domain> is very limited in LUD-16, add additional DNS record types to allow flexibility

In LUD-16, you have <domain>. It is my assumption (although it's not clearly defined) that this is referring to the DNS A record for the domain? This is very inflexible. It is every likely that one may not want to run a service on the host defined by the DNS A record to serve lightning invoices. It is very likely that their main website will be hosted there. E-mail has MX records for this very purpose. I propose that you create a new optional DNS record type that defines the host that should be contacted to request the invoice from. If that record is defined, then don't use the A record. If the record isn't defined, use the A record (just like e-mail).

Additionally, you may want to give the user the flexibility on what TCP port is used to connect to instead of port 80 or 443. You might want to also define a DNS SRV record that allows this to be changed. This can be very useful to people who have only one IP address but still want to run the invoice serving service on a different machine than their website.

Requests should be POST, not GET

In many places the spec says a GET request is sent with valuable information. GET requests are for "fetch" and "query" idempotent stuff, not for requests that trigger actions, in these cases the spec should say POST.

Main Readme.md 404 link

Hello, the following example link return 404, it should not be interpreted as URL with markdown because it can lead to confusion, thank you!

An example LNURL:

https://service.com/api?q=3fc3645b439ce8e7f2553a69e5267081d96dcd340693afabe04be7b0ccd178df

tlv/keysend lnurl-pay

I think having a standard for static tlv/keysend invoices could be cool.

Additionally to the standard lnurl-pay data the lnurl-pay-tlv data could contain:

  • destination pubkey

  • list of tlv payloads, such as fixed ones (userid) and maybe optional ones like custom donation messages

This would basically eliminate the 2 roundtrips of lnurl-pay as all of the above information is enough to have the same information

Unspecified response in case of invalid request

The specification doesn't describe what response should be at step 2 when there's an error - e.g. the secret is invalid. Should there be specific JSON body or just HTTP error? Which HTTP error?

LNURL for pull payments

I am looking for a way to implement the following flow with LNURL:

Suppose the merchant is a video streaming service that charges monthly. A user browses around on the merchant's website and decides to sign up.

  • Merchant displays a QR code to the user to sign up.
  • User scans this QR code and is prompted by their wallet to authorize the merchant to push invoices. User approves and sends a callback url to the merchant.
  • Each month, the merchant pushes an invoice to the user via that callback url.
  • The user's wallet will notify the user so that the user can confirm payment of the pushed invoice.

An extension to this is that the user can instruct their wallet to auto-pay invoices from that merchant up to a certain limit. The limit can be hinted in the initial merchant QR code too, so that approval of push invoices and approval of the (hinted) limit can be done in a single action.

The flow contains elements of LNURL-withdraw, but isn't quite the same. I don't think the initial merchant request to push invoices via a QR code is covered already.

Any thoughts on this?

Relative callback URL

The callback url in payRequest makes it impossible to create a static implementation of a payRequest server - the server must know its full URI to return in the callback parameter. It would be nice to be able to specify at least server-relative callback URLs so that a static implementation (run behind NGINX or some other TLS proxy) could be built that doesn't need additional LNURL-specific configuration

PIN support for withdrawRequest

LNURL-withdraw is increasingly used for convenient contactless payments via NFC devices that do not require a battery and do not have a user interface.

While these devices can produce unique one-time LNURLw-links with replay protection there is still the risk of losing the device or maliciously scanning the device without knowledge of the owner.

Security of tap & pay experiences could be improved by adding a second factor PIN to withdrawRequest callbacks.

I prepared a draft pull request for a new LUD: #200

lnurl-pay protocol

A protocol like this could be the solution for all services and websites that want to show a static QR code for payments (like a static site or a site not directly connected to an LN node), a QR code that could be printed on paper and so on -- while at the same time allowing for payment/user identification without loss of privacy (by the optional usage of per-service linkingKeys).

Example use cases:

  1. Donation webpages and other web-scenarios where one wants variable-amount payments;
  2. Restaurant menus;
  3. Simplification of setups where a webpage wants to accept payments (for simple, more "manual", things like selling a t-shirt) while the LN node responsible for that is running on a different computer;
  4. Pricing tags in market shelves (I'm just imagining a new self-checkout experience where the customer would pay at the time they would pick up the product from the shelf instead of paying everything at the end);
  5. Bike/scooter-sharing services and other fancy modern indie stuff;
  6. Other noveau use-cases like those powered by WeChat and Alipay stuff on China;

Spec suggestion

Two ideas of how this could be done come to my mind:

  1. _
    a. As the wallet scans a QR code it identifies the ?tag=pay&k1=<challenge> in the lnurl and immediately calls the URL with the signed challenge;
    b. Now the service knows who is willing to pay and returns pr (an invoice) along with metadata;
    c. The wallet displays a "Pay" screen to the user enhanced with the received metadata;
    d. The user decides to pay, then the service already knows who paid that and reacts accordingly.
  2. _
    a. As the wallet scans a QR code it first calls the URL;
    b. From the service response it gets tag: "pay" plus callback, k1, metadata and pricing information somehow (a fixed price or min/max prices?);
    c. Then the service displays the enhanced "Pay" screen with room for the user to decide the amount if that is not fixed;
    d. After the user clicking "confirm" the wallet sends the chosen amount to callback, plus the k1 signed with the user's linkingKey, then gets a pr (invoice) back;
    e. The wallet automatically pays the invoice if it matches the amount and metadata.

The spec 1 is simpler and easier to implement as it involves less roundtrips but it doesn't allow for undefined-amount payments and it also leaks the customer privacy as he scans the QR code even if he didn't decide to pay.

On the metadata returned by the service

The metadata field could be a string, a JSON object, raw HTML or who-knows-what, but the wallet will have to display it to the user somehow. Perhaps a good idea would be to do like emails do and return the metadata in all available mimetypes the service supports (a raw string should be mandatory) so the wallet can choose the one it wants and display.

The metadata could also be hashed into the invoice description (or in the descriptionHash field if that's still a living thing). This is useful for accountability between the parties.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.