agentsclimarketplace

Cofhe dev

Skill interesting-guy/cofhe-dev-skill/cofhe-dev

Build confidential smart contracts and dApps with Fhenix CoFHE (Fully Homomorphic Encryption coprocessor for EVM chains). Use this skill whenever the user mentions CoFHE, Fhenix, FHE.sol, cofhejs, @cofhe/sdk, FHERC20, ERC-7984, encrypted types (euint/ebool/eaddress), confidential tokens, private balances, encrypted bids/votes, or wants to add privacy/confidentiality to any Solidity contract or EVM dApp. Also use it when debugging "execution reverted" errors, ACLNotAllowed errors, or stuck decryptions in an FHE project — even if the user doesn't name Fhenix explicitly but their code imports cofhe-contracts or @cofhe/sdk.From its SKILL.md

Install
npx -y skills add interesting-guy/cofhe-dev-skill --skill cofhe-dev

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

8.4 KB, ~2.0k tokens by cl100k_base, as published. Nobody here has run it

CoFHE Development (Fhenix)

CoFHE is Fhenix's FHE coprocessor: contracts stay on Ethereum/Arbitrum/Base, heavy FHE computation runs off-chain, data stays encrypted end-to-end. Writing CoFHE code is NOT like writing normal Solidity — naive ports leak information or silently break. This skill encodes the rules that make FHE contracts correct on the first try.

The mental model (read this before writing any code)

  1. Encrypted values are handles, not data. euint32 etc. are wrappers over ciphertext handles (pointers). The actual ciphertext lives in the coprocessor.
  2. Everything is asynchronous. FHE operations are queued and computed off-chain. Results are not available in the same transaction. Design two-phase flows: submit → settle.
  3. Access control is per-handle. Every handle has an ACL. A handle created in a transaction is accessible to the creating contract only for that transaction. Persisting access requires explicit FHE.allow* calls. Forgetting FHE.allowThis() after writing an encrypted value to storage is the #1 bug in CoFHE development.
  4. You cannot branch on encrypted data. No if (encrypted), no require(encrypted). Use FHE.select(cond, a, b) — constant-time, both branches always evaluated.
  5. Ciphertexts don't hide metadata. FHE protects values, not behavior. msg.value, deposit sizes, calldata shape, which function was called, when, and by whom are all public — and any of them correlated with a secret leaks it (e.g., a deposit proportional to a sealed bid reveals the bid). Design rule: every public-facing quantity must be fixed or uniform across users (exact-amount deposits, fixed-size inputs, constant call patterns). When reviewing, ask: "what does a block explorer observer learn from this transaction, ignoring the ciphertexts entirely?"
  6. Decryption is a three-step dance (new flow — FHE.decrypt() is deprecated):
    • Contract grants permission: FHE.allowPublic(ct) / FHE.allow(ct, addr) / FHE.allowSender(ct)
    • Client decrypts off-chain: decryptForTx(ctHash) → returns { ctHash, decryptedValue, signature } (signature from the Threshold Network)
    • Anyone submits on-chain: FHE.publishDecryptResult(ctHash, plaintext, signature) (stores publicly) or FHE.verifyDecryptResult(...) (verifies only)
    • For UI-only display, skip the chain entirely: decryptForView(ctHash, FheTypes.UintXX).

Critical gotchas — check EVERY contract against this list

  • Missing FHE.allowThis() after state updates. Any encrypted value stored for later use needs FHE.allowThis(value) in the same transaction, AFTER the operation that produced it. New handles from FHE.add etc. are new handles — the old permission does not carry over.
  • Missing FHE.allow(value, user) for user-readable values. If a user should be able to decryptForView their balance, the contract must grant them access on every new handle (e.g., after every transfer).
  • Arithmetic is unchecked. euint types wrap around on overflow/underflow — revert-on-overflow would leak information. Guard with comparisons + select, e.g. clamp a transfer amount to the available balance:
    ebool canTransfer = FHE.lte(amount, balance);
    euint64 actualAmount = FHE.select(canTransfer, amount, FHE.asEuint64(0));
    
  • Division/remainder by encrypted zero returns the type's max value (e.g. encrypted 255 for euint8), not a revert. Handle it.
  • ebool is a euint8 under the hood, not a real boolean.
  • No revert paths that depend on encrypted values. Reverting based on plaintext-adjacent conditions derived from ciphertexts leaks information. Constant execution paths only.
  • Use the smallest sufficient bit width (euint32 over euint64 when possible) — FHE ops are expensive and cost scales with width.
  • Reuse encrypted constants. Encrypt 0/1/common thresholds once at init, FHE.allowThis() them, reuse.
  • Trivially encrypted values (FHE.asEuint32(5) from a plaintext literal) are NOT secret — the plaintext was visible on-chain. Real secrets must come in as InEuintXX input structs encrypted client-side with ZK proofs.
  • Do FHE work incrementally per-action, never in settlement loops. Maintain running aggregates (max, sum, winner index) with one gt+select per user action; a settlement function that iterates participants doing FHE comparisons is unbounded gas, a fat async batch, and a griefing vector. Settlement should only flip permissions (allowPublic) and emit.
  • Verify the bit width fits the value RANGE, not just the type. Arithmetic is unchecked: euint64 holding wei caps at ~18.4 ETH, and a larger value silently wraps to a tiny one — no revert, no warning. Re-denominate (e.g., gwei instead of wei) or widen the type.
  • euintXX.unwrap() returns bytes32 in cofhe-contracts 0.1.x, not uint256 — type events/params accordingly.
  • Uninitialized encrypted storage is a landmine. A never-written mapping(address => euint64) entry is handle 0 — any FHE op on it reverts. Initialize encrypted state in the constructor, or guard reads with a fallback: euint64.unwrap(bal) == 0 ? ZERO : bal (where ZERO is a pre-allowed encrypted constant).
  • Cross-contract calls need FHE.allowTransient(ct, otherContract) before passing handles to another contract within a transaction.
  • Permits are scoped to chainId + account. Wrong-chain or wrong-account is the usual cause of mysterious ACL/permit errors client-side.
  • decryptForTx requires exactly one of .withPermit() or .withoutPermit() before .execute(). withoutPermit only works on allowPublic'd handles.

Workflow for any CoFHE task

  1. Identify the task type, then read the matching reference file:
    • Writing/reviewing Solidity contracts → references/contract-patterns.md
    • Frontend/client work, encryption, decryption, permits, or migrating from old cofhejsreferences/client-sdk.md
    • Project setup, testing, debugging errors, network/version questions → references/setup-testing-errors.md
  2. For contracts: write the logic, then run the gotcha checklist above line by line. Pay special attention to every storage write of an encrypted type (allowThis?) and every user-facing value (allow user?).
  3. For clients: default to @cofhe/sdk (NOT cofhejs — it's deprecated). Builder pattern, explicit permits, viem-first.
  4. For two-phase flows (auctions, unshields, reveals): make the async boundary explicit in the design — what is submitted encrypted, what triggers allowPublic, who publishes the decrypt result, and what the UI shows while pending.
  5. Local dev: always start in the mock environment (Hardhat or Foundry plugin) — instant results, plaintext visible for debugging. Move to testnet (Sepolia / Arbitrum Sepolia / Base Sepolia) only after mock tests pass.

Quick facts (current as of June 2026 — verify before relying on versions)

  • Packages: @fhenixprotocol/cofhe-contracts (Solidity, v0.1.x), @cofhe/sdk (TS client, v0.5.x), @cofhe/hardhat-plugin, @cofhe/hardhat-3-plugin, @cofhe/foundry-plugin, @cofhe/mock-contracts, @fhenixprotocol/cofhe-errors (error decoder), @fhenixprotocol/fhenix-confidential-contracts (FHERC20/ERC-7984 primitives).
  • Networks: Sepolia, Arbitrum Sepolia, Base Sepolia (testnet only, API v1).
  • Types: euint8/16/32/64/128, ebool, eaddress; inputs InEuintXX, InEbool, InEaddress. Encrypted randomness: FHE.randomEuintXX() (front-running-proof — see contract-patterns.md for range/coin-flip recipes).
  • Decode revert selectors instantly: npx cofhe-errors 0x<selector>.
  • Docs live at https://cofhe-docs.fhenix.zone — append .md to any page URL for raw markdown, and /llms.txt is the full index. When in doubt about an API that may have changed, fetch the docs rather than guessing.

What ships with it: 3 files

21.6 KB alongside SKILL.md

Keep looking

Skills are one crate of 326,499. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.