Skip to content

NUT-03: Swap tokens

mandatory


The 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).

The 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.

Swap to send

To make this more clear, we present an example of a typical case of sending tokens from Alice to Carol.

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.

Note: 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.

Swap to receive

Another 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.

Example

Request of Alice:

POST https://mint.host:3338/v1/swap

With the data being of the form PostSwapRequest:

{
  "inputs": <Array[Proof]>,
  "outputs": <Array[BlindedMessage]>,
}

With curl:

curl -X POST https://mint.host:3338/v1/swap -d \
{
  "inputs":
    [
      {
        "amount": 2,
        "id": "009a1f293253e41e",
        "secret": "407915bc212be61a77e3e6d2aeb4c727980bda51cd06a6afc29e2861768a7837",
        "C": "02bc9097997d81afb2cc7346b5e4345a9346bd2a506eb7958598a72f0cf85163ea"
      },
      {
      ...
      }
    ],
  "outputs":
    [
      {
        "amount": 2,
        "id": "009a1f293253e41e",
        "B_": "02634a2c2b34bec9e8a4aba4361f6bf202d7fa2365379b0840afe249a7a9d71239"
      },
      {
      ...
      }
    ],
}

If successful, Bob will respond with a PostSwapResponse

{
  "signatures": <Array[BlindSignature]>
}