Confidential Token Deploy (fhEVM)
Deploy fully homomorphic encryption (FHE) tokens on fhEVM-compatible networks. Balances and transfers are encrypted on-chain — only authorized parties can decrypt them.
Supported Standards
| Standard | Description |
|---|---|
CONFIDENTIAL_ERC20 | Encrypted ERC-20 with private balances and transfers |
CONFIDENTIAL_ERC20_VOTES | Encrypted ERC-20 with private voting delegation |
CONFIDENTIAL_ERC721 | Encrypted metadata ERC-721 |
Prerequisites
- fhEVM-enabled network — deploy to a network where
is_fhevm = true(e.g., Zama devnet, Inco Rivest) - Network configuration — the target network must have all fhEVM fields populated:
confidential_factory_addressacl_addresscoprocessor_addresskms_verifier_addressgateway_url
- API key — secret key (
sk_...)
tip
Use GET /v1/networks and filter by is_fhevm: true to discover available fhEVM networks.
1. Check Network Support
import Urblock from "@urblock/sdk";
const client = new Urblock({ apiKey: "sk_test_..." });
const networks = await client.networks.list();
const fhevmNetworks = networks.data.filter((n) => n.is_fhevm);
console.log("fhEVM networks:", fhevmNetworks.map((n) => n.name));
Or with curl:
curl https://api.urblock.io/v1/networks \
-H "Authorization: Bearer sk_test_..." | jq '.data[] | select(.is_fhevm == true) | .name'
2. Deploy a Confidential ERC-20
const token = await client.tokens.create({
name: "Private Stablecoin",
symbol: "pUSD",
standard: "ERC20",
network_id: "net_zama_devnet", // or chain_id
initial_supply: "1000000000000000000000000",
confidential: true, // ← enables fhEVM encryption
features: {
mintable: true,
burnable: true,
pausable: true,
},
idempotency_key: "deploy-pusd-001",
});
console.log("Token deployed:", token.id);
console.log("Contract:", token.contract_address);
console.log("Tx hash:", token.deploy_tx);
curl -X POST https://api.urblock.io/v1/tokens \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Private Stablecoin",
"symbol": "pUSD",
"standard": "ERC20",
"network_id": "net_zama_devnet",
"initial_supply": "1000000000000000000000000",
"confidential": true,
"features": { "mintable": true, "burnable": true },
"idempotency_key": "deploy-pusd-001"
}'
3. Deploy Confidential ERC-20 with Votes
caution
CONFIDENTIAL_ERC20_VOTES requires networks with full coprocessor support. Some fhEVM testnets may not yet support encrypted delegate/vote flows.
const govToken = await client.tokens.create({
name: "Private Governance",
symbol: "pGOV",
standard: "ERC20_VOTES",
network_id: "net_zama_devnet",
initial_supply: "10000000000000000000000000",
confidential: true,
features: { mintable: true, burnable: true },
idempotency_key: "deploy-pgov-001",
});
4. Deploy Confidential ERC-721
const nft = await client.tokens.create({
name: "Private Art",
symbol: "pART",
standard: "ERC721",
network_id: "net_zama_devnet",
confidential: true,
features: { mintable: true, burnable: true },
idempotency_key: "deploy-part-001",
});
How It Works
- The API detects
confidential: trueand validates the target network is fhEVM-enabled - The token is deployed via
UrblockConfidentialFactoryinstead of the standard factory - Constructor args include the network's
acl_address,coprocessor_address, andkms_verifier_address - All balance and allowance state is stored as FHE ciphertexts on-chain
- Only the token owner and approved addresses can decrypt balances via the fhEVM gateway
Contract ABIs
Get the full ABIs for integration:
const abi = await client.contracts.getAbi("confidential_erc20");
// Also available: confidential_erc20_votes, confidential_erc721, confidential_factory
See the Contracts & ABIs reference for the full list.
Error Handling
| Error Code | When |
|---|---|
network_not_fhevm | Target network does not support fhEVM |
incomplete_fhevm_config | Network is fhEVM but missing required addresses (acl, coprocessor, kms_verifier) |
confidential_votes_unsupported | ERC20_VOTES with confidential: true not supported on this network |