Skip to content

Commit 839f9ad

Browse files
authored
update documentation
1 parent 034d2c0 commit 839f9ad

File tree

1 file changed

+178
-0
lines changed

1 file changed

+178
-0
lines changed

docs/lit/accounts.md

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# Custodial accounts
2+
3+
This document describes how the "accounts" feature of LiT can be used to create
4+
custodial user accounts with their own balances on an existing `lnd` node.
5+
6+
## What is an account?
7+
8+
An account in the LiT context is a virtual construct that provides restricted
9+
access to an existing `lnd`/LiT node. An account has a virtual (off-chain only)
10+
balance in satoshis and an optional expiration. That allows a node operator to
11+
give someone else (or some client application, see [Use cases](#use-cases))
12+
restricted access to their node with the ability to only spend up to a certain
13+
amount of the node's channel balance.
14+
15+
NOTE: An account's balance is purely virtual. If an account is created with an
16+
initial balance higher than the node's actual overall channel balance, that is
17+
equivalent to fractional reserve banking. Therefore, the user accepting an
18+
account restricted access enters a trust relationship with the node operator
19+
that the promised balance of the account is actually spendable.
20+
21+
## How do accounts work?
22+
23+
The accounts systems is made possible thanks to the power of
24+
[macaroons](https://github.com/lightningnetwork/lnd/blob/master/docs/macaroons.md)
25+
and the [RPC middleware
26+
interceptor](https://github.com/lightningnetwork/lnd/blob/master/lnrpc/lightning.proto#L558)
27+
of `lnd`.
28+
29+
**What does that mean?**
30+
31+
It means a node operator can give another user or client application access to
32+
their node through the default gRPC interface of `lnd`, which makes this access
33+
mode fully compatible with any remote (or local) user interfaces or
34+
apps/browser plugins, as well as any [LNC (Lightning Node
35+
Connect)](https://github.com/lightninglabs/lightning-node-connect) connection.
36+
37+
What features and balance the restricted user has access to is **solely
38+
controlled by the macaroon that is given to the user**. So a user that wants to
39+
get restricted access to a node will receive a macaroon that is bound to an
40+
account that is defined in LiT. Because of the cryptographic setup of macaroons,
41+
that restriction cannot be removed from the macaroon by the user without
42+
invalidating the macaroon itself. Therefore, any user/application using such a
43+
restricted macaroon will trigger special rules in the RPC middleware interceptor
44+
mentioned above. See [the features](#features) section below to find out what
45+
those rules are.
46+
47+
## Features
48+
49+
When an account-restricted macaroon is used, the RPC middleware interceptor
50+
enforces the following rules on the RPC interface:
51+
52+
* Any payment made by a custodial/restricted user account is deducted from an
53+
account's virtual balance (the full amount, including off-chain routing fees).
54+
* If a payment (or the sum of multiple in-flight payments) exceeds the account's
55+
virtual balance, it is denied.
56+
* The on-chain balance of any RPC responses such as the `WalletBalance` RPC is
57+
always shown as `0`. A custodial/restricted user shouldn't be able to see what
58+
on-chain balance is available to the node operator as an account can only
59+
spend off-chain balances anyway.
60+
* The off-chain balance (e.g. the response returned by the `ChannelBalance` RPC)
61+
always reflects the account's virtual balance and not the node's overall
62+
channel balance (and any remote balances are always shown as `0`).
63+
* The list of active/pending/closed channels is always returned empty. The
64+
custodial/restricted user should not need to care (or even know) about
65+
channels and their internal workings.
66+
* The list of payments and invoices is filtered to only return payments/invoices
67+
created or paid by the account.
68+
* Invoices created by an account are mapped to that account. If/when such a
69+
mapped invoice is paid, the amount is credited to that account's virtual
70+
balance.
71+
72+
## Use cases
73+
74+
The following (definitely non-exhaustive) list of use cases is made possible by
75+
the accounts system:
76+
- The "Uncle Jim" model: The tech-savvy person of the family (e.g. "Uncle Jim")
77+
operates a Lightning node. He manages the liquidity of the node and provides
78+
the capital for the channels. He can onboard his family members by creating
79+
an account, locking a macaroon to that account and then scanning a QR code
80+
with an app like [Zeus](https://github.com/ZeusLN/zeus) on the family
81+
member's smartphone.
82+
- The "spend up to a certain amount automatically" model: A web user has a
83+
browser extension like [Alby](https://getalby.com/) installed and wants to
84+
allow that extension to pay invoices for paywalls automatically up to a
85+
certain amount per month. That amount could be enforced by the account so the
86+
browser extension doesn't have to keep track of its spending actions. And an
87+
account can be shared between extensions installed in different browsers.
88+
- The "allowance" model: A parent wants to give their child their allowance in
89+
Lightning satoshis. They create an account over the allowance amount and top
90+
up the account each week/month.
91+
92+
## HOWTO
93+
94+
This section describes how an account can be created and used.
95+
96+
### Create the account
97+
98+
The first thing that needs to be done is to create the account with its initial
99+
balance (and an optional expiry). This **needs to be done by the node
100+
operator**, meaning access to the `lit.macaroon` is required.
101+
102+
Example:
103+
```shell
104+
$ litcli accounts create 50000 --save_to /tmp/accounts.macaroon
105+
106+
{
107+
"account": {
108+
"id": "d64dbc31b28edf66",
109+
"initial_balance": "50000",
110+
"current_balance": "50000",
111+
"last_update": "1652353332",
112+
"expiration_date": "0"
113+
},
114+
"macaroon": "020103........."
115+
}
116+
Account macaroon saved to /tmp/accounts.macaroon
117+
```
118+
119+
This created a new account (ID `d64dbc31b28edf66`) with an initial balance of
120+
50k satoshis and no expiration. A new macaroon was baked that contains the
121+
correct permissions and is locked to that account. The macaroon file was stored
122+
under `/tmp/accounts.macaroon` in this example.
123+
124+
### Use the macaroon
125+
126+
This step is done by the user/app that should be given the restricted access. An
127+
example could be to create a QR code with a tool like
128+
[`lndconnect`](https://github.com/LN-Zap/lndconnect) that can be scanned by
129+
mobile apps to connect to the node. Or some browser extensions require the user
130+
to upload the macaroon to the browser.
131+
132+
**It's absolutely crucial to use the macaroon generated in the previous step
133+
here** to make sure the restrictions are applied.
134+
135+
The permissions and restrictions of a macaroon can always be inspected by:
136+
```shell
137+
$ lncli printmacaroon --macaroon_file /tmp/accounts.macaroon
138+
139+
{
140+
"version": 2,
141+
"location": "lnd",
142+
"root_key_id": "0",
143+
"permissions": [
144+
"info:read",
145+
"invoices:read",
146+
"invoices:write",
147+
"offchain:read",
148+
"offchain:write",
149+
"onchain:read"
150+
],
151+
"caveats": [
152+
"lnd-custom account d64dbc31b28edf66"
153+
]
154+
}
155+
```
156+
157+
The important part is the `lnd-custom account ...` part in the `caveats`
158+
section.
159+
160+
Example of using `lncli` to check the account balance (assuming integrated `lnd`
161+
mode, adjust RPC server/port and TLS cert for remote mode):
162+
```shell
163+
$ lncli --macaroonpath=/tmp/accounts.macaroon channelbalance
164+
165+
{
166+
"balance": "5000",
167+
"pending_open_balance": "0",
168+
"local_balance": {
169+
"sat": "5000",
170+
"msat": "5000000"
171+
},
172+
"remote_balance": {
173+
"sat": "0",
174+
"msat": "0"
175+
}
176+
...
177+
}
178+
```

0 commit comments

Comments
 (0)