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 3c181e2
Show file tree
Hide file tree
Showing 2 changed files with 134 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
133 changes: 133 additions & 0 deletions umad-09-invoice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# 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.

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

View workflow job for this annotation

GitHub Actions / markdown-lint

Hard tabs

umad-09-invoice.md:17:1 MD010/no-hard-tabs Hard tabs [Column: 1] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md010.md
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

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

View workflow job for this annotation

GitHub Actions / markdown-lint

Hard tabs

umad-09-invoice.md:34:5 MD010/no-hard-tabs Hard tabs [Column: 5] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md010.md
},
// The currency of the invoice

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

View workflow job for this annotation

GitHub Actions / markdown-lint

Hard tabs

umad-09-invoice.md:36:3 MD010/no-hard-tabs Hard tabs [Column: 3] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md010.md
Expiration: number,
// The unix timestamp the UMA invoice expires

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

View workflow job for this annotation

GitHub Actions / markdown-lint

Hard tabs

umad-09-invoice.md:39:4 MD010/no-hard-tabs Hard tabs [Column: 4] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md010.md
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

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

View workflow job for this annotation

GitHub Actions / markdown-lint

Hard tabs

umad-09-invoice.md:58:1 MD010/no-hard-tabs Hard tabs [Column: 1] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md010.md
// 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

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

View workflow job for this annotation

GitHub Actions / markdown-lint

Hard tabs

umad-09-invoice.md:72:1 MD010/no-hard-tabs Hard tabs [Column: 1] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md010.md
// The callback url that the sender should send the PayRequest to.

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

View workflow job for this annotation

GitHub Actions / markdown-lint

Hard tabs

umad-09-invoice.md:73:1 MD010/no-hard-tabs Hard tabs [Column: 1] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md010.md
Signature: bytes

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

View workflow job for this annotation

GitHub Actions / markdown-lint

Hard tabs

umad-09-invoice.md:75:1 MD010/no-hard-tabs Hard tabs [Column: 1] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md010.md
// The signature of the UMA invoice

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

View workflow job for this annotation

GitHub Actions / markdown-lint

Hard tabs

umad-09-invoice.md:76:1 MD010/no-hard-tabs Hard tabs [Column: 1] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md010.md
}
```

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

View workflow job for this annotation

GitHub Actions / markdown-lint

Fenced code blocks should be surrounded by blank lines

umad-09-invoice.md:78 MD031/blanks-around-fences Fenced code blocks should be surrounded by blank lines [Context: "```"] https://github.com/DavidAnson/markdownlint/blob/v0.31.1/doc/md031.md
## 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.

```
["text/plain", invoiceUUID]
```

Once this is included in the metadata field for the lightning invoice, the UMA invoice can be tied
to the lightning invoice. Then the proof of payment for the lightning invoice can be used as the
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
follows:

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

TLV fields are encoded in the following order:
- 0: ReceiverUma
- 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
by a comma
- 7: UmaVersion
- 8: CommentCharsAllowed
- 9: SenderUma
- 10: InvoiceLimit
- 11: KycStatus
- 12: Callback
- 100: Signature

### Signature Calculation
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
- The invoice reader must validate that all non-optional fields are present.
- 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 3c181e2

Please sign in to comment.