Your first private note.
Install the toolkit, prepare the browser assets, and connect a wallet to fund a note.
On this page
Prerequisites
- A browser application using React 19.
- One copy of
@openanonymity/zkapi-browser-sdk, supplied through your zkAPI operator. - An EIP-1193 wallet provider and the connected account address.
- Same-origin static hosting for the worker, WASM, proving keys, and browser configuration.
Install the toolkit
npm install @openzk.app/purse reactThe SDK peer is optional in the package manifest because it is distributed through operator access. Add the operator-supplied package to your project separately, using the installation path supplied with it. Keep exactly one SDK instance.
Prepare browser assets
Generate the browser SDK assets into your public directory before starting or building your application.
import { buildBrowserSdkAssets } from "@openanonymity/zkapi-browser-sdk/build";
await buildBrowserSdkAssets({
outDir: "public/zkapi",
publicPath: "/zkapi/",
network: "mainnet",
});The client reads /zkapi/browser-config.json and loads its worker from /zkapi/assets/zkapiWasmWorker.js. Serve these URLs as assets rather than your application’s HTML fallback.
VITE_ZKAPI_NETWORK=mainnetConnect a wallet
Use your existing wallet connection layer. Pass the connected provider to the shared client when it becomes available; the toolkit does not read window.ethereum automatically.
import { useEffect } from "react";
import { purseClient } from "@openzk.app/purse";
export function WalletBridge({ provider }: { provider?: unknown }) {
useEffect(() => {
if (provider) purseClient().setWalletProvider(provider);
}, [provider]);
return null;
}Mount this bridge with the provider returned by your wallet layer. Pass the connected account’s address into the funding component below.
Fund a note
Request a USD-denominated quote, then use that quote to prepare the wallet deposit. The browser installs the funded note after confirmation.
import { usePurse } from "@openzk.app/purse/react";
export function FundNote({ address }: { address?: string }) {
const {
snapshot, requestQuote, startDeposit,
depositStatus, errorMessage,
} = usePurse();
const busy = !["idle", "ready", "failed"].includes(depositStatus);
async function fund() {
if (!address) return;
const quote = await requestQuote(5);
if (quote) await startDeposit(quote, undefined, address);
}
return (
<div>
<p>{snapshot.balanceGwei.toString()} gwei</p>
<button onClick={fund} disabled={!address || busy}>
Fund $5
</button>
<p role="status">{depositStatus}</p>
{errorMessage && <p role="alert">{errorMessage}</p>}
</div>
);
}The provider must already be registered through setWalletProvider. The optional provider argument on startDeposit is not used by the current hook.
Continue with inference, model selection, and withdrawals.
Documentation for the OpenZK browser toolkit. Report a documentation issue ↗