Cashu playground

Run cashu-ts flows and see what actually changes.

Choose a flow, run it against a test mint, and compare the request, response, wallet state, and cashu-ts code. Test shortcuts are labelled where they appear.

Primary mint: https://nofee.testnut.cashu.spaceFallback: https://testnut.cashu.spaceLive calls and test-only steps are labelled in the timeline.Open starter kit

How it works

Start here.

1. Choose a flowUse the recipe cards below. Create wallet is the clean first run.
2. Press runThe timeline shows each request and response.
3. Copy the codeThe code panel shows the cashu-ts calls and the state your app owns.

Choose a flow

These cards are clickable.

Inputs

Melt token / pay invoice

Mint: https://nofee.testnut.cashu.space

Mint wallet proofs, create a payable test invoice, melt live, and store returned change.

Ready. Run this to mint wallet proofs, create a payable invoice, melt live, and inspect change.

Code

cashu-ts code

melt-token.ts

Kept close to the cashu-ts docs. Add your own storage functions where shown.

import { Wallet } from '@cashu/cashu-ts'

const mintUrl = "https://nofee.testnut.cashu.space"
const invoice = "lnbc120n1pdemomeltinvoicepp5cashutoolsdemo"

const wallet = new Wallet(mintUrl)
await wallet.loadMint()

const proofs = await loadSpendableProofs()
const meltQuote = await wallet.createMeltQuoteBolt11(invoice)
const amountToSend = meltQuote.amount.add(meltQuote.fee_reserve)

const { keep: proofsToKeep, send: proofsToSend } = await wallet.send(amountToSend, proofs, {
  includeFees: true,
})

const meltResponse = await wallet.meltProofsBolt11(meltQuote, proofsToSend)
await replaceProofs({ remove: proofs, add: [...proofsToKeep, ...meltResponse.change] }) // your app persistence function

Workings

Request / response timeline

4 steps

Step 1

Create melt quote

EXAMPLE

POST /v1/melt/quote/bolt11

A melt starts by asking the mint for the invoice amount and fee reserve before spending proofs.

Request

{
  "request": "lnbc120n1pdemomeltinvoicepp5cashutoolsdemo",
  "unit": "sat"
}

Quote basics

{
  "quote": "melt_quote_demo_12",
  "amount": 12,
  "fee_reserve": 2,
  "state": "UNPAID"
}

Invoice carried through quote

{
  "request": "lnbc120n1pdemomeltinvoicepp5cashutoolsdemo"
}

Step 2

Select proofs to cover amount + reserve

EXAMPLE

LOCAL wallet.selectProofs()

Unlike a plain send, proof selection has to cover the invoice amount plus the mint fee reserve.

Invoice + reserve target

{
  "amount": 12,
  "feeReserve": 2,
  "target": 14
}

Available proofs in wallet

[
  {
    "amount": 8,
    "id": "009a1f293253e41e"
  },
  {
    "amount": 8,
    "id": "009a1f293253e41e"
  },
  {
    "amount": 4,
    "id": "009a1f293253e41e"
  },
  {
    "amount": 1,
    "id": "009a1f293253e41e"
  }
]

Selected proofs to melt

[
  {
    "amount": 8,
    "id": "009a1f293253e41e"
  },
  {
    "amount": 8,
    "id": "009a1f293253e41e"
  }
]

Untouched proofs that remain local

[
  {
    "amount": 4,
    "id": "009a1f293253e41e"
  },
  {
    "amount": 1,
    "id": "009a1f293253e41e"
  }
]

Step 3

Prepare change outputs

EXAMPLE

LOCAL wallet.prepareMeltChange()

If the fee reserve was too high, the unused sats come back as change proofs.

Request

{
  "selectedTotal": 16,
  "amount": 12,
  "feeReserve": 2,
  "actualFeePaid": 1
}

Reserved vs actual fee

{
  "feeReserve": 2,
  "actualFeePaid": 1,
  "unusedReserveReturned": 1
}

Change outputs returned to wallet

[
  2,
  1
]

Step 4

Complete melt and settle invoice

READY

POST /v1/melt/bolt11

When run with the default invoice, the API creates a payable test invoice and settles it live through the payer mint.

Inputs: proofs consumed for payment

[
  {
    "amount": 8,
    "id": "009a1f293253e41e"
  },
  {
    "amount": 8,
    "id": "009a1f293253e41e"
  }
]

Requested change outputs

[
  2,
  1
]

Paid quote result

{
  "paid": true,
  "payment_preimage": "demo-preimage-12",
  "invoice": "lnbc120n1pdemomeltinvoicepp5cashutoolsdemo",
  "amount": 12,
  "feeReserve": 2,
  "actualFeePaid": 1,
  "totalSpent": 13,
  "quote": "melt_quote_demo_12"
}

Change proofs returned

[
  {
    "amount": 2,
    "id": "009a1f293253e41e",
    "secret": "demo-melt-change-1",
    "C": "02meltchange1"
  },
  {
    "amount": 1,
    "id": "009a1f293253e41e",
    "secret": "demo-melt-change-2",
    "C": "02meltchange2"
  }
]

State

Before / after

Wallet state

Quote amount + reserve

12 sat + 2 satThe wallet budgets invoice amount plus fee reserve before melting.

Selected proofs

8 sat + 8 satThese proofs are consumed to fund the invoice payment path.

Returned change

2 sat + 1 sat3 sat comes back after fee reconciliation.

Payment result

Invoice paidSpent 13 sat total; fee used 1 sat.

Before summary

{
  "balance": 21,
  "amount": 12,
  "feeReserve": 2,
  "consumed": [
    8,
    8
  ],
  "preimagePresent": false
}

After summary

{
  "balance": 8,
  "amount": 12,
  "feeReserve": 2,
  "consumed": [
    8,
    8
  ],
  "returnedChange": [
    2,
    1
  ],
  "paid": true,
  "totalSpent": 13,
  "preimagePresent": true
}