From inco
Build confidential smart contracts and dApps on EVM with Inco's TEE-based confidential computing: encrypted types (euint256/ebool/eaddress), encrypted ops (add/sub/mul/select/eq/rand), access control (e.allow), and attestation verification. Use for @inco/lightning Solidity + @inco/lightning-js SDK encrypt/decrypt, Foundry/Hardhat with a local covalidator or Base Sepolia, create-inco-app scaffolding, and confidential tokens, auctions, voting, or lottery dApps. Also covers confidential / hidden-information GAMES — deciding what stays private and which Inco feature goes where, then building fast: casino, cards, board, sealed auction, social deduction, fog-of-war, word/code-guessing. TRIGGER: imports "@inco/lightning" or "@inco/lightning-js" (or legacy "@inco/js"), mentions Inco, confidential EVM contracts, encrypted types, "what should be private in my game", on-chain poker/mafia/minesweeper/word-guessing, fog of war, provably fair. NOT for: ZK proofs, FHE/fhevm circuits.
How this skill is triggered — by the user, by Claude, or both
Slash command
/inco:lightningThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Build confidential smart contracts on EVM chains. Inco uses TEE-based confidential computing to add encrypted data types, operations, and programmable access control to Solidity without modifying the underlying blockchain. This skill covers Inco on **EVM (Inco Lightning)**; Inco's Solana/SVM track is out of scope here.
docs/troubleshooting.mdexamples/attestation-flow.tsexamples/basic-encrypt-decrypt.tsexamples/confidential-token-interaction.tsexamples/session-key-decrypt.tsreferences/deployment-testing.mdreferences/elist-reference.mdreferences/games/archetypes.mdreferences/games/choosing-your-approach.mdreferences/games/frontend.mdreferences/games/overview.mdreferences/games/patterns.mdreferences/games/settlement-and-math.mdreferences/js-sdk-reference.mdreferences/solidity-reference.mdscripts/ConfidentialToken.solscripts/ConfidentialWithAttestation.solscripts/games/hangman/IncoHangMan.solscripts/games/mines/Mines.solscripts/games/mines/MinesFactory.solBuild confidential smart contracts on EVM chains. Inco uses TEE-based confidential computing to add encrypted data types, operations, and programmable access control to Solidity without modifying the underlying blockchain. This skill covers Inco on EVM (Inco Lightning); Inco's Solana/SVM track is out of scope here.
IMPORTANT: Inco is NOT FHE (Fully Homomorphic Encryption). It is TEE-based (Trusted Execution Environment). Never describe Inco as FHE to users. While the developer-facing API uses "encrypted" terminology (euint256, ebool), the underlying cryptographic mechanism is encryption/decryption in TEE, not homomorphic encryption.
allowThis() after storing an encrypted handle - the contract permanently loses access otherwisemsg.value >= inco.getFee() for every newEuint256/newEbool/newEaddress call or wherever consuming a bytes calldata ciphertextif/else with encrypted conditions - use condition.select(ifTrue, ifFalse) instead| Thought | Reality |
|---|---|
"I'll add allowThis() in a cleanup pass" | Access is lost permanently once the tx lands. Add it on the line after every encrypted store. |
"This encrypted condition is simple — if/else is fine" | An ebool is a handle, not a bool. Branching on it is broken code. Use .select(), no exceptions. |
| "Fee handling can come later" | Every ciphertext ingest and rand/shuffle call reverts unfunded. Decide user-pays vs contract-sponsored before writing the function. |
| "The validation checklist is overkill for this small contract" | Small contracts lose handles too. Run the checklist before every deploy. |
Frontend (@inco/lightning-js) Smart Contract (@inco/lightning) Covalidator (TEE)
───────────────────────────── ─────────────────────────────── ──────────────────
zap.encrypt(value) ──────────> newEuint256(bytes, sender)
e.add / e.sub / e.select / ...
e.allow(handle, user)
zap.attestedDecrypt(handle) <──────────────────────────────────── decrypt + sign
submit attestation on-chain -> incoVerifier().isValidAttestation()
npx create-inco-app my-app --chain evm --framework hardhat --wallet rainbowkit --yes
import {euint256, ebool, e, inco} from "@inco/lightning/src/Lib.sol";
contract MyConfidentialContract {
using e for *;
mapping(address => euint256) public balanceOf;
function deposit(bytes memory encryptedAmount) external payable {
require(msg.value >= inco.getFee(), "Fee not paid");
euint256 amount = encryptedAmount.newEuint256(msg.sender);
euint256 newBal = balanceOf[msg.sender].add(amount);
balanceOf[msg.sender] = newBal;
newBal.allow(msg.sender); // User can decrypt
newBal.allowThis(); // CRITICAL: contract retains access
}
}
import { Lightning } from "@inco/lightning-js/lite";
import { handleTypes } from "@inco/lightning-js";
const zap = await Lightning.baseSepoliaTestnet(); // Base Sepolia (chain 84532)
// Encrypt
const ct = await zap.encrypt(100n, {
accountAddress: userAddress,
dappAddress: contractAddress,
handleType: handleTypes.euint256,
});
// Send to contract (with fee as msg.value)
writeContract({ address: contractAddr, abi, functionName: "deposit", args: [ct], value: fee });
// Decrypt (retry if covalidator hasn't processed yet)
const results = await zap.attestedDecrypt(walletClient, [handle]);
const plaintext = results[0].plaintext.value;
create-inco-app's --template maps to three ways to use this skill — load only the slice you need:
--template monorepo, default) — the Quick Start above, then references as needed.--template contracts) — encrypted types, allow/allowThis, fee handling, and .select (never if/else on encrypted conditions); write and unit-test in Foundry/Hardhat with IncoTest. → solidity-reference.md, deployment-testing.md, scripts/ConfidentialToken.sol.--template frontend, integrating an already-deployed confidential contract) — encrypt/decrypt against a contract you may not own. → js-sdk-reference.md (integrating an existing contract), examples/basic-encrypt-decrypt.ts, scripts/incoHelper.ts.Designing a hidden-information game (casino/provably-fair, cards, board, sealed auction, social deduction, fog-of-war, word/code guessing)? The base API on this page still applies — but start at references/games/overview.md: it has the decision tree (what's secret, when does it reveal), the archetype catalog, the cross-cutting moves, the two settlement models, and the frontend loop. Load only the games references the task needs.
Design before code (RIGID): do NOT write any Solidity until you have answered the decision tree — what is secret, from whom, and when does it reveal. Code written before those answers bakes in the wrong privacy boundary and gets rewritten. "The game is simple, I'll design as I go" is the red flag — simple games still leak through event logs, public state, and reveal timing.
euint256, ebool, eaddress - all are bytes32 handles pointing to encrypted data off-chain.
With using e for *;, there are two equivalent calling styles:
// Style 1: variable.operation(other) - method syntax on the encrypted variable
euint256 sum = a.add(b);
ebool isGreater = a.ge(b);
euint256 result = condition.select(ifTrue, ifFalse);
// Style 2: e.operation(a, b) - static call via the `e` library
euint256 sum = e.add(a, b);
ebool isGreater = e.ge(a, b);
euint256 result = e.select(condition, ifTrue, ifFalse);
Both are identical. Use whichever reads better in context.
Static-only operations (no variable to call on):
e.rand() // Random euint256
e.randBounded(n) // Random euint256 in [0, n)
e.asEuint256(42) // Plaintext -> encrypted handle
e.asEbool(true) // Plaintext -> encrypted handle
e.asEaddress(addr) // Plaintext -> encrypted handle
Available operations:
Math: add, sub, mul, div, rem, and, or, xor, shr, shl
Compare: eq, ne, ge, gt, le, lt, min, max, not
Control: select(ifTrue, ifFalse) (first arg = value when condition is true) - NEVER use if/else with encrypted conditions
newValue.allow(userAddress); // User can decrypt
newValue.allowThis(); // Contract can use in future txs
Forgetting allowThis() = contract loses access to the handle permanently.
Every newEuint256/newEbool/newEaddress call (and rand/randBounded/shuffle) charges inco.getFee(), drawn from the contract's balance. Either the user pays it (payable + require(msg.value >= inco.getFee())) or you pre-fund the contract to sponsor it (gasless for the caller). See Fee Payment.
require(inco.incoVerifier().isValidDecryptionAttestation(decryption, signatures), "Invalid");
require(euint256.unwrap(myHandle) == decryption.handle, "Handle mismatch"); // ALWAYS check
Before deploying any Inco contract, verify:
.allowThis().allow(userAddress)payable with fee checkif/else or require on encrypted conditions (use .select())using e for *; is declared in the contractaccountAddress and dappAddress@inco/lightning in v1) - see elist-reference.mdMines.sol + MinesMath.sol + MinesFactory.sol)e.eq match, private per-player decrypt, client-side settlement. POC — see header caveatsCommon issues and fixes: docs/troubleshooting.md Covers: fee errors, missing allowThis, covalidator timeouts, handle formatting, Docker issues, Foundry test pitfalls.
ebool canTransfer = balanceOf[sender].ge(amount);
euint256 transferred = canTransfer.select(amount, e.asEuint256(0));
// Transfers 0 instead of reverting - hides the failure reason
// EOA: encrypted bytes input (requires fee)
function transfer(address to, bytes memory input) external payable { ... }
// Contract: existing handle (requires isAllowed check)
function transfer(address to, euint256 value) public { ... }
zap.encrypt(value) -> ciphertext bytesnewEuint256(bytes, sender) -> handle, then encrypted operationse.allow(result, user) -> grant decryption accesszap.attestedDecrypt(walletClient, [handle]) -> plaintext + signatures| Package | Version | Purpose |
|---|---|---|
@inco/lightning | latest (v1+) | Solidity library — install @latest |
@inco/lightning-js | latest (v1+) | JavaScript SDK (renamed from @inco/js) — install @latest |
| Solidity | 0.8.30 | Compiler version (0.8.29+ supported) |
| EVM | cancun | Target EVM version |
Provides CDSS development patterns for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert classification integrated into EMR workflows.
npx claudepluginhub inco-fhevm/skills --plugin inco