Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NUT-19: Cached Responses #195

Merged
merged 19 commits into from
Dec 3, 2024
67 changes: 67 additions & 0 deletions 19.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# NUT-19: Cached Responses

`optional`

---

To minimize the risk of loss of funds to due network errors during critical operations such as minting, swapping, and melting, we introduce a caching mechanism for successful responses. This allows wallet to replay requests on cached endpoints and allow it to recover the desired state after a network interruption.

## Requests & Responses

Any Mint implementation should elect a data structure `D` that maps request objects to their respective responses. `D` should be fit for fast insertion, look-up and deletion (eviction) operations. This could be an in-memory database or a dedicated caching service like Redis.

### Derive & Repeat

Upon receiving a `request` on a cached endpoint, the mint derives a unique key `k` for it which should depend on the method, path, and the payload of `request`.

The mint uses `k` to look up a `response = D[k]` and discriminates execution based on the following checks:

- If no cached `response` is found: `request` has no matching `response`. The mint processes `request` as per usual.
- If a cached `response` is found: `request` has a matching `response`. The mint returns the cached `response`.

### Store

For each successful response on a cached endpoint (`status_code == 200`), the mint stores the response in `D` under key `k` (`D[k] = response`).

### Expiry

The mint decides the `ttl` (Time To Live) of cached response, after which it can evict the entry from `D`.

## Settings

Support for NUT-19 is announced as an extension to the `nuts` field of the `GetInfoResponse` described in [NUT-6](06).

The entry is structured as follows:

```json
"nuts": {
...,
"19": {
"ttl": <int|null>,
"cached_endpoints": [
{
"method": "POST",
"path": "/v1/mint/bolt11",
},
{
"method": "POST",
"path": "/v1/swap",
},
...
]
}
}
```

Where:

- `ttl` is the number of seconds the responses are cached for
- `cached_endpoints` is a list of the methods and paths for which caching is enabled.
- `path` and `method` describe the cached route and its method respectively.

If `ttl` is `null`, the responses are expected to be cached _indefinitely_.

[03]: 03.md
[04]: 04.md
[05]: 05.md
[06]: 06.md
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Wallets and mints `MUST` implement all mandatory specs and `CAN` implement optio
| [16][16] | Animated QR codes | [Cashu.me][cashume] | - |
| [17][17] | WebSocket subscriptions | [Nutshell][py] | [Nutshell][py] |
| [18][18] | Payment requests | [Cashu.me][cashume], [Boardwalk][bwc], [cdk-cli] | - |
| [19][19] | Cached Responses | - | [Nutshell][py], [cdk-mintd] |

#### Wallets:

Expand Down Expand Up @@ -89,3 +90,4 @@ Wallets and mints `MUST` implement all mandatory specs and `CAN` implement optio
[16]: 16.md
[17]: 17.md
[18]: 18.md
[19]: 19.md
Loading