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

Mint token

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

Create a BOLT11 quote, use the test mint auto-fill, then mint and store real test proofs.

Ready. Run this to create a real quote, preview the blinded outputs, then mint proofs from the test mint.

Code

cashu-ts code

mint-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 amount = 21
const unit = "sat"

const wallet = new Wallet(mintUrl, { unit })
await wallet.loadMint()

const mintQuote = await wallet.createMintQuoteBolt11(amount)
console.log('BOLT11 invoice:', mintQuote.request)

const checkedQuote = await wallet.checkMintQuoteBolt11(mintQuote.quote)
if (checkedQuote.state !== 'PAID') {
  throw new Error('Invoice is not paid yet')
}

const preview = await wallet.prepareMint('bolt11', amount, checkedQuote)
console.log('Mint request payload:', preview.payload)

const proofs = await wallet.completeMint(preview)
await saveProofs(proofs) // your app persistence function

Workings

Request / response timeline

4 steps

Step 1

Create mint quote

EXAMPLE

POST /v1/mint/quote/bolt11

The wallet asks the mint for a BOLT11 invoice.

Request

{
  "amount": 21,
  "unit": "sat"
}

Response

{
  "quote": "quote_demo_21",
  "request": "lnbc210n1demo...",
  "state": "UNPAID"
}

Step 2

Check auto-filled quote

EXAMPLE

GET /v1/mint/quote/bolt11/{quote}

The test mint auto-fills its own BOLT11 invoice, so the quote becomes PAID without a separate Lightning payment step.

Request

{
  "quote": "quote_demo_21"
}

Response

{
  "quote": "quote_demo_21",
  "state": "PAID"
}

Step 3

Prepare blinded outputs

EXAMPLE

LOCAL wallet.prepareMint('bolt11', amount, paidQuote)

This is not a mint HTTP request. cashu-ts uses the paid quote and amount to create the blinded outputs that step 4 sends to the mint.

cashu-ts call arguments

{
  "method": "bolt11",
  "amount": 21,
  "paidQuote": {
    "quote": "quote_demo_21",
    "state": "PAID",
    "unit": "sat"
  }
}

Prepared mint payload

{
  "quote": "quote_demo_21",
  "outputs": [
    {
      "amount": 16,
      "id": "00b4cd27d8861a44",
      "B_": "02demo_blinded_output_1"
    },
    {
      "amount": 4,
      "id": "00b4cd27d8861a44",
      "B_": "02demo_blinded_output_2"
    },
    {
      "amount": 1,
      "id": "00b4cd27d8861a44",
      "B_": "02demo_blinded_output_3"
    }
  ]
}

Step 4

Mint proofs

EXAMPLE

POST /v1/mint/bolt11

After the quote is PAID, the wallet asks the mint for signed proofs and stores them.

POST /v1/mint/bolt11 body

{
  "quote": "quote_demo_21",
  "outputs": [
    {
      "amount": 16,
      "id": "00b4cd27d8861a44",
      "B_": "02demo_blinded_output_1"
    },
    {
      "amount": 4,
      "id": "00b4cd27d8861a44",
      "B_": "02demo_blinded_output_2"
    },
    {
      "amount": 1,
      "id": "00b4cd27d8861a44",
      "B_": "02demo_blinded_output_3"
    }
  ]
}

Response

{
  "proofs": [
    {
      "amount": 16
    },
    {
      "amount": 4
    },
    {
      "amount": 1
    }
  ]
}

State

Before / after

Wallet state

Before summary

{
  "balance": 0,
  "proofs": []
}

After summary

{
  "balance": 21,
  "proofs": [
    16,
    4,
    1
  ]
}