A private-value transaction may use address credit, owned notes, or both while exposing the same public proof and effects. The credit-capable relation proves sufficiency and checkpoint continuity without revealing the funding composition.
For youRead this after the issuance article when you want to understand the public-to-private boundary.
Before you startKnow that creditAccrued is an address's public lifetime total and never decreases.
- Public stateLifetime creditThe proof privately opens the address's credit leaf and user account.
- Private proofAuthorize and checkSelected account rule + available credit + current checkpoint.
- New outputsOrdinary notes + checkpointUp to four ordinary outputs and one private cumulative-debit checkpoint.
- Public resultThe common private-value shapeFour nullifiers and five outputs reveal neither the funding composition nor the transfer value.
The protocol cannot issue a private note directly to an arbitrary Ethereum address: the address may never have published a PCASH receive key, and one block could otherwise create hundreds of tiny notes. Credit solves the delivery and fragmentation problem by accumulating publicly first. The owner later contributes any positive portion directly to an ordinary private-value transaction, alone or alongside notes.
Available credit is checked, never published
- Lifetime accrual
- creditAccrued
- Cumulative debit
- creditSpent
- Available now
- accrued − spent
- Ordinary outputs
- Up to 4 private notes
- Generated example accrual
- 1.175811238024197692 PCASH
- Debit after spend one
- 0.260000000000000000 PCASH
- Available after spend two
- 0.814811238024197692 PCASH
Inside the proof, the wallet opens the address's current credit leaf and user account under one recent PCASH state. It also opens the latest private checkpoint, if one exists, and zero to three ordinary input notes. The proof checks:
note inputs + credit contribution = native outputs + public fee
new creditSpent = prior creditSpent + credit contribution
new creditSpent ≤ creditAccrued
Neither comparison becomes a public transaction field. One selected installed application authorizes the account's complete transaction, whichever private funding sources participated. CHONK folds that application, the credit-capable protocol kernel, the common private-value finalizer, and the common wire into one proof.
View the source behind this explanationcircuits/stacks/private_value/credit_kernel/src/main.nr:329
One private checkpoint carries the running debit
- Before any spendNo checkpointThe first nullifier is derived from the address's private nullifier key.
- Spend 1checkpoint 0creditSpent = credit contribution
- Spend 2checkpoint 1creditSpent = previous total + credit contribution
- Next spendSpend the current checkpointOnly one successor can consume it.
On the first spend there is no predecessor. The proof derives a unique first-spend nullifier from the address and its private nullifier key, creates the ordinary outputs, and appends checkpoint 0.
Every later spend proves membership of the current checkpoint, publishes that checkpoint's nullifier, and appends a successor with the next index and higher cumulative debit. Because the global nullifier set accepts the predecessor only once, two competing successors cannot both settle. Whether this is the first spend is itself private.
Every successful private-value transaction appends exactly five output commitments. In a credit-bearing action input slot 3 carries the credit-chain nullifier and output slot 4 carries the new checkpoint; their classes remain private. Input slots 0 through 2 and output slots 0 through 3 retain the ordinary note-or-padding grammar.
View the source behind this explanationcircuits/stacks/private_value/credit_kernel/src/main.nr:166
The public transaction does not identify the funding source
| Fact | Observer sees | Why |
|---|---|---|
| Funding composition | Hidden | Notes, credit, and mixed funding share one wire shape |
| Fee and fee recipient | Visible | Nodes must apply the fee credit |
| Funding address | Hidden | Opened only inside the proof |
| Payment amount and recipients | Hidden | Committed in private note outputs |
| Spent total and remaining credit | Hidden | Carried through the checkpoint chain |
| Selected account rule | Hidden | Folded into the same proof |
Note-only, credit-only, and mixed actions share type 0x00, one wire VK, four nullifiers, five output bodies and output-data hashes, one fee, one validity window, and one proof length. The fee amount and recipient remain public because every node must apply that fee as a credit increment, but no field says which private funding sources participated.
The funding address and credit contribution are absent. So are the input notes, recipients, cumulative debit, available credit, first-versus-later branch, selected protocol kernel, and selected authorization application. Nodes verify the proof and apply its opaque commitments without reconstructing any of those facts.
The owner can recover after losing wallet state
The recovery capsule does not reveal the debit to observers. It is encrypted to a deterministic recovery key derived from the owner's private credit nullifier hierarchy, while its exact bytes are bound by the transaction commitment. The latest valid capsule alone determines cumulative spending and therefore current available credit; earlier capsules are needed only to locate and authenticate that terminal checkpoint when no trusted local position survives. The wallet validates any recovered capsule by recomputing the checkpoint body and indexed output commitment.
This makes the chain recoverable from the owner's keys and canonical history rather than a fragile local counter. Capsule usefulness follows the same wallet boundary as recipient delivery: consensus binds opaque bytes but does not prove that a custom wallet constructed useful recovery material. The reference wallet round-trips the capsule before submission; retaining an authenticated terminal checkpoint is an optimization, not a second balance representation.