Faucet
The faucet is a testnet-only static Cloudflare Pages app that mints 100 each of zkUSD, zkEUR, zkGBP, and zkPLN on Base Sepolia to a user-supplied EVM address. It exists for onboarding and demos, not for the main deployment.
User flow
The app serves a single static page:
- The user enters an EVM address or fills it from an injected wallet such as MetaMask.
- The page submits
{ address }toPOST /api/mint. - The API immediately returns
{ success: true, userOpHash }after the bundler accepts the UserOperation.
There is no receipt polling, CAPTCHA, password, rate limit, queue, or user wallet signature. The connected wallet is only an address source.
Mint route
The API route builds one sponsored ERC-4337 UserOperation:
| Field | Value |
|---|---|
| Chain | Base Sepolia (84532) |
| Sender | SharedAccount |
| Target | ZKHub |
| Call | publicMint(address zkemt,address to,uint256 amount) |
| Amount | 100_000000 base units per token (100, 6 decimals) |
| Paymaster flow | zk_requestGasAndPaymasterData through createZkBundlerClient |
The route must not fall back to a direct EOA transaction. The faucet holds no signing key of its own; it relies on the stage Paymaster Backend running in open-sponsorship mode and sends an empty partner context. If the stage paymaster is reconfigured with OPEN_SPONSORSHIP=false, the faucet must be reissued partner credentials and the partner-context signing path restored.
Deployment configuration
Required Cloudflare Pages environment variables:
| Variable | Purpose |
|---|---|
CHAIN_SLUG | Deployment to use (e.g. base-sepolia). Selects the chain, services, and addresses from the manifest. |
RPC_URL | Read RPC for the SDK's eth_call/nonce/fee lookups. Optional; defaults to the chain's public RPC. Required on Base mainnet — the public endpoint rate-limits and mints fail with "over rate limit". |
PAYMASTER_PARTNER_ID | Optional. Partner id registered in the Paymaster Backend. Set together with the key to sign the partner context. |
PAYMASTER_PARTNER_PRIVATE_KEY | Optional. Partner signing key for the paymaster context. Omit both to rely on open sponsorship. |
ENTRYPOINT_ADDRESS | Optional override; defaults come from the SDK path |
GITHUB_TOKEN | Build-time only: read:packages token. The install step writes an .npmrc and fetches the published @cardinal-cryptography/core from GitHub Packages. |
Chain + RPC, Bundler URL, Paymaster URL, SharedAccount address, Hub address, and zk token addresses all come from the CHAIN_SLUG deployment manifest in @cardinal-cryptography/core.
On-chain setup:
- Deploy the
ZKHuband the testZKEMTtoken contracts (Hub is shared across all tokens). - Ensure the SharedAccount is deployed on Base Sepolia.
- Call
Hub.setMinter(SHARED_ACCOUNT_ADDRESS, true)once — a single enrollment on Hub authorizes the SharedAccount to mint on every ZKEMT in the deployment. - Configure the Paymaster Backend to allow the Hub address and selector
0x36fac067. If the same backend sponsors direct token operations, also allow the four faucet token addresses. - Fund and stake the paymaster for EntryPoint.
Do not grant faucet minting rights or the publicMint selector in the main deployment.