Skip to main content
Version: 0.4.7

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:

  1. The user enters an EVM address or fills it from an injected wallet such as MetaMask.
  2. The page submits { address } to POST /api/mint.
  3. 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:

FieldValue
ChainBase Sepolia (84532)
SenderSharedAccount
TargetZKHub
CallpublicMint(address zkemt,address to,uint256 amount)
Amount100_000000 base units per token (100, 6 decimals)
Paymaster flowzk_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:

VariablePurpose
CHAIN_SLUGDeployment to use (e.g. base-sepolia). Selects the chain, services, and addresses from the manifest.
RPC_URLRead 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_IDOptional. Partner id registered in the Paymaster Backend. Set together with the key to sign the partner context.
PAYMASTER_PARTNER_PRIVATE_KEYOptional. Partner signing key for the paymaster context. Omit both to rely on open sponsorship.
ENTRYPOINT_ADDRESSOptional override; defaults come from the SDK path
GITHUB_TOKENBuild-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:

  1. Deploy the ZKHub and the test ZKEMT token contracts (Hub is shared across all tokens).
  2. Ensure the SharedAccount is deployed on Base Sepolia.
  3. Call Hub.setMinter(SHARED_ACCOUNT_ADDRESS, true) once — a single enrollment on Hub authorizes the SharedAccount to mint on every ZKEMT in the deployment.
  4. 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.
  5. Fund and stake the paymaster for EntryPoint.

Do not grant faucet minting rights or the publicMint selector in the main deployment.