A Buyer wants network access from a Seller.
The Buyer pays with Cashu ecash —
digital bearer tokens that work like electronic cash.
The Mint issues and verifies these tokens.
No accounts, no registration — the Buyer just sends tokens and gets access.
Buyer
Wants network access. Pays the Seller with Cashu ecash tokens minted from the Mint.
Seller
Sells bandwidth at 10 sat/second + 1 sat/byte. Verifies every token with the Mint before granting access.
Mint
Issues and verifies Cashu ecash. This test uses testnut.cashu.exchange (auto-paying fake wallet).
Protocol sequence — Bootstrap
Solid arrows (→) are requests ·
Dashed arrows (⇢) are responses ·
Numbers are auto-sequenced ·
Timing is relative to start
Setup
Payment
Metering
Teardown
sequenceDiagram
autonumber
participant Buyer
participant Mint
participant Seller
Note over Buyer,Buyer: NUT-04
rect rgb(230, 245, 255)
Note right of Buyer: Setup phase
Buyer->>Mint: MintQuote request 200 sat from testnut
Note right of Buyer: +0ms
Mint-->>Buyer: MintQuote 200 sat minted
Note right of Mint: +10092ms
Note over Buyer,Buyer: tollgate-protocol.md §3.1
Buyer->>Seller: Announce v=1, unit=bytes, caps=0x01
Note right of Buyer: +10092ms
Seller->>Buyer: Announce v=1, unit=bytes, caps=0x01
Note right of Seller: +10092ms
Note over Seller,Buyer: tollgate-protocol.md §3.2
Seller->>Buyer: PriceSheet 1 product, pps=10, ppu=1
Note right of Seller: +10092ms
Note over Buyer,Seller: tollgate-protocol.md §3.3
Buyer->>Seller: Accept product selected, interval=[2500,10000]
Note right of Buyer: +10093ms
Note over Buyer,Seller: tollgate-bootstrap.md §3
end
rect rgb(230, 255, 237)
Note right of Buyer: Payment phase
Buyer->>Seller: BootstrapToken 100 sat cashuB V4
Note right of Buyer: +10259ms
Seller-->>Buyer: BootstrapAck Accepted
Note right of Seller: +12449ms
Note over Buyer,Seller: credit: 100 sat × 1000 = 100,000 scaled pricing: 10 sat/s + 1 sat/unit remaining: 100.000 sat
Note right of Buyer: +12449ms
Note over Buyer,Seller: tollgate-metering.md §2
end
rect rgb(255, 248, 225)
Note right of Buyer: Metering phase
Buyer->>Seller: MeteringReport interval 1: elapsed=5000ms
Note right of Buyer: +12449ms
Note over Buyer,Seller: interval 1: cost=51000, cum.cost=51000 delivered: 1000 bytes in 5000ms remaining: 49.000 sat (49000 scaled)
Note right of Buyer: +12449ms
Buyer->>Seller: MeteringReport interval 2: elapsed=10000ms
Note right of Buyer: +12450ms
Note over Buyer,Seller: interval 2: cost=100950, cum.cost=102000 delivered: 2000 bytes in 10000ms remaining: -2.000 sat (-2000 scaled)
Note right of Buyer: +12450ms
Buyer->>Seller: MeteringReport interval 3: elapsed=15000ms
Note right of Buyer: +12450ms
Note over Buyer,Seller: interval 3: cost=150900, cum.cost=153000 delivered: 3000 bytes in 15000ms remaining: -53.000 sat (-53000 scaled)
Note right of Buyer: +12450ms
Note over Buyer,Buyer: tollgate-bootstrap.md §3
end
rect rgb(230, 255, 237)
Note right of Buyer: Payment phase
Buyer->>Seller: BootstrapToken 50 sat cashuB V4 (top-up)
Note right of Buyer: +12626ms
Seller-->>Buyer: BootstrapAck Accepted (top-up)
Note right of Seller: +12885ms
Note over Buyer,Seller: tollgate-bootstrap.md §4
Note over Buyer,Seller: top-up: +50 sat (+50,000 scaled) new credit: previous remaining + 50,000 scaled
Note right of Buyer: +12885ms
Note over Buyer,Seller: tollgate-protocol.md §3.5
end
rect rgb(255, 235, 233)
Note right of Buyer: Teardown phase
Buyer->>Seller: Disconnect Other
Note right of Buyer: +12885ms
end
Balance over time — Bootstrap
Remaining balance (sat) after each metering event. Red = depleted.
Step-by-step walkthrough — Bootstrap
Loading trace data…
Raw JSON trace — Bootstrap (machine-readable)
Spilman Payment Channel
Spilman Payment Channel
Alice opens a Spilman payment channel with Charlie. She locks 100 sat in the channel via Cashu ecash,
and then sends signed balance updates as she pays for service. The channel stays open across multiple
payments — only the cumulative balance moves. No per-payment mint interaction needed.
Alice (Buyer/Sender)
Opens the channel, funds it with 100 sat, and signs balance updates as she pays for service.
Charlie (Seller/Receiver)
Verifies the channel, accepts signed balance updates, and settles at the mint when the channel closes.
Mint
Issues ecash proofs for channel funding. Swaps channel proofs for spendable tokens on settlement.
Professor view: who can claim what, and when?
Think of the channel as a locked box. Alice puts 100 sat in the box. Charlie cannot take more than Alice has signed over to him. Alice cannot take everything back until the timeout path is valid.
Student question
Why do Alice and Charlie both compute the same secret during setup?
Professor answer
The shared secret makes the funding proofs deterministic. Charlie can verify the proofs belong to this channel before accepting balance updates.
Moment
Charlie can claim
Alice can recover
After funding, before updates
0 sat
100 sat after expiry, or all change cooperatively
After latest update = 40 sat
40 sat using the latest signed update
60 sat change through cooperative close or timeout/refund path
After expiry if Charlie never settles
No newer claim than the latest update he still holds
Refund path becomes available to Alice
Public testnut claim lab: keys, artifacts, and actions
Loading public testnut claim artifacts…
Interactive Explorations
Hands-on tools to explore how Spilman payment channels work step by step.
Close-Path Simulator
Explore what happens during each channel close path. Each tab shows the animated flow of actions between Alice, Charlie, and the Mint.
Balance Slider
Drag the slider to explore how channel balance affects settlements. Watch the denomination split and close-path outcomes change in real-time.
40sat to Charlie
01025405075100
Channel balance split (100 sat capacity)
40 sat
60 sat
Charlie's claim
Alice's remaining
Channel Lifecycle Quiz
Test your understanding of the Spilman channel protocol. Five questions covering the key concepts from the walkthrough above.
0 / 5 correct
Proof Anatomy Explorer
Click each field of a Cashu proof to learn what it does and why it matters for channel security. The blinding flow shows how proofs are created.
Proof structure
Blinding flow
Protocol sequence — Spilman
Solid arrows (→) are requests ·
Dashed arrows (⇢) are responses ·
Numbers are auto-sequenced ·
Timing is relative to start
Spilman-Setup
Spilman-Funding
Spilman-Balance
Spilman-Settlement
sequenceDiagram
autonumber
participant Alice
participant Charlie
participant Mint
Note over Alice,Charlie: Spilman-Setup
rect rgb(230, 245, 255)
Note right of Alice: Setup phase
Note over Alice: KeyGen generating buyer (sender) keypair
Note right of Alice: +0ms
Note over Charlie: KeyGen generating seller (receiver) keypair
Note right of Charlie: +2ms
Note over Alice,Charlie: computing shared channel secret via ECDH
Note right of Alice: +2ms
Note over Alice,Alice: NUT-02
Alice->>Mint: KeysetFetch GET /v1/keysets + GET /v1/keys/(id)
Note right of Alice: +3ms
Mint-->>Alice: KeysetInfo keyset_id=008e808b89acc141 fee_ppk=10
Note right of Mint: +6118ms
Note over Alice,Charlie: Spilman-Setup
Note over Alice: ChannelParams computing funding_token_amount for capacity=100
Note right of Alice: +6118ms
Note over Alice,Charlie: channel_id=01b369c082b48a1d...
Note right of Alice: +6121ms
Note over Alice: Spilman-Funding
Note over Alice: FundingOutputs creating deterministic blinded funding outputs
Note right of Alice: +6121ms
Note over Alice,Alice: NUT-04
Alice->>Mint: MintQuote requesting 102 sat for channel funding
Note right of Alice: +6132ms
Mint-->>Alice: MintProofs funding proofs minted (102 sat)
Note right of Mint: +8222ms
Note over Charlie,Alice: Spilman-Funding
Note over Charlie: VerifyChannel verifying DLEQ, value, deterministic secrets
Note right of Charlie: +8223ms
Note over Charlie,Alice: DLEQ OK, value OK, deterministic secrets OK
Note right of Charlie: +8235ms
Note over Alice,Alice: Spilman-Balance
end
rect rgb(230, 255, 237)
Note right of Alice: Payment phase
Alice->>Charlie: BalanceUpdate signed balance update: cumulative=10 sat
Note right of Alice: +8235ms
Charlie-->>Alice: BalanceAck verified: balance=10 sig=079c85c3afaa446d... channel=01b369c082b48a1d
Note right of Charlie: +8247ms
Alice->>Charlie: BalanceUpdate signed balance update: cumulative=25 sat
Note right of Alice: +8247ms
Charlie-->>Alice: BalanceAck verified: balance=25 sig=a03925d671f6d4f8... channel=01b369c082b48a1d
Note right of Charlie: +8259ms
Alice->>Charlie: BalanceUpdate signed balance update: cumulative=40 sat
Note right of Alice: +8259ms
Charlie-->>Alice: BalanceAck verified: balance=40 sig=35ffca5376892eae... channel=01b369c082b48a1d
Note right of Charlie: +8270ms
Note over Alice,Mint: Spilman-Settlement
end
rect rgb(255, 235, 233)
Note right of Alice: Teardown phase
Alice->>Charlie: ChannelClose cooperative close: final balance=40 sat
Note right of Alice: +8270ms
end
rect rgb(230, 245, 255)
Note right of Charlie: Setup phase
Charlie->>Mint: SwapProofs Charlie swaps final proofs at mint for spendable tokens
Note right of Charlie: +8270ms
Mint-->>Charlie: SwapComplete 40 sat swapped to Charlie's wallet
Note right of Mint: +8270ms
Note over Alice: Refund Alice receives 60 sat refund (capacity - paid)
Note right of Alice: +8270ms
Note over Alice,Charlie: cooperative: Alice and Charlie use latest balance=40, Charlie claims 40, Alice receives 60 change
Note right of Alice: +8270ms
Note over Charlie,Mint: unilateral: Charlie can submit latest signed update via /channel/(id)/unilateral-close if Alice disappears
Note right of Charlie: +8270ms
Note over Alice,Mint: timeout: after expiry_timestamp=1778885400, Alice can use refund path for unclaimed remainder
Note right of Alice: +8270ms
end