The easiest way to understand OpenZK is to follow one note. It starts with a visible ETH deposit, becomes private payment state in the browser, and ends when its holder withdraws what remains. Each transition has a different trust and privacy boundary.
Funding creates the note
A user connects an Ethereum wallet, requests a quote for a USD amount, and approves an ETH deposit. The quote determines the ETH amount to send. The transaction funds the vault, and the browser SDK installs the associated note after the deposit is confirmed.
The transaction itself is public. The private part is the note state maintained by the SDK in the browser: its secret material and the current balance used to prepare later proofs. The app can read a snapshot with a balance in gwei, a state status, and a display fingerprint. A fingerprint helps identify the note in an interface; it is not a recovery secret.
A request proves eligibility
When the holder makes a paid inference request, the browser prepares a zero-knowledge proof using its current note state. The proof is checked against protocol rules, including the payment's bounded spend. The service can verify the relation it needs without being handed the note secret or the entire balance.
The current integration then obtains a short-lived inference lease with a spending limit. That limit is linked to the selected model's supported cost tier. The browser uses the leased access to stream a response from OpenRouter. The prompt still goes to the model provider. Privacy of the payment does not encrypt application content on its way to that provider.
Settlement changes the local view
The response can arrive before the local note snapshot reflects the final charge. The React burn hook releases the inference lease, asks the SDK to settle it, and waits briefly for a refreshed balance. The displayed receipt is built from that local change when it becomes available.
If the refreshed balance has not arrived within the wait window, a receipt may say “settled onchain” while its local cost remains unresolved. That display is a reason to inspect the updated state later; it does not mean the request was free.
This separation between streaming and settlement is important when building a UI. Show the answer as it arrives, then show payment state with its own status. A single “complete” label would hide an operational step that matters to the payer.
Exiting closes the note
The holder can request a mutual withdrawal to an Ethereum address. The browser proves the withdrawal conditions, obtains coordinator clearance, and asks the wallet to submit the transaction. The withdrawal returns the remaining value to the public chain.
The package's useExit hook exposes this mutual close path. The protocol's contract escape path is separate and is not a method exposed by the current React wrapper. A UI reset clears a hook's temporary status and error fields; it does not restore or export private note state.
This lifecycle makes the architecture legible: public funding, private payment state, a proof for each spend, and public exit. Developers can inspect the current method signatures and status phases in the client documentation.
