{"id":"3bada20505c5a865002f93d54292d7ba29ec87702e13981322e239b5e9ba4771","pubkey":"d1678e7ef965374bbea308a1215609a78376dc158277a7d657680f9d5efd5c38","created_at":1725267910,"kind":30817,"tags":[["d","nut-03"],["title","NUT-03: Swap tokens"],["summary","The swap operation, where a wallet hands proofs to the mint and receives new blind signatures in return."],["s","mandatory"],["t","cashu"],["t","ecash"],["t","nut"],["alt","A specification: NUT-03: Swap tokens"],["client","openspecs-import"],["published_at","1674849737"],["proxy","https://github.com/cashubtc/nuts/blob/a845dfc998abae501fc3419592d53dc995d34b12/03.md","web"],["x","032a55a506c0da38436b660319b345d10ed4114c67fdc3a14653918995cc3fc2"]],"content":"# NUT-03: Swap tokens\n\n`mandatory`\n\n---\n\nThe swap operation is the most important component of the Cashu system. A swap operation consists of multiple inputs (`Proofs`) and outputs (`BlindedMessages`). Mints verify and invalidate the inputs and issue new promises (`BlindSignatures`). These are then used by the wallet to generate new `Proofs` (see [NUT-00][00]).\n\nThe swap operation can serve multiple use cases. The first use case is that `Alice` can use it to split her tokens to a target amount she needs to send to `Carol`, if she does not have the necessary amounts to compose the target amount in her wallet already. The second one is that `Carols`'s wallet can use it to receive tokens from `Alice` by sending them as inputs to the mint and receive new outputs in return.\n\n## Swap to send\n\nTo make this more clear, we present an example of a typical case of sending tokens from `Alice` to `Carol`.\n\n`Alice` has 64 sat in her wallet, composed of three `Proofs`, one worth 32 sat and another two worth 16 sat. She wants to send `Carol` 40 sat but does not have the necessary `Proofs` to compose the target amount of 40 sat. For that, `Alice` requests a swap from the mint and uses `Proofs` worth `[16, 16, 32]` as inputs and asks for new outputs worth `[8, 32, 8, 16]` totalling 64 sat. Notice that the first two tokens can now be combined to 40 sat. The `Proofs` that `Alice` sent `Bob` as inputs of the swap operation are now invalidated.\n\nNote: In order to preserve privacy around the amount that a client might want to send to another user and keep the rest as change, the client **SHOULD** ensure that the list requested outputs is ordered by amount in ascending order. As an example of what to avoid, a request for outputs expressed like so: `[16, 8, 2, 64, 8]` might imply the client is preparing a payment for 26 sat; the client should instead order the list like so: `[2, 8, 8, 16, 64]` to mitigate this privacy leak to the mint.\n\n## Swap to receive\n\nAnother useful case for the swap operation follows up the example above where `Alice` has swapped her `Proofs` ready to be sent to `Carol`. `Carol` can receive these `Proofs` using the same operation by using them as inputs to invalidate them and request new outputs from `Bob`. Only if `Carol` has redeemed new outputs, `Alice` can't double-spend the `Proofs` anymore and the transaction is settled. To continue our example, `Carol` requests a swap with input `Proofs` worth `[32, 8]` to receive new outputs (of an arbitrary distribution) with the same total amount.\n\n## Example\n\n**Request** of `Alice`:\n\n```http\nPOST https://mint.host:3338/v1/swap\n```\n\nWith the data being of the form `PostSwapRequest`:\n\n```json\n{\n  \"inputs\": <Array[Proof]>,\n  \"outputs\": <Array[BlindedMessage]>,\n}\n```\n\nWith curl:\n\n```bash\ncurl -X POST https://mint.host:3338/v1/swap -d \\\n{\n  \"inputs\":\n    [\n      {\n        \"amount\": 2,\n        \"id\": \"009a1f293253e41e\",\n        \"secret\": \"407915bc212be61a77e3e6d2aeb4c727980bda51cd06a6afc29e2861768a7837\",\n        \"C\": \"02bc9097997d81afb2cc7346b5e4345a9346bd2a506eb7958598a72f0cf85163ea\"\n      },\n      {\n      ...\n      }\n    ],\n  \"outputs\":\n    [\n      {\n        \"amount\": 2,\n        \"id\": \"009a1f293253e41e\",\n        \"B_\": \"02634a2c2b34bec9e8a4aba4361f6bf202d7fa2365379b0840afe249a7a9d71239\"\n      },\n      {\n      ...\n      }\n    ],\n}\n```\n\nIf successful, `Bob` will respond with a `PostSwapResponse`\n\n```json\n{\n  \"signatures\": <Array[BlindSignature]>\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":"221870384c31ed7192df9973695f99ae22ca32d5cfb2aad03a8f83369ad040e7dd298364c380f5fe5dd920d412a789b1f44c3497de62357fcf04ea84423490a8"}