From zama-skills
Author confidential Solidity contracts using @fhevm/solidity (euint, ebool, eaddress, ACL, FHE.allowThis). Use when the user wants to write or modify FHE-aware smart contracts, integrate OpenZeppelin Confidential Contracts (ERC-7984, governance), or pick a decryption path (public/user/oracle).
How this skill is triggered — by the user, by Claude, or both
Slash command
/zama-skills:contractThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
<!-- @sync:prompt:mcp-prerequisite -->
This skill talks to two MCP servers. The first is required; the second is recommended for higher-quality UI output.
| MCP | Status | Why | Install |
|---|---|---|---|
context7 | REQUIRED | Live Zama / OpenZeppelin Confidential / fhEVM docs (anti-hallucination guarantee) | claude mcp add context7 -- npx -y @upstash/context7-mcp |
magic (21st.dev) | RECOMMENDED for /zama-frontend and /zama-design | Production-grade UI component scaffolding (shadcn-flavored, design-system-aware) | claude mcp add magic -- npx -y @21st-dev/magic (sign-in required) |
Before invoking any mcp__context7__* or mcp__magic__* tool, verify the tool is available. If a context7 call would fail (tool not found / not in the available tool list):
STOP. Do NOT generate any code or write any file.
Tell the user (verbatim, do not paraphrase):
This skill requires the context7 MCP server to fetch live Zama documentation.
It does not appear to be installed.
Install it (one-time setup):
claude mcp add context7 -- npx -y @upstash/context7-mcp
After install, restart Claude Code (or run /mcp to verify) and re-run this skill.
Wait for the user to confirm install. Re-attempt the call. If it still fails, tell the user to run /zama-doctor for a full diagnostic.
If a magic call would fail (only relevant for /zama-frontend and /zama-design UI generation):
Do NOT stop — magic is optional. Continue with hand-authored shadcn components.
Tell the user (once, near the start of UI generation):
Magic MCP (21st.dev) is not installed. UI components will be hand-authored
using shadcn primitives. For higher-quality, design-system-aware components,
install Magic:
claude mcp add magic -- npx -y @21st-dev/magic
Then restart Claude Code and re-run this skill.
Continue without magic.
context7 is hard-required. Every Zama / OpenZeppelin / fhEVM API the skill emits is verified against /zama-ai/fhevm (1772 HIGH-reputation snippets) and /websites/openzeppelin_confidential-contracts (354 snippets). A WebFetch fallback would weaken the anti-hallucination guarantee — if context7 is unavailable, the right answer is to fix the setup, not to silently degrade.
Run /zama-doctor — it lists every required and recommended MCP/tool with install commands and a status check.
Single source of truth. Every SKILL.md in this plugin transcludes this block via a
@sync:shared:context7-querymarker pair. Edit here, runpnpm sync, and all skills update.
Zama Protocol package surfaces (@fhevm/solidity, @zama-fhe/relayer-sdk, @fhevm/hardhat-plugin, @openzeppelin/confidential-contracts) evolve faster than any LLM training cut-off. To avoid hallucinated APIs, always query context7 for live documentation before emitting Zama-related code.
When this skill activates, BEFORE generating any Solidity, TypeScript, or config file that touches fhEVM, perform the following calls in order:
Resolve the primary fhEVM library
mcp__context7__resolve-library-idlibraryName: "fhevm" → expect /zama-ai/fhevm (HIGH reputation, ~1772 snippets).Fetch topic-scoped fhEVM docs for the operation in progress
mcp__context7__get-library-docscontext7CompatibleLibraryId: "/zama-ai/fhevm"topic: narrowed to the user's question (e.g., "acl", "decryption", "euint", "relayer", "auction").Fetch hardhat-template scaffolding docs when generating build/test infra
context7CompatibleLibraryId: "/zama-ai/fhevm-hardhat-template"topic: such as "deploy", "test", "mock".Fetch OpenZeppelin Confidential Contracts when generating tokens, governance, or vesting
context7CompatibleLibraryId: "/websites/openzeppelin_confidential-contracts"topic: such as "ERC7984", "VotesConfidential", "FHESafeMath".Fallback narrowing — if returned docs are too broad, re-call get-library-docs with a tighter topic: parameter focused on the user's exact question.
fhevmjs or fhevm (root package). Both were officially deprecated 2025-07-10. Replacements are @zama-fhe/relayer-sdk and @fhevm/solidity respectively.pinned-versions.json, the JSON wins. That file was npm-registry-verified on 2026-05-03 and reflects peer-dep alignment across the Zama stack. Treat docs as API guidance; treat the JSON as version truth.https://docs.zama.org/protocol/protocol-apps/addresses/testnet/sepolia at skill runtime.| Library ID | Snippets | Use For |
|---|---|---|
/zama-ai/fhevm | 1772 | Solidity FHE primitives, ACL, decryption, encrypted types |
/zama-ai/fhevm-hardhat-template | 43 | Hardhat config, deploy scripts, mock testing |
/websites/openzeppelin_confidential-contracts | 354 | ERC-7984, governance, FHESafeMath |
You are operating inside a Zama Protocol skill. Before emitting any package import, dependency declaration, or install command, you MUST consult the deprecation/incompatibility ban list.
Before emitting ANY import statement, package.json dependency entry, or npm install / pnpm add command:
plugins/zama-skills/shared/deprecated-imports.json.deprecated key:
replaces instead.// fhevmjs deprecated 2025-07-10; using @zama-fhe/relayer-sdk).incompatible key:
useInstead instead.// hardhat v3 incompatible with @fhevm/hardhat-plugin peer range).plugins/zama-skills/shared/pinned-versions.jsonplugins/zama-skills/shared/snippets/deprecation-guard.mdTwo Zama packages were officially deprecated 2025-07-10. Two adjacent packages are incompatible with the current fhEVM plugin and must not be installed.
| Package | Status | Replacement |
|---|---|---|
fhevmjs | Deprecated 2025-07-10. Official npm message: "use @zama-fhe/relayer-sdk instead" | @zama-fhe/relayer-sdk |
fhevm (root pkg) | Deprecated 2025-07-10. Official npm message: "use @fhevm/solidity instead" | @fhevm/solidity |
| Package | Reason | Use Instead |
|---|---|---|
hardhat@^3.x | fhevm-plugin peer-dep is hardhat@^2.0.0; v3 untested + breaking config changes. | hardhat@^2.28.4 |
ethers@^5 | fhevm-plugin pins ethers v6; v5 mismatches typechain output. | ethers@^6.16.0 |
If the user asks me to import
fhevmjsorfhevm(root pkg), I refuse and propose the modern replacement instead. No fallback workaround is offered for deprecated packages — they are unsafe (no upstream support, frozen API, will fail against current Sepolia relayer/KMS contracts).
The same refusal applies to hardhat@^3.x and ethers@^5 until the fhEVM plugin upgrades its peer dependency range.
The following versions are the authoritative pin set for this plugin. They were verified via direct npm view queries against the npm registry on 2026-05-03 and cross-checked against the fhevm-hardhat-template package.json for peer-dep alignment.
| Package | Version | Notes |
|---|---|---|
@fhevm/solidity | ^0.11.1 | Solidity FHE library. Replaces deprecated fhevm (root pkg). OZ confidential pins this exactly. |
@fhevm/hardhat-plugin | ^0.4.2 | Mock encrypt/decrypt + local FHE node for tests. |
@fhevm/mock-utils | 0.4.2 | Exact-version peer of hardhat-plugin. |
@fhevm/host-contracts | 0.10.0 | Pulled in transitively by hardhat-plugin. |
@zama-fhe/relayer-sdk | ^0.4.2 | Frontend SDK. Replaces deprecated fhevmjs. Use exact 0.4.1 in devDeps to match plugin peer; ^0.4.2 in frontend deps. |
@openzeppelin/confidential-contracts | ^0.4.0 | ERC-7984, VotesConfidential, FHESafeMath. |
@openzeppelin/contracts | ^5.6.1 | Required peer of confidential-contracts. |
@openzeppelin/contracts-upgradeable | ^5.6.1 | Optional, paired with above. |
encrypted-types | ^0.0.4 | Shared TS types for encrypted handles. |
ethers | ^6.16.0 | v6 only — fhevm plugin pins v6 and v5 will mismatch typechain output. |
hardhat | ^2.28.4 | v2 line. fhevm plugin peer-deps hardhat@^2.0.0. Do NOT use Hardhat 3 yet. |
solc | 0.8.27 | Compiler version pinned by template (supports ^0.8.24+). |
| Node.js | >=20 | Matches fhevm-hardhat-template engines field. LTS, ESM-first. |
| Package | Last Version | Replacement |
|---|---|---|
fhevmjs | 0.6.2 (deprecated 2025-07-10) | @zama-fhe/relayer-sdk |
fhevm (root pkg) | 0.6.2 (deprecated 2025-07-10) | @fhevm/solidity |
| Package | Reason |
|---|---|
hardhat@^3.x | fhevm plugin peer-dep is hardhat@^2.0.0; v3 breaking config changes. Revisit Q3 2026. |
ethers@^5 | fhevm plugin pins ethers v6; v5 mismatches typechain output. |
The Zama Protocol Access Control List (ACL) governs which addresses may decrypt a given encrypted handle (euint*, ebool, eaddress).
Every state-write that produces or stores an encrypted handle MUST be followed by an ACL grant in the same transaction:
FHE.allowThis(handle) — required so the contract itself can read the handle in subsequent calls. Forgetting this breaks future reads.FHE.allow(handle, msg.sender) — required if the caller needs to user-decrypt the value later via the relayer SDK.FHE.allow(handle, otherAddress) — grant decryption to a third party (e.g., counterparty in an auction settlement).@fhevm/solidity@^0.11.1 ACL primitives (FHE.allowThis, FHE.allow, FHE.makePubliclyDecryptable).@fhevm/[email protected] — older examples (0.10.x and earlier) use a different API surface./zama-ai/fhevm topic: "acl" before generating new patterns.Writing state.balance = FHE.add(state.balance, amount) without FHE.allowThis(state.balance) afterwards leaves the contract unable to read its own state next call. This will silently fail downstream.
Zama Protocol exposes three ways to reveal an encrypted handle's plaintext. Choosing the wrong one leaks data or makes the dApp unusable. Always confirm with the user which path applies BEFORE generating decrypt logic.
FHE.publicDecryptuserDecrypt (client-side)@zama-fhe/relayer-sdk. The contract must have called FHE.allow(handle, userAddress) first.FHE.requestDecryption callbackAsk the user which path applies BEFORE generating decrypt logic. If unspecified, default-refuse and prompt for clarification. Picking the wrong path is a privacy bug, not a feature gap.
Confirm the exact signature for the chosen path via context7 /zama-ai/fhevm topic: "decryption" — the API surface evolved across @fhevm/[email protected] → 0.11.x and the older examples on the open web are stale.
Generate a fhEVM-ready confidential Solidity contract with auto-injected ACL grants, refused cleartext-leak patterns, and an HCU budget reminder. The skill walks the user through a 4-question prompt flow, materializes a Solidity template, post-processes it through acl-injector + cleartext-guard, and writes the file to packages/contracts/contracts/<Name>.sol.
Before doing anything, run:
node ${CLAUDE_SKILL_DIR}/scripts/lib/preflight.ts
This validates the active workspace contains packages/contracts/ and lists @fhevm/solidity in package.json. If the check fails, print:
Run
/zama-initfirst to scaffold the project.
…and STOP. Do not proceed to Step 2.
Use AskUserQuestion (multi-question form) to collect the contract spec. Run the four questions one at a time so each answer can validate the next.
Q1 — Contract name (free text, validate ^[A-Z][A-Za-z0-9]+$)
Re-prompt if invalid. Reject path-traversal segments (e.g., .., /, \).
Q2 — Base contract (single-select)
| Option | Description |
|---|---|
ERC7984 (confidential token) | Extends @openzeppelin/confidential-contracts/token/ERC7984.sol. Use for confidential ERC-20-style tokens. |
VotesConfidential (governance) | Extends @openzeppelin/confidential-contracts/governance/VotesConfidential.sol. Use for confidential voting / DAOs. |
Standalone | No base contract beyond SepoliaConfig. Use for custom logic (auctions, escrows, counters). |
Ownable extension | Standalone + Ownable from @openzeppelin/contracts/access/Ownable.sol. |
Q3 — State schema (repeat-prompt loop)
For each field, prompt three sub-questions until the user answers done:
^[a-z][A-Za-z0-9]*$)euint8 / euint16 / euint32 / euint64 / ebool / eaddressnone (single slot) / address (mapping(address => T)) / uint256 (mapping(uint256 => T))Record the answers as the schema: ContractInputs["schema"] array.
Q4 — Decryption path (single-select; each option carries an example signature)
| Option | Description |
|---|---|
public (anyone can decrypt) | Emits FHE.makePubliclyDecryptable(handle). Example: function publish() external { FHE.makePubliclyDecryptable(result); } |
user (caller only via FHE.allow) | Emits FHE.allow(handle, msg.sender). Example: function getMine() external returns (euint64) { FHE.allow(balance[msg.sender], msg.sender); return balance[msg.sender]; } |
oracle (off-chain relayer with allowlist) | Emits FHE.requestDecryption(...) + callback. Example: function settle() external { FHE.requestDecryption(handle, this.onDecrypted.selector); } |
Generated contracts MUST NOT contain any of the following patterns. The runtime guard at ${CLAUDE_SKILL_DIR}/scripts/lib/cleartext-guard.ts enforces this — if the post-processed Solidity matches any pattern below, generation aborts with the canonical replacement message.
| # | Forbidden pattern | Canonical replacement |
|---|---|---|
| 1 | require(FHE.decrypt(x)) | FHE.allow(x, recipient) + off-chain decrypt via relayer |
| 2 | require(decrypt(x)) | (same — decrypt(...) is not a valid runtime call on encrypted handles) |
| 3 | if (FHE.decrypt(x)) | ebool cond = FHE.lt(...); FHE.allow(cond, recipient); |
| 4 | if (decrypt(x)) | (same) |
| 5 | euint64 a; … if (a == b) | FHE.eq(a, b) |
| 6 | euint64 a; … a != b | FHE.ne(a, b) |
| 7 | euint64 a; … a < b | FHE.lt(a, b) |
| 8 | euint64 a; … a > b | FHE.gt(a, b) |
| 9 | euint64 a; … a <= b | FHE.le(a, b) |
| 10 | euint64 a; … a >= b | FHE.ge(a, b) |
| 11 | ebool b; … if (b) (boolean cleartext branching) | euint64 v = FHE.select(b, x, y); |
| 12 | decrypt(<euint storage slot>) | FHE.allow(slot, msg.sender) and decrypt off-chain |
Refusal contract: if the user explicitly asks for a forbidden pattern, refuse and provide the canonical replacement above. Do not offer "just for debugging" fallbacks — they ship to Sepolia by default.
Every state-write of an encrypted handle MUST be followed by FHE.allowThis(handle);. Every handle returned to a caller MUST also have FHE.allow(handle, msg.sender); immediately before the return statement. The post-processor at ${CLAUDE_SKILL_DIR}/scripts/lib/acl-injector.ts injects both grants idempotently after template materialization.
If a generated contract is later edited by hand:
FHE.allowThis(...) lines emitted by the generator.state = FHE.add(...) writes without an immediate FHE.allowThis(state); afterward — the contract will silently fail to read its own state on the next call.Reference: @fhevm/solidity@^0.11.1 ACL primitives (FHE.allowThis, FHE.allow, FHE.makePubliclyDecryptable).
Every emitted contract begins with this header comment:
// HCU budget: 20M/tx, 5M depth.
// Heavy loops + nested FHE.select can exceed; use `pnpm gas-report` to profile.
The generator additionally injects a one-line reminder above any for / while body or nested FHE.select(...) call when the template contains them.
Once the four questions are answered, invoke:
node ${CLAUDE_SKILL_DIR}/scripts/generate.ts --inputs "$(cat <<'JSON'
{ "name": "...", "base": "...", "schema": [...], "decryptionPath": "..." }
JSON
)"
Capture the printed output path. If the cleartext-guard aborts, surface the canonical replacement message verbatim — do not attempt to "fix" the template by deleting the guard.
To overwrite an existing file, append --force. Without it, generation aborts with a file exists error.
Print a 4-line summary on success:
Wrote: packages/contracts/contracts/<Name>.sol
ACL grants injected: <N>
This contract refuses 12 known cleartext-leak patterns.
Next: run /zama-test to generate mock + Sepolia tests for this contract.
{{name}}.sol{{path}}{{aclCount}} (FHE.allowThis / FHE.allow)assertNoCleartextLeak)// HCU budget: 20M/tx, 5M depth)Every state-write that produces an encrypted handle is paired with FHE.allowThis(handle); handles exposed to users get FHE.allow(handle, msg.sender). The skill refused to emit any require(decrypt(...)), if (decrypt(x)), or comparison against a cleartext value — the canonical replacement uses FHE.lt / FHE.eq returning an ebool.
context7 was queried at scaffold time — every Solidity API used is verified against
/zama-ai/fhevm(HIGH reputation, 1772 snippets), no hallucinated symbols.
/zama-test to generate mock + Sepolia tests for {{name}}.npx claudepluginhub kocaemre/zama-skills --plugin zama-skillsProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.