Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions 24.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
LUD-24: `currencies` base spec.
=======================================

`author: ethanrose` `author: lsunsi` `author: lorenzolfm` `author: jklein24`

---

## Support for LNURL-pay currencies

This document describes an extension to the [payRequest](https://github.com/lnurl/luds/blob/luds/06.md) base specification that allows the `WALLET` to send money to a `SERVICE` while denominating the amount in a different currency. The features proposed enable many use cases including:

- Bitcoin-settled cash remittances

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What do you understand by "remittances"?

From what I understood from the spec, this doesn't enable a remittance UX like Wise, for instance. This would required the convertible info

- Merchant bitcoin acceptance
- Lightning address aliases for bank & mobile money accounts
- Cross-border payroll


The main features provided by this extension are:
- `SERVICE` **MAY** provide `WALLET` with a list of supported currencies.
- `WALLET` **MAY** allow user to request an invoice for an amount denominated in a supported currency in place of millisats.


### 1. `currencies` array in payRequest details

`SERVICE` must alter its JSON response to the first request to include a `currencies` field, as follows:

```diff
{
"tag": "payRequest",
"callback": string,
"maxSendable": number,
"minSendable": number,
"metadata": string,
+ "currencies": [
+ {
+ "code": "PHP",
+ "name": "Philippine Pesos",
+ "symbol": "₱",
+ "decimals": 2,
+ "minSendable": 1,
+ "maxSendable": 50000,
Comment on lines +40 to +41

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Given that multiplier is not optional (see here), wouldn't minSendable and maxSendable be a derivation of multiplier and top level minSendable and maxSendable.

Since this LUD is just about denomitation there is no further limitation imposed by different currencies not already represented in the minSendable and maxSendable on top level

+ "multiplier": 64501 // (optional)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why do think this should be optional?

The service already knows the multiplier because its needed in order to fulfill the denomination request. So why not share it with the wallet.

+ }
+ ]
}
```

- The inclusion of the `currencies` field indicates the support of this extension
- The `multiplier` may be included for informational purposes, not a guaranteed rate

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This is the reason that the multiplier in the payreq response is critical IMO. The way this is interpreted in UMA is that the first response includes an estimate for while the sender is typing an amount, then the second response actually locks a quote including rate and fees.

- The `code` of a `currency` must be unique
- The order of the `currencies` may be interpreted by the `WALLET` as the receiving user preference for a currency


### 2. Wallet interface

If there is a `currency` record, `WALLET` should display a modified interface:
- Display currency symbol and code
- If there are multiple currency options, allow user to select/change currencies
- Validate "decimals" count for user amount input


### 3. Including `currency` in callback parameters

```diff
- <callback><?|&>amount=<number>
+ <callback><?|&>currency=PHP&amount=<numberInSmallestUnit>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This is missing critical functionality of the original LUD which allows the sender to lock either the sending or receiving amount. If I'm sending from USD to MXN, I need to be able to say either "I'm sending $100 USD" or "I need the receiver to receive $100 MXN". Both are quite important for different use cases. UMA doesn't use the full subset of flexibility for the convert stuff, but it definitely needs this point to still exist.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why did you go with currency outside instead of inside the amount, like here

Is not that we don't like this option, but we chose the other one because without it was less umbiguous in case wallet misuses the API. A service not supporting the LUD wouldn't even be able to understand the request

```

- Amount must be in SMALLEST UNIT INTEGER (wallet should use `decimals` value to modify amount)
- If `currency` param is omitted, the `amount` will be interpreted as millisatoshis (base spec)


### 4. Service processing

`SERVICE` response is unchanged.

`SERVICE` may optionally lock-in a rate and auto-convert to the specified currency, but that is a `SERVICE` / recipient decision, not relevant to the `WALLET` / sender.

### 5. User interface for reviewing & confirming the exchange rate

`WALLET` must display a confirmation screen so that the user can review and confirm the invoice amount.