{"_id":"@0xbojack/fhevm-core","_rev":"2-1150572e080b4f9c0cecc2fe5cd5de96","name":"@0xbojack/fhevm-core","dist-tags":{"latest":"0.2.1"},"versions":{"0.2.0":{"name":"@0xbojack/fhevm-core","version":"0.2.0","keywords":["fhevm","fhe","encryption","privacy","zama","blockchain"],"author":{"name":"Zama"},"license":"BSD-3-Clause-Clear","_id":"@0xbojack/fhevm-core@0.2.0","maintainers":[{"name":"0xbojack","email":"coderbojack@gmail.com"}],"homepage":"https://github.com/zama-ai/fhevm-sdk#readme","bugs":{"url":"https://github.com/zama-ai/fhevm-sdk/issues"},"dist":{"shasum":"66535b7cab645137bcc031487ccbdf5ea1398f31","tarball":"https://registry.npmjs.org/@0xbojack/fhevm-core/-/fhevm-core-0.2.0.tgz","fileCount":9,"integrity":"sha512-Jli1ykak4kyTJ39mJxFpFL78afubThNxXTisQBHXWY8cfl4Z5/EyvsrXUxmrbCnTHEtG/l2ZvdkgzJ0iMcOK+w==","signatures":[{"sig":"MEUCIQCeDXItVjNbFOkeaSdcSuQLYwwHwW3Jtl6GL1HRX9UbQgIga4rRQyryfKgUvpnmGnyPVQxqUXDMSCdRMAiTIu6aNeY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":247011},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./types":{"types":"./dist/types.d.ts","import":"./dist/types.js","require":"./dist/types.cjs"},"./storage":{"types":"./dist/storage/index.d.ts","import":"./dist/storage/index.js","require":"./dist/storage/index.cjs"}},"gitHead":"ff17a53b95b33a83c2bd89c3b608290641d2be72","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","clean":"rm -rf dist","test:watch":"vitest","prepublishOnly":"pnpm build && pnpm test"},"_npmUser":{"name":"0xbojack","email":"coderbojack@gmail.com"},"repository":{"url":"git+https://github.com/zama-ai/fhevm-sdk.git","type":"git","directory":"packages/core"},"_npmVersion":"10.8.2","description":"Framework-agnostic FHEVM SDK core library","directories":{},"sideEffects":false,"_nodeVersion":"20.19.4","dependencies":{"ethers":"^6.13.7","@zama-fhe/relayer-sdk":"0.2.0"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.0","vitest":"^2.1.9","typescript":"^5.9.2","@types/node":"^22.7.5"},"peerDependencies":{"@fhevm/mock-utils":"^0.1.0"},"peerDependenciesMeta":{"@fhevm/mock-utils":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/fhevm-core_0.2.0_1761115097193_0.6834149440453685","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@0xbojack/fhevm-core","version":"0.2.1","description":"Framework-agnostic FHEVM SDK core library","type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./storage":{"types":"./dist/storage/index.d.ts","import":"./dist/storage/index.js","require":"./dist/storage/index.cjs"},"./types":{"types":"./dist/types.d.ts","import":"./dist/types.js","require":"./dist/types.cjs"}},"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","clean":"rm -rf dist","prepublishOnly":"pnpm build && pnpm test"},"engines":{"node":">=18.0.0"},"sideEffects":false,"keywords":["fhevm","fhe","encryption","privacy","zama","blockchain"],"author":{"name":"Zama"},"license":"BSD-3-Clause-Clear","repository":{"type":"git","url":"git+https://github.com/huaigu/fhevm-sdk.git","directory":"packages/core"},"homepage":"https://github.com/huaigu/fhevm-sdk/tree/main/packages/core#readme","bugs":{"url":"https://github.com/huaigu/fhevm-sdk/issues"},"dependencies":{"ethers":"^6.13.7","@zama-fhe/relayer-sdk":"0.2.0"},"peerDependencies":{"@fhevm/mock-utils":"^0.1.0"},"peerDependenciesMeta":{"@fhevm/mock-utils":{"optional":true}},"devDependencies":{"@types/node":"^22.7.5","tsup":"^8.5.0","typescript":"^5.9.2","vitest":"^2.1.9"},"_id":"@0xbojack/fhevm-core@0.2.1","gitHead":"c07f422db6ea84e5cdbb2866228f8181f2bfa6a3","_nodeVersion":"20.19.4","_npmVersion":"10.8.2","dist":{"integrity":"sha512-xLOShRbAp/cCWw7LdndNer/mN8CyMwOsoTBARc89bcqlRJbQRVEV34hN8m9+syxBUUQrGHJMy6D7ATICmSGSLQ==","shasum":"cc068133deafd2fbd4f3f3ce269a46798cedad79","tarball":"https://registry.npmjs.org/@0xbojack/fhevm-core/-/fhevm-core-0.2.1.tgz","fileCount":9,"unpackedSize":247032,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICYEk12goGJEY4DVBDVY2P0Ujct7lFmXifbFUIJg/zVqAiEAp0ZoNceq186qamj+i6qnciRcDvDWuruRbTSkvkwY1Ik="}]},"_npmUser":{"name":"0xbojack","email":"coderbojack@gmail.com"},"directories":{},"maintainers":[{"name":"0xbojack","email":"coderbojack@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/fhevm-core_0.2.1_1761116162913_0.696449373815438"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-22T06:38:17.102Z","modified":"2025-10-22T06:56:03.614Z","0.2.0":"2025-10-22T06:38:17.386Z","0.2.1":"2025-10-22T06:56:03.090Z"},"bugs":{"url":"https://github.com/huaigu/fhevm-sdk/issues"},"author":{"name":"Zama"},"license":"BSD-3-Clause-Clear","homepage":"https://github.com/huaigu/fhevm-sdk/tree/main/packages/core#readme","keywords":["fhevm","fhe","encryption","privacy","zama","blockchain"],"repository":{"type":"git","url":"git+https://github.com/huaigu/fhevm-sdk.git","directory":"packages/core"},"description":"Framework-agnostic FHEVM SDK core library","maintainers":[{"name":"0xbojack","email":"coderbojack@gmail.com"}],"readme":"# @fhevm/core\n\nFramework-agnostic FHEVM SDK core library for building privacy-preserving applications with Fully Homomorphic Encryption.\n\n## Features\n\n- 🔒 **Fully Homomorphic Encryption**: Compute on encrypted data without decryption\n- 🎯 **Framework Agnostic**: Works with any JavaScript framework or vanilla JS\n- 💾 **Flexible Storage**: Built-in support for Memory, localStorage, and IndexedDB\n- 🔐 **EIP-712 Signatures**: Secure 365-day decryption authorization caching\n- 🧪 **Mock Support**: Local development with Hardhat using `@fhevm/mock-utils`\n- 📦 **Tree-shakeable**: Optimized bundle size with ESM and CJS builds\n\n## Installation\n\n```bash\nnpm install @fhevm/core ethers\n# or\npnpm add @fhevm/core ethers\n# or\nyarn add @fhevm/core ethers\n```\n\nFor local development with Hardhat:\n```bash\nnpm install -D @fhevm/mock-utils\n```\n\n## Quick Start\n\n### Basic Usage\n\n```typescript\nimport { FhevmClient } from '@fhevm/core';\nimport { BrowserProvider } from 'ethers';\n\n// Create client\nconst client = new FhevmClient();\n\n// Initialize with provider\nconst provider = new BrowserProvider(window.ethereum);\nawait client.init({ provider });\n\n// Encrypt data\nconst encrypted = await client.encrypt({\n  value: 42,\n  type: 'euint32',\n  contractAddress: '0x...',\n  userAddress: '0x...',\n});\n\n// Decrypt data (requires signer)\nconst signer = await provider.getSigner();\nconst decrypted = await client.decrypt(\n  [{ handle: '0x...', contractAddress: '0x...' }],\n  signer\n);\n```\n\n### Custom Storage\n\n```typescript\nimport { FhevmClient, IndexedDBStorage } from '@fhevm/core';\n\nconst client = new FhevmClient({\n  storage: new IndexedDBStorage(), // Persistent browser storage\n});\n```\n\n### Local Development (Hardhat)\n\n```typescript\nimport { FhevmClient } from '@fhevm/core';\n\nconst client = new FhevmClient({\n  mockChains: {\n    31337: 'http://localhost:8545', // Hardhat local network\n  },\n});\n\nawait client.init({\n  provider: 'http://localhost:8545',\n  chainId: 31337,\n});\n```\n\n## API Reference\n\n### FhevmClient\n\n#### Constructor\n\n```typescript\nnew FhevmClient(config?: FhevmConfig)\n```\n\n**Config Options:**\n- `storage?: StorageAdapter` - Custom storage implementation (default: MemoryStorage)\n- `mockChains?: Record<number, string>` - Mock chain configurations for local development\n\n#### Methods\n\n##### `init(params: InitParams, signal?: AbortSignal): Promise<FhevmInstance>`\n\nInitialize the FHEVM instance.\n\n**Parameters:**\n- `params.provider: Eip1193Provider | string` - Ethereum provider or RPC URL\n- `params.chainId?: number` - Chain ID (auto-detected if not provided)\n- `signal?: AbortSignal` - Optional abort signal for cancellation\n\n**Returns:** Promise<FhevmInstance>\n\n##### `getStatus(): FhevmStatus`\n\nGet current initialization status.\n\n**Returns:** `'idle' | 'loading' | 'ready' | 'error'`\n\n##### `onStatusChange(listener: (status: FhevmStatus) => void): () => void`\n\nSubscribe to status changes.\n\n**Returns:** Unsubscribe function\n\n##### `getPublicKey(): string`\n\nGet the public key for encryption.\n\n**Returns:** Public key string\n\n##### `encrypt(params: EncryptParams): Promise<EncryptResult>`\n\nEncrypt data for on-chain computation.\n\n**Parameters:**\n- `value: number | bigint | boolean | string` - Value to encrypt\n- `type: EncryptedType` - Type of encrypted value\n- `contractAddress: 0x${string}` - Contract address\n- `userAddress: 0x${string}` - User address\n\n**Supported Types:**\n- `ebool` - Encrypted boolean\n- `euint8` - Encrypted 8-bit unsigned integer\n- `euint16` - Encrypted 16-bit unsigned integer\n- `euint32` - Encrypted 32-bit unsigned integer\n- `euint64` - Encrypted 64-bit unsigned integer\n- `euint128` - Encrypted 128-bit unsigned integer\n- `euint160` - Encrypted 160-bit unsigned integer\n- `euint256` - Encrypted 256-bit unsigned integer\n- `eaddress` - Encrypted address\n\n**Returns:** `{ handles: Uint8Array[], inputProof: Uint8Array }`\n\n##### `decrypt(requests: DecryptRequest[], signer: JsonRpcSigner): Promise<DecryptResult>`\n\nDecrypt encrypted data (requires user signature).\n\n**Parameters:**\n- `requests` - Array of decrypt requests\n- `signer` - ethers.JsonRpcSigner for EIP-712 signature\n\n**Returns:** Decrypted values as Record<string, string | bigint | boolean>\n\n## Storage Adapters\n\n### MemoryStorage (Default)\n\nIn-memory storage, data persists only for the lifetime of the instance.\n\n```typescript\nimport { MemoryStorage } from '@fhevm/core';\nconst storage = new MemoryStorage();\n```\n\n### LocalStorageStorage\n\nBrowser localStorage with prefix support.\n\n```typescript\nimport { LocalStorageStorage } from '@fhevm/core';\nconst storage = new LocalStorageStorage('my-app:'); // Optional prefix\n```\n\n### IndexedDBStorage\n\nBrowser IndexedDB for larger storage capacity.\n\n```typescript\nimport { IndexedDBStorage } from '@fhevm/core';\nconst storage = new IndexedDBStorage();\n```\n\n### Custom Storage\n\nImplement the `StorageAdapter` interface:\n\n```typescript\ninterface StorageAdapter {\n  getItem(key: string): Promise<string | null>;\n  setItem(key: string, value: string): Promise<void>;\n  removeItem(key: string): Promise<void>;\n  clear(): Promise<void>;\n}\n```\n\n## Error Handling\n\n```typescript\nimport { FhevmError, FhevmAbortError } from '@fhevm/core';\n\ntry {\n  await client.init({ provider });\n} catch (error) {\n  if (error instanceof FhevmAbortError) {\n    console.log('Operation was cancelled');\n  } else if (error instanceof FhevmError) {\n    console.error('FHEVM Error:', error.code, error.message);\n  }\n}\n```\n\n## TypeScript Support\n\nFull TypeScript support with comprehensive type definitions.\n\n```typescript\nimport type {\n  FhevmConfig,\n  FhevmStatus,\n  InitParams,\n  EncryptParams,\n  EncryptResult,\n  DecryptRequest,\n  DecryptResult,\n  StorageAdapter,\n} from '@fhevm/core';\n```\n\n## Advanced Usage\n\n### Abort Operations\n\n```typescript\nconst controller = new AbortController();\n\n// Start initialization\nconst initPromise = client.init({ provider }, controller.signal);\n\n// Cancel if needed\ncontroller.abort();\n\ntry {\n  await initPromise;\n} catch (error) {\n  if (error instanceof FhevmAbortError) {\n    console.log('Initialization cancelled');\n  }\n}\n```\n\n### Status Monitoring\n\n```typescript\nconst unsubscribe = client.onStatusChange((status) => {\n  console.log('Status:', status);\n  // idle -> loading -> ready\n});\n\nawait client.init({ provider });\nunsubscribe();\n```\n\n### Multiple Contract Decryption\n\n```typescript\nconst results = await client.decrypt(\n  [\n    { handle: '0x...', contractAddress: '0xContract1...' },\n    { handle: '0x...', contractAddress: '0xContract2...' },\n  ],\n  signer\n);\n```\n\n### Batch Encryption\n\n```typescript\n// Encrypt multiple values for the same contract\nconst client = new FhevmClient();\nawait client.init({ provider });\n\nconst contractAddress = '0x...';\nconst userAddress = '0x...';\n\n// Encrypt multiple values\nconst age = await client.encrypt({\n  value: 25,\n  type: 'euint8',\n  contractAddress,\n  userAddress,\n});\n\nconst balance = await client.encrypt({\n  value: 1000n,\n  type: 'euint64',\n  contractAddress,\n  userAddress,\n});\n\nconst isActive = await client.encrypt({\n  value: true,\n  type: 'ebool',\n  contractAddress,\n  userAddress,\n});\n\n// Use in contract call\nawait contract.setUserData(\n  age.handles[0],\n  balance.handles[0],\n  isActive.handles[0],\n  age.inputProof // All values share the same proof\n);\n```\n\n### Custom Error Handling\n\n```typescript\nimport { FhevmClient, FhevmError, FhevmAbortError } from '@fhevm/core';\n\ntry {\n  await client.encrypt({ value: 42, type: 'euint32', contractAddress, userAddress });\n} catch (error) {\n  if (error instanceof FhevmAbortError) {\n    console.log('Operation cancelled by user');\n  } else if (error instanceof FhevmError) {\n    switch (error.code) {\n      case 'NOT_INITIALIZED':\n        console.error('Client not initialized - call init() first');\n        break;\n      case 'INVALID_TYPE':\n        console.error('Invalid encrypted type provided');\n        break;\n      case 'BROWSER_REQUIRED':\n        console.error('Browser environment required for production chains');\n        break;\n      default:\n        console.error(`FHEVM Error (${error.code}):`, error.message);\n    }\n  } else {\n    console.error('Unexpected error:', error);\n  }\n}\n```\n\n### Production Deployment Example\n\n```typescript\nimport { FhevmClient, IndexedDBStorage } from '@fhevm/core';\nimport { BrowserProvider } from 'ethers';\n\n// Production configuration\nconst client = new FhevmClient({\n  storage: new IndexedDBStorage(), // Persistent storage\n  mockChains: {}, // Disable mock chains in production\n});\n\n// Initialize with MetaMask/WalletConnect\nconst provider = new BrowserProvider(window.ethereum);\nawait client.init({ provider });\n\n// Subscribe to status changes for UI feedback\nclient.onStatusChange((status) => {\n  switch (status) {\n    case 'loading':\n      showLoadingSpinner();\n      break;\n    case 'ready':\n      hideLoadingSpinner();\n      enableEncryptButton();\n      break;\n    case 'error':\n      hideLoadingSpinner();\n      showErrorMessage();\n      break;\n  }\n});\n```\n\n## Performance Best Practices\n\n### 1. Optimize Encrypted Type Selection\n\nChoose the smallest encrypted type that fits your data to minimize gas costs:\n\n```typescript\n// ❌ BAD: Using oversized type\nconst age = await client.encrypt({\n  value: 25, // 0-255 range\n  type: 'euint256', // Wastes gas\n  contractAddress,\n  userAddress,\n});\n\n// ✅ GOOD: Using appropriate type\nconst age = await client.encrypt({\n  value: 25,\n  type: 'euint8', // Perfect fit for 0-255 range\n  contractAddress,\n  userAddress,\n});\n```\n\n### 2. Storage Adapter Selection\n\n| Storage Type | Use Case | Persistence | Capacity | Performance |\n|--------------|----------|-------------|----------|-------------|\n| MemoryStorage | Testing, ephemeral sessions | Session only | Low (~5MB) | Fastest |\n| LocalStorageStorage | Simple apps, small data | Browser restart | ~10MB | Fast |\n| IndexedDBStorage | Production apps | Browser restart | ~50MB+ | Good |\n\n**Recommendation**: Use `IndexedDBStorage` for production to cache public keys and signatures persistently.\n\n### 3. Signature Reuse\n\nDecryption signatures are valid for **365 days** and automatically cached:\n\n```typescript\n// First decrypt - prompts user to sign\nconst result1 = await client.decrypt([{ handle: '0x...', contractAddress }], signer);\n\n// Subsequent decrypts within 365 days - no signature prompt!\nconst result2 = await client.decrypt([{ handle: '0x...', contractAddress }], signer);\nconst result3 = await client.decrypt([{ handle: '0x...', contractAddress }], signer);\n```\n\n**Impact**: Reduces user friction by 99% after initial signature.\n\n### 4. Public Key Caching\n\nPublic keys are automatically cached using `PublicKeyStorage`:\n\n- **First init**: Downloads public key from network (~1-2s)\n- **Subsequent inits**: Loads from storage (<50ms)\n\n**Recommendation**: Always use persistent storage (IndexedDB) to maximize cache hit rate across sessions.\n\n### 5. Abort Long-Running Operations\n\nUse `AbortController` to cancel initialization if user navigates away:\n\n```typescript\nconst controller = new AbortController();\n\n// Cancel on component unmount\nuseEffect(() => {\n  const initPromise = client.init({ provider }, controller.signal);\n  return () => controller.abort();\n}, []);\n```\n\n## Troubleshooting\n\n### MetaMask Nonce Mismatch After Hardhat Restart\n\n**Symptom**: Transactions fail with \"nonce too high\" or \"nonce too low\" after restarting local Hardhat node.\n\n**Solution**:\n1. Open MetaMask → Settings → Advanced → **Clear Activity Tab Data**\n2. Restart your browser (clears view function cache)\n3. Reconnect to `http://localhost:8545`\n4. Redeploy contracts with `pnpm contract:deploy`\n\n### Public Key Not Found Error\n\n**Symptom**: `FhevmError: Public key not found` during decryption.\n\n**Causes & Solutions**:\n- **Signature expired** (>365 days old): Re-initialize client\n  ```typescript\n  await client.init({ provider }); // Refreshes public key\n  ```\n- **Storage cleared**: Signature was deleted from browser storage\n  ```typescript\n  // User will be prompted to sign again\n  await client.decrypt([...], signer);\n  ```\n- **Wrong contract address**: Signature is per-contract\n  ```typescript\n  // Generate new signature for new contract\n  await client.decrypt(\n    [{ handle: '0x...', contractAddress: '0xNEW_CONTRACT' }],\n    signer\n  );\n  ```\n\n### Mock Utils Not Found (Local Development)\n\n**Symptom**: `Cannot find module '@fhevm/mock-utils'` when using Hardhat (chainId 31337).\n\n**Solution**: Install as dev dependency:\n```bash\nnpm install -D @fhevm/mock-utils\n# or\npnpm add -D @fhevm/mock-utils\n```\n\n### Browser Environment Required\n\n**Symptom**: `FhevmError: BROWSER_REQUIRED` when running on server.\n\n**Explanation**: Production chains (Sepolia, mainnet) require browser environment to load Relayer SDK.\n\n**Solutions**:\n- **Next.js**: Use client components (`'use client'`) for FHEVM operations\n- **Node.js backend**: Use mock chains for testing, or implement server-side decryption (advanced)\n- **SSR**: Defer FHEVM initialization to `useEffect` (client-side only)\n\n```typescript\n'use client'; // Next.js client component\n\nimport { useEffect } from 'react';\nimport { FhevmClient } from '@fhevm/core';\n\nexport function EncryptForm() {\n  useEffect(() => {\n    // Client-side only\n    const client = new FhevmClient();\n    client.init({ provider: window.ethereum });\n  }, []);\n}\n```\n\n### ChainId Mismatch\n\n**Symptom**: Client initializes but encryption fails.\n\n**Cause**: Provider and config chainId don't match.\n\n**Solution**: Let the SDK auto-detect chainId:\n```typescript\n// ❌ BAD: Manual chainId may mismatch\nawait client.init({ provider: window.ethereum, chainId: 11155111 });\n\n// ✅ GOOD: Auto-detect from provider\nawait client.init({ provider: window.ethereum });\n```\n\n### Slow Initialization\n\n**Symptom**: `init()` takes >5 seconds on subsequent loads.\n\n**Causes**:\n1. **No persistent storage**: Using `MemoryStorage` (default)\n   - **Solution**: Switch to `IndexedDBStorage`\n2. **Network latency**: Downloading public key every time\n   - **Solution**: Verify storage adapter is working\n3. **Relayer SDK loading**: CDN download on first load\n   - **Expected**: First load slower (~2-3s), subsequent loads fast\n\n```typescript\n// Enable persistent caching\nconst client = new FhevmClient({\n  storage: new IndexedDBStorage(),\n});\n\n// Verify caching works\nconsole.time('First init');\nawait client.init({ provider });\nconsole.timeEnd('First init'); // ~2000ms\n\nconsole.time('Second init');\nawait client.init({ provider });\nconsole.timeEnd('Second init'); // ~50ms (cached!)\n```\n\n## Migration Guide\n\n### From fhevmjs Direct Usage\n\n**Before** (fhevmjs):\n```typescript\nimport { createInstance } from 'fhevmjs';\n\nconst instance = await createInstance({\n  network: window.ethereum,\n  aclContractAddress: '0x...',\n  kmsVerifierContractAddress: '0x...',\n  inputVerifierContractAddress: '0x...',\n});\n\nconst input = instance.createEncryptedInput('0xContract', '0xUser');\ninput.add32(42);\nconst encrypted = await input.encrypt();\n```\n\n**After** (@fhevm/core):\n```typescript\nimport { FhevmClient } from '@fhevm/core';\n\nconst client = new FhevmClient();\nawait client.init({ provider: window.ethereum });\n// ACL addresses auto-detected from Relayer SDK config\n\nconst encrypted = await client.encrypt({\n  value: 42,\n  type: 'euint32',\n  contractAddress: '0xContract',\n  userAddress: '0xUser',\n});\n```\n\n**Key Changes**:\n- ✅ Wrapped in class API with lifecycle management (`init()`, `getStatus()`)\n- ✅ Automatic ACL address detection from network config\n- ✅ Built-in storage adapters for public key/signature caching\n- ✅ Type-safe encrypt/decrypt with `EncryptedType` enum\n- ✅ Error handling with custom error classes (`FhevmError`, `FhevmAbortError`)\n\n## Examples\n\nSee full working examples in our monorepo:\n\n- **[Next.js App](../../examples/nextjs-app/)** - Complete dApp with RainbowKit + wagmi integration\n- **[Vue App](../../examples/vue-app/)** - Vue 3 Composition API example\n- **[Smart Contracts](../../packages/contracts/)** - Solidity contracts with encryption\n\n**Live Demos**:\n- [Next.js Demo](https://fhevm-sdk-nextjs.vercel.app) - Encrypted counter example\n- [Vue Demo](https://fhevm-sdk-vue.netlify.app) - Same example in Vue 3\n\n## License\n\nBSD-3-Clause-Clear\n\n## Links\n\n- [FHEVM Documentation](https://docs.zama.ai/fhevm)\n- [GitHub Repository](https://github.com/zama-ai/fhevm-sdk)\n- [Zama](https://zama.ai)\n","readmeFilename":"README.md"}