{"id":"ed3a3554ce5c35035e4c07f951faba785205984a2012167f039faacf3fc8b018","pubkey":"d1678e7ef965374bbea308a1215609a78376dc158277a7d657680f9d5efd5c38","created_at":1782655276,"kind":30817,"tags":[["d","nut-14"],["title","NUT-14: Hashed Timelock Contracts (HTLCs)"],["summary","Ecash locked to the hash of a preimage and a deadline, which makes atomic swaps between users possible."],["s","optional"],["t","cashu"],["t","ecash"],["t","nut"],["alt","A specification: NUT-14: Hashed Timelock Contracts (HTLCs)"],["client","openspecs-import"],["published_at","1713949538"],["proxy","https://github.com/cashubtc/nuts/blob/a845dfc998abae501fc3419592d53dc995d34b12/14.md","web"],["x","b6be11a2c9ddab0b1dfa92ca1ee94148547f61d058a5c92c57b0a41644068637"]],"content":"# NUT-14: Hashed Timelock Contracts (HTLCs)\n\n`optional`\n\n`depends on: NUT-10, NUT-11`\n\n`extended by: NUT-28`\n\n---\n\nThis NUT describes the use of Hashed Timelock Contracts (HTLCs) which defines a spending condition based on [NUT-10][10]'s well-known `Secret` format. Using HTLCs, ecash proofs can be locked to the hash of a preimage and a timelock. This enables use cases such as atomic swaps of ecash between users, and atomic coupling of an ecash spending condition to a Lightning HTLC.\n\n`HTLC` spending conditions can be thought of as an extension of `P2PK` locks (see [NUT-11][11]) but with a hash lock in `Secret.data` and a new `Proof.witness.preimage` witness in the locked inputs to be spent. The `preimage` used to spend a locked Proof can be retrieved using [NUT-07][07].\n\nCaution: applications that rely on being able to retrieve the witness independently of the spender must check, via the mint’s [info][06] endpoint, that NUT-07 is supported.\n\nCaution: if the mint does not support this type of spending condition, proofs may be treated as regular anyone-can-spend proofs. Applications must ensure that the mint supports a specific kind of spending condition by checking the mint’s [info][06] endpoint.\n\n## HTLC Locked Proof\n\n[NUT-10][10] Secret `kind: HTLC`\n\nIf for a `Proof`, `Proof.secret` is a `Secret` of kind `HTLC`, the hash of the lock is in `Proof.secret.data`. The preimage for unlocking the HTLC is in the witness `Proof.witness.preimage`. All additional tags from P2PK locks can also be used here, allowing a locktime, signature flag, and multisig (see [NUT-11][11]).\n\nHere is a concrete example of a `Secret` of kind `HTLC`:\n\n```json\n[\n  \"HTLC\",\n  {\n    \"nonce\": \"da62796403af76c80cd6ce9153ed3746\",\n    \"data\": \"023192200a0cfd3867e48eb63b03ff599c7e46c8f4e41146b2d281173ca6c50c\",\n    \"tags\": [\n      [\n        \"pubkeys\",\n        \"02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904\"\n      ],\n      [\"locktime\", \"1689418329\"],\n      [\n        \"refund\",\n        \"033281c37677ea273eb7183b783067f5244933ef78d8c3f15b1a77cb246099c26e\"\n      ]\n    ]\n  }\n]\n```\n\nThe hash lock in `Secret.data` and the preimage in `Proof.witness.preimage` are treated as 32-byte data, encoded as 64-character hexadecimal strings.\n\nSee [NUT-11][11] for a description of the signature scheme, the additional use of signature flags, and how to require signatures from multiple public keys (Multisig).\n\n## Spending HTLC Proofs\n\nA `Proof` with a `Secret` of kind `HTLC` can be spent in two ways.\n\n### Receiver Pathway (hash lock)\n\nThe receiver(s) listed in the `pubkeys` tag can spend the proof by providing **BOTH** of the following:\n\n- The preimage to `Secret.data` in the `Proof.witness`\n- Signature(s) as per the [NUT-11][11] rules for **Locktime MultiSig**.\n\nThis pathway is **ALWAYS** available to the receivers, as possession of the preimage confirms performance of the Sender's wishes.\n\n**NOTE:** If the `pubkeys` tag is absent, the preimage alone spends the proof; no signature is required.\n\n### Sender Pathway (timelocked refund)\n\nThe sender(s) listed in the `refund` tag can spend the proof once the `locktime` lock has \"expired\" by providing signature(s) as per the [NUT-11][11] rules for **Refund MultiSig**.\n\n**NOTE:** As per the [NUT-11][11] rules, if the `refund` tag is not present, the HTLC proof would become \"anyone can spend\" after the `locktime` lock has \"expired\". Likewise, if the `locktime` is not present, or is not a valid unix timestamp, the HTLC proof will be permanently locked and can only be spent using the Receiver (hash lock) pathway.\n\n## Hash lock\n\nAligned with Bitcoin's HTLC construction, the hash lock in `Secret.data` represents the **SHA-256 hash** of a 32-byte preimage.\n\nWhen an HTLC-locked proof is created, the `Secret.data` field must contain:\n\n```\nhash_hex = bytes_to_hex(SHA256(preimage_bytes))\n```\n\nwhere:\n\n- `preimage_bytes` is exactly 32 bytes of arbitrary data, commonly random and uniformly distributed\n- `hash_hex` is the 32-byte SHA-256 digest of preimage_bytes, encoded as a 64-character lowercase hexadecimal string\n\nTo successfully spend a Proof via the **Receiver Pathway**, the spender must present the matching `preimage_bytes`, encoded as a 64-character lowercase hexadecimal string in the `Proof.witness.preimage`.\n\nMints and wallets **must verify** this equality before accepting the spend as valid:\n\n```\nSHA256(hex_to_bytes(Proof.witness.preimage)) == hex_to_bytes(Proof.secret.data)\n```\n\nHere is an example of a matching hash / preimage pair:\n\n```\nProof.secret.data = 'ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5'\nProof.witness.preimage = '0000000000000000000000000000000000000000000000000000000000000001'\n```\n\nThis hash-lock mechanism ensures that the Proof can only be spent once the secret preimage is revealed, allowing interoperability with external HTLC systems (such as Bitcoin or Lightning Network contracts).\n\n## Witness format\n\n`HTLCWitness` is a serialized JSON string of the form\n\n```json\n{\n  \"preimage\": <hex_str>,\n  \"signatures\": <Array[<hex_str>]>\n}\n```\n\nThe witness for a spent proof can be obtained with a `Proof` state check (see [NUT-07][07]).\n\n## Complex Example\n\nThis is an example `Secret` that locks a `Proof` with an HTLC condition that can be spent in either of the following ways:\n\n**Receiver Pathway** - 2-of-3 signatures from the public keys in the `pubkeys` tag **PLUS** the preimage in `Proof.witness.preimage` of the hash in `Secret.data`.\n\n**Sender Pathway** - One signature from the public keys in the `refund` tag, only available once the `locktime` has expired.\n\nThe signature flag `sigflag` indicates that signatures are necessary on the `inputs` and the `outputs` of the transaction this `Proof` is spent by.\n\n```json\n[\n  \"HTLC\",\n  {\n    \"nonce\": \"da62796403af76c80cd6ce9153ed3746\",\n    \"data\": \"023192200a0cfd3867e48eb63b03ff599c7e46c8f4e41146b2d281173ca6c50c\",\n    \"tags\": [\n      [\"sigflag\", \"SIG_ALL\"],\n      [\"n_sigs\", \"2\"],\n      [\"locktime\", \"1689418329\"],\n      [\n        \"refund\",\n        \"033281c37677ea273eb7183b783067f5244933ef78d8c3f15b1a77cb246099c26e\",\n        \"02e2aeb97f47690e3c418592a5bcda77282d1339a3017f5558928c2441b7731d50\"\n      ],\n      [\n        \"pubkeys\",\n        \"02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904\",\n        \"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\n        \"0249098aa8b9d2fbec49ff8598feb17b592b986e62319a4fa488a3dc36387157a7\"\n      ]\n    ]\n  }\n]\n```\n\n## Mint info setting\n\nThe [NUT-06][06] `MintMethodSetting` indicates support for this feature:\n\n```json\n{\n  \"14\": {\n    \"supported\": true\n  }\n}\n```\n\n[00]: nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595crqqpd6d9\n[01]: nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595crznyve7g\n[02]: nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595cry0t0uzl\n[03]: nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595crxuwwl3j\n[04]: nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595crg74fknc\n[05]: nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595cr2dsg4q4\n[06]: nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595crv3ltsuz\n[07]: nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595crwz62n00\n[08]: nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595crs4q9zck\n[09]: nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595crjx9yptm\n[10]: nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595cnqx5tye7\n[11]: nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595cnz43282n\n[12]: nostr:naddr1qvzqqqrcvypzp5t83el0jefhfwl2xz9py9tqnfurwmwptqnh5lt9w6q0n4006hpcqqrxuat595cnyf7fzky\n","sig":"ed7d9e85b26cf188d12e6e17237d3a9a5a66fa596ef8c04d16a37db305af6848769132fe877d52e9f0570dba8f9b0176714be2ddbd551cae31193c55bdf48151"}