Skip to content

Commit

Permalink
Add UMAD-09 UMA Invoice
Browse files Browse the repository at this point in the history
  • Loading branch information
zhenlu committed Sep 5, 2024
1 parent aec9a4f commit 0180168
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This repo is organized as a set of individual documents describing a single mess
| [UMAD-06](/umad-06-payreq-response.md) | Payreq Response |
| [UMAD-07](/umad-07-post-tx-hooks.md) | Post Transaction Compliance Hooks |
| [UMAD-08](/umad-08-versioning.md) | Versioning |
| [UMAD-09](/umad-09-invoice.md) | Invoice |

## Additional Resources

Expand Down
135 changes: 135 additions & 0 deletions umad-09-invoice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# UMAD-09 Invoice

UMA invoice is a data structure that describes payments that can be coordinated using UMA and
provides a way for a payment sender to have proof of payment–without having to use the existing
LNURLPRequest/Response handshake flow.

## Invoice Format

The full structure of the invoice is:

```raw
{
ReceiverUma: string,
// Receiving UMA address
InvoiceUUID: string,
// Invoice UUID Served as both the identifier of the UMA invoice, and the validation of proof of payment.
Amount: number,
// The amount of invoice to be paid in the smalest unit of the ReceivingCurrency.
ReceivingCurrency: {
Code: string,
// Code is the ISO 4217 (if applicable) currency code (eg. "USD"). For cryptocurrencies,
// this will be a ticker symbol, such as BTC for Bitcoin.
Name: string,
// Name is the full display name of the currency (eg. US Dollars).
Symbol: string,
// Symbol is the symbol of the currency (eg. $ for USD).
Decimals: number,
// Decimals is the number of digits after the decimal point for display on the sender side
},
// The currency of the invoice
Expiration: number,
// The unix timestamp the UMA invoice expires
IsSubjectToTravelRule: boolean,
// Indicates whether the VASP is a financial institution that requires travel rule information.
RequiredPayerData: {
"identifier": { "mandatory": true },
"name": { "mandatory": boolean },
"email": { "mandatory": boolean },
// Indicates we want TR data and/or utxos. This is UMA-specific and not in LUD-18.
"compliance": { "mandatory": boolean },
}
// Required data about the payer. See LUD-18 for details.
UmaVersion: string,
// The versions of the UMA protocol supported by the VASP. It should include the highest minor
// version for all major versions supported by the VASP, separated by commas.
CommentCharsAllowed: number,
// Optional field. CommentCharsAllowed is the number of characters that the sender can include
// in the comment field of the pay request.
SenderUma: string,
// Optional field. The sender's UMA address. If this field presents, the UMA invoice should
// directly go to the sending VASP instead of showing in other formats.
InvoiceLimit: number,
// Optional field. The maximum number of the invoice can be paid. If this field doesn't present,
// there's no limit for the invoice.
KycStatus: KycStatus,
// Optional field. [enum] KYC state indicating whether the receiver is a KYC'd customer of VASP2.
Callback: string
// The callback url that the sender should send the PayRequest to.
Signature: bytes
// The signature of the UMA invoice
}
```

## Proof of Payment

When creating the lightning invoice from the UMA invoice, the invoice UUID should be included in the
metadata field. It should be one extra item for the metadata field. See the LUD-18 for details.

```

Check failure on line 86 in umad-09-invoice.md

View workflow job for this annotation

GitHub Actions / markdown-lint

Fenced code blocks should have a language specified

umad-09-invoice.md:86 MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md040.md
["text/plain", invoiceUUID]
```

Once this is included in the metadata field for the lightning invoice, the UMA invoice can be tied

Check failure on line 90 in umad-09-invoice.md

View workflow job for this annotation

GitHub Actions / markdown-lint

Trailing spaces

umad-09-invoice.md:90:99 MD009/no-trailing-spaces Trailing spaces [Expected: 0 or 2; Actual: 1] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md009.md
to the lightning invoice. Then the proof of payment for the lightning invoice can be used as the

Check failure on line 91 in umad-09-invoice.md

View workflow job for this annotation

GitHub Actions / markdown-lint

Trailing spaces

umad-09-invoice.md:91:97 MD009/no-trailing-spaces Trailing spaces [Expected: 0 or 2; Actual: 1] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md009.md
proof of payment for the UMA invoice.

## Encoding

Bech32 encoding is used for the invoice without the 90 character limit.

### Human Readable Part

The human-readable part of the Bech32 encoding is `uma`.

### Data Part

The data part of the Bech32 encoding is the invoice encoded in TLV format. The TLV format is as

Check failure on line 104 in umad-09-invoice.md

View workflow job for this annotation

GitHub Actions / markdown-lint

Trailing spaces

umad-09-invoice.md:104:96 MD009/no-trailing-spaces Trailing spaces [Expected: 0 or 2; Actual: 1] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md009.md
follows:

```raw
1 byte: Type + 1 byte: Length + Length bytes: Value
```

TLV fields are encoded in the following order:
- 0: ReceiverUma

Check failure on line 112 in umad-09-invoice.md

View workflow job for this annotation

GitHub Actions / markdown-lint

Lists should be surrounded by blank lines

umad-09-invoice.md:112 MD032/blanks-around-lists Lists should be surrounded by blank lines [Context: "- 0: ReceiverUma"] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md032.md
- 1: InvoiceUUID
- 2: Amount
- 3: ReceivingCurrency, the receiving currency itself is encoded in TLV format
- 4: Expiration
- 5: IsSubjectToTravelRule
- 6: RequiredPayerData, the required payer data itself is encoded to field:boolean pairs separated

Check failure on line 118 in umad-09-invoice.md

View workflow job for this annotation

GitHub Actions / markdown-lint

Trailing spaces

umad-09-invoice.md:118:99 MD009/no-trailing-spaces Trailing spaces [Expected: 0 or 2; Actual: 1] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md009.md
by a comma
- 7: UmaVersion
- 8: CommentCharsAllowed
- 9: SenderUma
- 10: InvoiceLimit
- 11: KycStatus
- 12: Callback
- 100: Signature

### Signature Calculation

Check failure on line 128 in umad-09-invoice.md

View workflow job for this annotation

GitHub Actions / markdown-lint

Headings should be surrounded by blank lines

umad-09-invoice.md:128 MD022/blanks-around-headings/blanks-around-headers Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "### Signature Calculation"] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md022.md
The message for creating the signature is SHA256 of the TLV values without the signature field. Then
the signature is appended to the TLV encoded invoice.

## Reader requirements

Check failure on line 132 in umad-09-invoice.md

View workflow job for this annotation

GitHub Actions / markdown-lint

Headings should be surrounded by blank lines

umad-09-invoice.md:132 MD022/blanks-around-headings/blanks-around-headers Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "## Reader requirements"] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md022.md
- The invoice reader must validate that all non-optional fields are present.

Check failure on line 133 in umad-09-invoice.md

View workflow job for this annotation

GitHub Actions / markdown-lint

Lists should be surrounded by blank lines

umad-09-invoice.md:133 MD032/blanks-around-lists Lists should be surrounded by blank lines [Context: "- The invoice reader must vali..."] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md032.md
- The invoice reader must validate that the invoice has not expired.
- The invoice reader must validate that the signature is valid using the receiver's public key.

0 comments on commit 0180168

Please sign in to comment.