{"id":"54539b169094f5f9181c216cd40e9ab310e308813505efd28469abca571f4f19","pubkey":"d1678e7ef965374bbea308a1215609a78376dc158277a7d657680f9d5efd5c38","created_at":1738452837,"kind":30817,"tags":[["d","nut-19"],["title","NUT-19: Cached Responses"],["summary","Response caching on the critical endpoints, so a wallet can safely replay a request that a network error interrupted."],["s","optional"],["t","cashu"],["t","ecash"],["t","nut"],["alt","A specification: NUT-19: Cached Responses"],["client","openspecs-import"],["published_at","1733229862"],["proxy","https://github.com/cashubtc/nuts/blob/a845dfc998abae501fc3419592d53dc995d34b12/19.md","web"],["x","579a67c98addc3325267705eba9892cf9d67d96fbc9fc2c1b094912679e7de82"]],"content":"# NUT-19: Cached Responses\n\n`optional`\n\n---\n\nTo 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.\n\n## Requests & Responses\n\nAny 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.\n\n### Derive & Repeat\n\nUpon 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`.\n\nThe mint uses `k` to look up a `response = D[k]` and discriminates execution based on the following checks:\n\n- If no cached `response` is found: `request` has no matching `response`. The mint processes `request` as per usual.\n- If a cached `response` is found: `request` has a matching `response`. The mint returns the cached `response`.\n\n### Store\n\nFor each successful response on a cached endpoint (`status_code == 200`), the mint stores the response in `D` under key `k` (`D[k] = response`).\n\n### Expiry\n\nThe mint decides the `ttl` (Time To Live) of cached response, after which it can evict the entry from `D`.\n\n## Settings\n\nSupport for NUT-19 is announced as an extension to the `nuts` field of the `GetInfoResponse` described in [NUT-06][06].\n\nThe entry is structured as follows:\n\n```json\n\"nuts\": {\n    ...,\n    \"19\": {\n        \"ttl\": <int|null>,\n        \"cached_endpoints\": [\n            {\n                \"method\": \"POST\",\n                \"path\": \"/v1/mint/bolt11\",\n            },\n            {\n                \"method\": \"POST\",\n                \"path\": \"/v1/swap\",\n            },\n            ...\n        ]\n    }\n}\n```\n\nWhere:\n\n- `ttl` is the number of seconds the responses are cached for\n- `cached_endpoints` is a list of the methods and paths for which caching is enabled.\n- `path` and `method` describe the cached route and its method respectively.\n\nIf `ttl` is `null`, the responses are expected to be cached _indefinitely_.\n\n[06]: nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595crv3ltsuz\n","sig":"dfc55bffcbf687371ea895d1b5445a65f02a5b15a2a4fa0a596f263d45c33858e79147685dd6017c230d5b8898511a88521c7b9aabcf5a769fab1f5d13f85506"}