Skip to main content
HideMe runs entirely in the browser on Ethereum mainnet. You need a wallet with ETH for gas — no test network, no faucet, no setup required.
1

Connect your wallet

Open the HideMe app and click Connect Wallet. HideMe uses RainbowKit for wallet connection and supports MetaMask, Coinbase Wallet, WalletConnect, and any injected EVM wallet.Make sure your wallet is set to Ethereum mainnet (chain ID 1). You need a small amount of ETH to cover gas for encrypted operations — these transactions are more compute-intensive than standard ERC-20 transfers.
HideMe does not require any off-chain account, API key, or sign-up. Your wallet is your identity.
2

Browse the token registry

The home page shows every confidential token deployed through HideMeFactory. Each card displays the token name, symbol, total supply, and creator address.The factory contract at 0x46E16F6E248dfa735D50345b1d2657C8dBC5d60B stores on-chain metadata for every token: name, symbol, initial supply, mintability, burnability, description, logo URI, and website. The frontend queries this using getTokensPaginated().Click any token card to open the token detail page, where you can transfer, check your balance, and view the contract on Etherscan.
3

Create a token or use an existing one

To create your own confidential token, click Create Token from the registry page. You configure the following parameters:
ParameterDescription
nameFull token name (e.g. “My Private Token”)
symbolTicker symbol (e.g. “MPT”)
initialSupplyTokens minted to you at deploy time (6 decimals)
mintableWhether the owner can mint additional tokens later
burnableWhether holders can burn their own tokens
maxSupplyHard cap on total supply (0 = unlimited)
observersCompliance addresses that can decrypt any balance
The factory deploys a new HideMeToken contract and records the metadata on-chain in a single transaction. Your initial supply is minted directly to your address as an FHE ciphertext.
If you just want to try encrypted transfers, use one of the existing tokens in the registry — you don’t need to deploy your own.
4

Make an encrypted transfer

On the token detail page, enter a recipient address and an amount, then click Transfer.Before the transaction is submitted, your browser encrypts the amount using the Zama TFHE WASM library loaded from /sdk/relayer-sdk.js. The encryption happens entirely client-side:
export async function encryptAmount(
  contractAddress: string,
  userAddress: string,
  amount: bigint,
): Promise<{ handle: `0x${string}`; inputProof: `0x${string}` }>
The function calls createEncryptedInput(contractAddress, userAddress), adds the uint64 value with .add64(amount), and calls .encrypt(). This returns a handle (a reference to the ciphertext) and an inputProof (a zero-knowledge proof that the encrypted value was formed correctly).Both values are passed to HideMeToken.transfer(to, encryptedAmount, inputProof). On-chain, FHE.fromExternal() verifies the proof and returns the encrypted euint64. The contract then performs the balance check and update entirely on encrypted values — the EVM never sees the plaintext amount.
Transfer events always emit amount = 0. This is intentional: the event is required for ERC-20 compatibility, but the real amount must not appear in logs.
If you are in an environment where the Zama relayer is not directly accessible, set NEXT_PUBLIC_USE_MINI_RELAYER=true in your .env.local. This routes decryption requests through the app’s own /api/decrypt route instead of calling relayer.mainnet.zama.org directly.
5

Check your balance

Click Decrypt Balance on the token detail page. Your wallet will prompt you to sign an EIP-712 message — this signature is the proof that you are the account owner and authorizes the Zama KMS network to return your decrypted balance.The decrypt flow is handled by decryptUserBalance():
export async function decryptUserBalance(
  contractAddress: string,
  ciphertextHandle: string,
  walletClient: {
    signTypedData: (args: {
      domain: Record<string, unknown>;
      types: Record<string, Array<{ name: string; type: string }>>;
      primaryType: string;
      message: Record<string, unknown>;
    }) => Promise<string>;
    account: { address: string };
  },
): Promise<bigint>
The function generates a temporary keypair, creates an EIP-712 request scoped to the contract address and a 10-day validity window, and calls fhevm.userDecrypt(). The Zama KMS network verifies your signature, checks the ACL on-chain to confirm you are permitted to decrypt the ciphertext handle, and returns the plaintext value encrypted under your temporary public key. Your browser decrypts it locally with the temporary private key.Nothing about your balance is ever sent to a server in plaintext.
To reveal all your encrypted cToken balances at once, go to the Portfolio page and click Decrypt All. This sends a single signTypedData request covering all contracts in one batch.

What’s next

How it works

Learn about the three-layer architecture: Ethereum L1, Zama KMS network, and Gateway Chain.

Private portfolio

Wrap existing ERC-20s into confidential cTokens and manage all your private balances in one place.

Confidential payments

Send ERC-20 payments where the amount is encrypted in transit. The receiver gets plain tokens.

Smart contracts

Read the contract reference for HideMeToken, HideMeFactory, ConfidentialWrapper, and the payment router.

Build docs developers (and LLMs) love