From a0e41fe166b7e779e69d5ff3fc26c348823a2ffc Mon Sep 17 00:00:00 2001 From: Roee Zolantz Date: Wed, 13 May 2026 14:44:35 +0300 Subject: [PATCH] add React docs section (@cofhe/react) and replace quick-start stub @cofhe/react 0.5.2 ships providers, hooks, an SSR-safe SDK boundary, a styled UI kit, and a token portal. The docs had only a stub quick-start page saying the library was 'currently in development'. - New nav group 'React' under the Client SDK tab with three pages: - getting-started: install, CofheProvider, hooks-only vs styled UI entrypoints, react.* config (projectName, logger, position, theme), SSR notes. - hooks: client/connection (useCofheClient, useCofheConnection, useCofheConnect, useCofheAutoConnect), coprocessor status (useCofheEnabled), permits (useCofheActivePermit and the typed ValidationResult.error union), encryption (useCofheEncrypt, useEncryptInput), reads (useCofheReadContract, useCofheReadContractAndDecrypt) with the renamed disabledDueToMissingValidPermit flag called out, writes (useCofheWriteContract), and the full CoFHE token-helper surface. - components-and-portal: CofheEncryptInput props, CofheFloatingButton portal, wallet-disconnected projectName behavior, custom-token import flow. - Replace the quick-start/react.mdx stub with a real walkthrough that links into the new section. - docs.json: add the 'React' group between Foundry Plugin and Examples. Co-authored-by: multica-agent --- client-sdk/quick-start/react.mdx | 68 +++++- client-sdk/react/components-and-portal.mdx | 120 +++++++++++ client-sdk/react/getting-started.mdx | 143 +++++++++++++ client-sdk/react/hooks.mdx | 229 +++++++++++++++++++++ docs.json | 8 + 5 files changed, 563 insertions(+), 5 deletions(-) create mode 100644 client-sdk/react/components-and-portal.mdx create mode 100644 client-sdk/react/getting-started.mdx create mode 100644 client-sdk/react/hooks.mdx diff --git a/client-sdk/quick-start/react.mdx b/client-sdk/quick-start/react.mdx index e8b52e9..27427db 100644 --- a/client-sdk/quick-start/react.mdx +++ b/client-sdk/quick-start/react.mdx @@ -1,10 +1,68 @@ --- title: "Quick Start: React" -description: "Get started with @cofhe/sdk in a React application" +description: "Wrap your React app with CofheProvider and use the @cofhe/react hooks to encrypt, decrypt, and read FHE state" --- - -`@cofhe/react` is currently in development. This page will be updated with a full quick start guide once the React library is available. - +`@cofhe/react` is the React layer on top of [`@cofhe/sdk`](/client-sdk/introduction/overview). It ships a context provider, hooks for connection / permits / encryption / decryption / contract reads / writes, and an optional styled UI kit including the `CofheEncryptInput` field and the `CofheFloatingButton` portal. -In the meantime, you can use `@cofhe/sdk/web` directly in your React app. See the [Client Setup](/client-sdk/guides/client-setup) guide for how to configure and connect the SDK with viem or wagmi. +## Install + + + +```bash npm +npm install @cofhe/react @cofhe/sdk @fhenixprotocol/cofhe-contracts viem +``` + +```bash pnpm +pnpm add @cofhe/react @cofhe/sdk @fhenixprotocol/cofhe-contracts viem +``` + +```bash yarn +yarn add @cofhe/react @cofhe/sdk @fhenixprotocol/cofhe-contracts viem +``` + + + +## Wrap your app + +```tsx providers.tsx +'use client'; + +import { CofheProvider } from '@cofhe/react'; +import { createCofheConfig } from '@cofhe/sdk/web'; +import { chains } from '@cofhe/sdk/chains'; + +const config = createCofheConfig({ + environment: 'react', + supportedChains: [chains.sepolia], + react: { projectName: 'My dApp' }, +}); + +export function Providers({ children }: { children: React.ReactNode }) { + return {children}; +} +``` + +## Encrypt and decrypt + +```tsx ConfidentialBalance.tsx +'use client'; + +import { useCofheTokenDecryptedBalance, useCofheEncrypt } from '@cofhe/react'; +import { Encryptable } from '@cofhe/sdk'; + +export function ConfidentialBalance({ tokenAddress }: { tokenAddress: `0x${string}` }) { + const { balance, disabledDueToMissingValidPermit } = useCofheTokenDecryptedBalance(tokenAddress); + const encrypt = useCofheEncrypt(); + + if (disabledDueToMissingValidPermit) return ; + + return
Balance: {balance?.toString() ?? '…'}
; +} +``` + +## Where to next + +- [Getting Started](/client-sdk/react/getting-started) — install, provider, SSR notes, `react.*` config options. +- [Hooks](/client-sdk/react/hooks) — full hook surface (connection, permits, encryption, decryption, reads / writes, token helpers). +- [Components & Portal](/client-sdk/react/components-and-portal) — `CofheEncryptInput`, `CofheFloatingButton`, custom-token import. diff --git a/client-sdk/react/components-and-portal.mdx b/client-sdk/react/components-and-portal.mdx new file mode 100644 index 0000000..9aaf832 --- /dev/null +++ b/client-sdk/react/components-and-portal.mdx @@ -0,0 +1,120 @@ +--- +title: Components & Portal +description: "Drop-in encrypted-input field, the CoFHE floating button portal, and the custom-token import flow" +--- + +The components on this page live behind the `@cofhe/react/ui` entrypoint. Importing from this entry automatically loads the package styles — the headless root `@cofhe/react` import does not. See [Getting Started → Hooks-only vs styled UI](/client-sdk/react/getting-started#hooks-only-vs-styled-ui) for the full picture. + +## `CofheEncryptInput` + +Drop-in input field with type selector, real-time validation against the chosen FHE type, encryption progress reporting, and one-click copy of the encrypted result. + +```tsx +import { CofheEncryptInput } from '@cofhe/react/ui'; +import { FheTypesList } from '@cofhe/react'; + +export function EncryptDemo() { + return ( + console.log('Encrypted:', data)} + onEncryptError={(err) => console.error('Encryption failed:', err)} + /> + ); +} +``` + +### Props + +| Prop | Type | Default | Description | +| --- | --- | --- | --- | +| `placeholder` | `string` | `''` | Input placeholder text. | +| `initialValue` | `string` | `''` | Initial input string. | +| `options` | `FheTypeOption[]` | none | Type-selector dropdown options. Pass `FheTypesList` from `@cofhe/react` for the full set, or a subset to restrict choices. | +| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Component size. | +| `hasError` | `boolean` | `false` | Force the error state (e.g. driven by external validation). | +| `errorMessage` | `string` | `''` | Error string rendered below the input. | +| `disabled` | `boolean` | `false` | Disable input + encrypt actions. | +| `showProgressBar` | `boolean` | `false` | Render the encryption progress bar inline. | +| `debounceMs` | `number` | `300` | Debounce on `onTextChange`. | +| `onTextChange` | `(value: string) => void` | — | Fires on every input change (post-debounce). | +| `onTypeChange` | `(value: string) => void` | — | Fires when the type selector changes. | +| `onEncryptStart` | `(data) => void` | — | Fires when encryption begins. | +| `onEncryptProgress` | `(data) => void` | — | Per-step progress callback (`fetchKeys` → `pack` → `prove` → `verify` → `done`). | +| `onEncryptComplete` | `(data) => void` | — | Fires once the encrypted result is available. | +| `onEncryptError` | `(error: string) => void` | — | Fires on encryption failure. | +| `className` | `string` | — | Extra class on the root element. | +| `testId` | `string` | — | `data-testid` for the root element. | + +Internally `CofheEncryptInput` is driven by [`useEncryptInput`](/client-sdk/react/hooks#useencryptinput-ui-helper) — if you want the same logic without the bundled visuals, drop down to that hook. + +## `CofheFloatingButton` portal + +The portal is the user-facing UI for managing permits, browsing CoFHE tokens, importing custom tokens, shielding / unshielding, and watching pending decryptions. It mounts as a floating button anywhere in your app: + +```tsx +import { CofheProvider } from '@cofhe/react'; +import { CofheFloatingButtonWithProvider } from '@cofhe/react/ui'; + +export function App() { + return ( + + + + + ); +} +``` + +### Wallet-disconnected state + +Since `@cofhe/react@0.5.0`, when no wallet is connected the portal hides the wallet header and primary navigation and shows a "please connect" message instead. To make that message say *your* app name, set `react.projectName` on the config: + +```ts +createCofheConfig({ + environment: 'react', + supportedChains: [chains.sepolia], + react: { projectName: 'My dApp' }, +}); +``` + +See [Getting Started → `react.*` config options](/client-sdk/react/getting-started#react-config-options) for the full table. + +### Position and theme + +Set the initial position and theme through the config: + +```ts +createCofheConfig({ + environment: 'react', + supportedChains: [chains.sepolia], + react: { + position: 'bottom-right', + initialTheme: 'dark', + }, +}); +``` + +Both can also be flipped at runtime via context-bound setters that `CofheProvider` exposes on its inner store (used by the portal's own settings UI). + +## Custom-token import + +Added in `@cofhe/react@0.5.0`. Lets users import a CoFHE-aware token by its contract address straight from the portal's token list or portfolio flow: + +- The portal resolves the token's metadata, on-chain CoFHE compatibility, and (when relevant) its wrapped-token pair before the user confirms the import. +- Imported tokens are persisted per chain in `localStorage` and merged into `useCofheTokens()` results, so other hooks (`useCofheTokenDecryptedBalance`, `useCofheTokenShield`, etc.) treat them as first-class tokens immediately. +- Hooks like `useCofheReadContract`, `useCofheTokenDecryptedBalance`, and `useCofheReadContractAndDecrypt` automatically gate their reads on the imported token's permit / ACL state — `disabledDueToMissingValidPermit` reflects custom-token state the same way it does for known tokens. + +No extra setup is needed beyond mounting `CofheFloatingButton` — the import UI is already wired in. + +## Bundling notes + +- `@cofhe/react/ui` ships its own CSS via the bundle; you don't need to import a separate stylesheet. +- Internal icons are bundled — `@mui/icons-material` and `@mui/material` are **no longer** required peers as of `0.5.0`. If you previously installed them just for `@cofhe/react`, you can remove them. + +## Related + +- [Getting Started](/client-sdk/react/getting-started) — install, provider, SSR notes. +- [Hooks](/client-sdk/react/hooks) — read / write / decrypt / token hooks that back these components. diff --git a/client-sdk/react/getting-started.mdx b/client-sdk/react/getting-started.mdx new file mode 100644 index 0000000..dd85545 --- /dev/null +++ b/client-sdk/react/getting-started.mdx @@ -0,0 +1,143 @@ +--- +title: Getting Started +description: "Set up @cofhe/react in a Next.js, Vite, or any React app" +--- + +`@cofhe/react` is the React layer on top of [`@cofhe/sdk`](/client-sdk/introduction/overview). It ships a context provider, a set of hooks for reading/writing encrypted state, and an optional styled UI kit (`@cofhe/react/ui`) including the `CofheEncryptInput` input and the `CofheFloatingButton` portal. + + +The hooks ship from the root `@cofhe/react` import and are **headless** — no styles, no peer deps on `@mui/material`. The styled UI components live behind a separate `@cofhe/react/ui` entry that loads the package CSS for you. + + +## Installation + + + +```bash npm +npm install @cofhe/react @cofhe/sdk @fhenixprotocol/cofhe-contracts +``` + +```bash pnpm +pnpm add @cofhe/react @cofhe/sdk @fhenixprotocol/cofhe-contracts +``` + +```bash yarn +yarn add @cofhe/react @cofhe/sdk @fhenixprotocol/cofhe-contracts +``` + + + +### Peer dependencies + +| Package | Range | +| --- | --- | +| `react` | `^16.8.0 \|\| ^17 \|\| ^18 \|\| ^19` | +| `react-dom` | same range as `react` | +| `viem` | `^2.38.6` | + + +As of `0.5.0`, `@cofhe/react` **no longer requires** `@mui/material` / `@mui/icons-material` as peers — the internal icons are bundled inside the package. + + +## Wrap your app with `CofheProvider` + +There are two equivalent ways to set up the provider — pass a config and let the provider create the SDK client, or pass an existing client you created yourself. + + + +```tsx Config-only (most apps) +import { CofheProvider } from '@cofhe/react'; +import { createCofheConfig } from '@cofhe/sdk/web'; +import { chains } from '@cofhe/sdk/chains'; + +const config = createCofheConfig({ + environment: 'react', + supportedChains: [chains.sepolia], + react: { + projectName: 'My dApp', + // logger: (level, ...args) => console.log(level, ...args), + }, +}); + +export function Providers({ children }: { children: React.ReactNode }) { + return {children}; +} +``` + +```tsx Pass an existing client +import { CofheProvider } from '@cofhe/react'; +import { createCofheConfig, createCofheClient } from '@cofhe/sdk/web'; +import { chains } from '@cofhe/sdk/chains'; + +const config = createCofheConfig({ + environment: 'react', + supportedChains: [chains.sepolia], +}); +const client = createCofheClient(config); + +export function Providers({ children }: { children: React.ReactNode }) { + return {children}; +} +``` + + + +`CofheProvider` props: + +| Prop | Type | Required | Description | +| --- | --- | --- | --- | +| `config` | `CofheConfig` | one of `config` / `cofheClient` | Provider creates and owns the SDK client. | +| `cofheClient` | `CofheClient` | one of `config` / `cofheClient` | You own the client. The provider asserts `config.environment === 'react'`. | +| `children` | `ReactNode` | yes | Your app tree. | + +### `react.*` config options + +`createCofheConfig({ react: { … } })` accepts a few React-specific knobs: + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `projectName` | `string` | `undefined` | Shown in the wallet-disconnected portal state so users see *your* app name instead of a generic message. | +| `logger` | `(level, ...args) => void` | `undefined` | Internal logger for `@cofhe/react`. Pipe to your own observability stack. | +| `position` | `FloatingButtonPosition` | `'bottom-right'` | Default position of the `CofheFloatingButton`. | +| `initialTheme` | `'light' \| 'dark'` | follows system | Initial theme for the styled UI. | + +The `projectName` and `logger` options were added in [`@cofhe/react@0.5.0`](https://github.com/FhenixProtocol/cofhesdk/blob/master/packages/react/CHANGELOG.md#050). + +## Hooks-only vs styled UI + +The root `@cofhe/react` entrypoint is **headless** — it ships only the provider and hooks, with **no package CSS** loaded: + +```tsx +import { CofheProvider, useCofheClient } from '@cofhe/react'; +``` + +The styled UI components live behind `@cofhe/react/ui`. Importing from this entry automatically loads the package styles: + +```tsx +import { CofheProvider } from '@cofhe/react'; +import { CofheFloatingButtonWithProvider, CofheEncryptInput } from '@cofhe/react/ui'; + +export function App() { + return ( + + + + + ); +} +``` + + +If you're styling everything from scratch (Tailwind, CSS-in-JS, design system), stick with the hooks-only entrypoint and skip `@cofhe/react/ui` entirely — you'll save bundle size and own the visuals end-to-end. + + +## SSR support + +Since [`@cofhe/sdk@0.5.1`](https://github.com/FhenixProtocol/cofhesdk/blob/master/packages/sdk/CHANGELOG.md#051), `@cofhe/sdk/web` no longer crashes Next.js / Remix / Astro server builds with `self is not defined`. The TFHE WASM module is lazy-loaded on the first `encryptInputs(...)` call instead of at import time, so importing the SDK from a Server Component (or any code that runs at build time) is safe. + +The provider itself is a Client Component — keep it under a `"use client"` boundary as usual. + +## Next steps + +- [Hooks](/client-sdk/react/hooks) — `useCofheClient`, `useCofheConnection`, `useCofheEnabled`, `useCofheActivePermit`, read / write / decrypt hooks. +- [Components & Portal](/client-sdk/react/components-and-portal) — `CofheEncryptInput`, the `CofheFloatingButton` portal, and the custom-token import flow. diff --git a/client-sdk/react/hooks.mdx b/client-sdk/react/hooks.mdx new file mode 100644 index 0000000..a2f177a --- /dev/null +++ b/client-sdk/react/hooks.mdx @@ -0,0 +1,229 @@ +--- +title: Hooks +description: "React hooks for connection state, permits, encryption, decryption, and contract reads/writes" +--- + +Every hook below is exported from the root `@cofhe/react` entrypoint and works inside any tree wrapped in [`CofheProvider`](/client-sdk/react/getting-started). The hooks compose on top of the SDK client — when you need direct client access, use [`useCofheClient`](#usecofheclient). + +## Client and connection + +### `useCofheClient` + +Returns the SDK `CofheClient` owned by the provider. Use it when you need a one-off, imperative SDK call from inside a component (most apps don't — see the higher-level hooks below). + +```tsx +import { useCofheClient } from '@cofhe/react'; + +const client = useCofheClient(); +``` + +### `useCofheConnection` + +Reactive snapshot of the connection state. Re-renders when the user connects/disconnects a wallet or switches chains. + +```tsx +import { useCofheConnection } from '@cofhe/react'; + +const { connected, account, chainId, publicClient, walletClient } = useCofheConnection(); +``` + +Companion helpers shadow the most common fields so you can destructure narrowly: + +- `useCofheAccount()` → `address | undefined` +- `useCofheChainId()` → `number | undefined` +- `useCofhePublicClient()` → `PublicClient | undefined` +- `useCofheWalletClient()` → `WalletClient | undefined` + +### `useCofheConnect` / `useCofheAutoConnect` + +Imperative hooks for driving the connection lifecycle from app UI (e.g. a custom "Connect" button or a wallet-restore-on-mount effect). + +```tsx +import { useCofheConnect, useCofheAutoConnect } from '@cofhe/react'; + +const { connect, disconnect } = useCofheConnect(); +useCofheAutoConnect(); // restore last connection on mount +``` + +## Coprocessor status + +### `useCofheEnabled` + +Added in `@cofhe/react@0.5.0`. Reads `TaskManager.isEnabled()` from the connected chain and re-evaluates as block state changes. Useful for showing a "CoFHE temporarily unavailable" banner without firing a doomed transaction. + +```tsx +import { useCofheEnabled } from '@cofhe/react'; + +const { enabled, isLoading, error } = useCofheEnabled(); + +if (!isLoading && enabled === false) { + return CoFHE is paused — try again shortly.; +} +``` + +The hook is gated by the TaskManager's `onlyIfEnabled` modifier — see [TaskManager → Enable / Disable Switch](/deep-dive/cofhe-components/task-manager#enable--disable-switch). + +## Permits + +### `useCofheActivePermit` + +Returns the active permit for the current `chainId + account`, plus a typed validity flag (`isValid`) that already accounts for schema, signature, and expiry. + +```tsx +import { useCofheActivePermit } from '@cofhe/react'; + +const { permit, isValid, error } = useCofheActivePermit(); +``` + +`error` is the same typed union as [`ValidationResult.error`](/client-sdk/guides/permits#validating-permits): `'invalid-schema' | 'expired' | 'not-signed' | null`. + +### `useCofheAllPermits` / `useCofheSelectPermit` / `useCofheRemovePermit` + +Bulk management of the permit store. + +```tsx +const allPermits = useCofheAllPermits(); +const select = useCofheSelectPermit(); +const remove = useCofheRemovePermit(); +``` + +### Mutations: create / navigate + +For permit creation flows (e.g. a "Sign permit" button on a settings page), there are higher-level mutations under `@cofhe/react/permits` — `useCofheCreatePermitMutation`, `useCofheNavigateToCreatePermit`, `usePermitForm`, `usePermitsList`. These wrap the underlying SDK calls so you can drop them straight into a UI without manually managing loading/error state. + +## Encryption + +### `useCofheEncrypt` + +Encrypt one or more values from inside a component. Returns the mutation surface so you can drive a button or a form without juggling promises manually. + +```tsx +import { useCofheEncrypt } from '@cofhe/react'; +import { Encryptable } from '@cofhe/sdk'; + +const encrypt = useCofheEncrypt(); + +const onSubmit = async () => { + const [encryptedAmount] = await encrypt.mutateAsync([Encryptable.uint64(amount)]); + // pass encryptedAmount to your contract call +}; +``` + +### `useEncryptInput` (UI helper) + +Powers the styled `CofheEncryptInput` component (see [Components & Portal](/client-sdk/react/components-and-portal)). Use it directly to build a custom encrypted-input UI with progress reporting: + +```tsx +import { useEncryptInput } from '@cofhe/react'; + +const { + onEncryptInput, // (type, value) => Promise + isEncryptingInput, // boolean + encryptionStep, // 'fetchKeys' | 'pack' | 'prove' | 'verify' | 'done' + encryptionProgress, // 0..100 + encryptionProgressLabel, // human-readable label + inputEncryptionDisabled, +} = useEncryptInput(); +``` + +## Reading encrypted state + +### `useCofheReadContract` + +Mirrors wagmi's `useReadContract` for an FHE-aware read. Returns the encrypted ciphertext handle from the contract along with a `disabledDueToMissingValidPermit` flag so your UI can render a "sign a permit" prompt rather than firing a request that would fail anyway. + +```tsx +import { useCofheReadContract } from '@cofhe/react'; + +const { + data, + disabledDueToMissingValidPermit, + isLoading, +} = useCofheReadContract({ + address: token.address, + abi: token.abi, + functionName: 'encryptedBalanceOf', + args: [account], +}); +``` + + +**Renamed in `@cofhe/react@0.5.0`.** This flag used to be `disabledDueToMissingPermit`. The new name (`...ValidPermit`) reflects that it goes to `true` when the active permit is missing **or** invalid (expired / unsigned / malformed schema). Update any consumer code that destructured the old name. + + +### `useCofheReadContracts` + +Multi-call variant — same shape, takes an array of contracts. + +### `useCofheReadContractAndDecrypt` + +Reads an encrypted handle from a contract **and** decrypts it via the SDK in one hook. Useful for "display a confidential balance" UIs: + +```tsx +import { useCofheReadContractAndDecrypt } from '@cofhe/react'; +import { FheTypes } from '@cofhe/sdk'; + +const { data, disabledDueToMissingValidPermit, isLoading } = useCofheReadContractAndDecrypt({ + address: token.address, + abi: token.abi, + functionName: 'encryptedBalanceOf', + args: [account], + fheType: FheTypes.Uint64, +}); +``` + +### `useCofheTokenDecryptedBalance` + +Convenience wrapper around the read-and-decrypt flow specifically for CoFHE tokens. Re-renders when the active permit becomes valid. + +```tsx +const { balance, disabledDueToMissingValidPermit } = useCofheTokenDecryptedBalance(tokenAddress); +``` + +## Writing encrypted state + +### `useCofheWriteContract` / `useCofheSimulateWriteContract` + +FHE-aware analogues of wagmi's `useWriteContract` / `useSimulateContract`. They encrypt any `Encryptable.*` values in the `args` array before submitting: + +```tsx +const { writeContractAsync } = useCofheWriteContract(); + +await writeContractAsync({ + address: token.address, + abi: token.abi, + functionName: 'transfer', + args: [recipient, Encryptable.uint64(amount)], +}); +``` + +The simulate variant returns the same data shape wagmi does, plus encryption awaits. + +## CoFHE token helpers + +A set of higher-level hooks for the official CoFHE token flow (shield / unshield / transfer / claim): + +| Hook | Purpose | +| --- | --- | +| `useCofheTokens` | List of CoFHE-aware tokens for the current chain. Includes **custom tokens** the user imported (added in `@cofhe/react@0.5.0`). | +| `useCofheTokenLists` | Underlying token-list resolver. | +| `useCofheTokenPublicBalance` | Public ERC-20 balance for a token. | +| `useCofheTokenTransfer` | `transfer` mutation. | +| `useCofheTokenApprove` | `approve` mutation. | +| `useCofheTokenShield` | Shield a public balance into the encrypted side. | +| `useCofheTokenUnshield` | Request unshield (returns an `UnshieldClaim` handle). | +| `useCofheTokenClaimUnshielded` | Finalize an unshield claim once the decryption result lands on-chain. | +| `useCofheTokenClaimable` / `useCofheTokensClaimable` | Discover claimable unshield positions for one or many tokens. | +| `useCofheTokenDecryptedBalance` | See [Reading encrypted state](#reading-encrypted-state) above. | +| `useCofheTokensWithExistingEncryptedBalances` | Filter the token list down to those the connected account already holds. | +| `useCofhePinnedToken` / `useCofhePinnedTokenAddress` | Persisted "primary token" selection. | + +Each shield/unshield/claim hook also exposes a `getCofhe…CallArgs(...)` helper for cases where you want to compose the transaction call manually instead of using the mutation. + +## Wagmi parity + +Hooks that mirror a wagmi API keep the same prop shape on purpose — `address`, `abi`, `functionName`, `args` flow through identically. The CoFHE-specific surface (the `disabledDueToMissingValidPermit` flag, the `fheType` arg on `useCofheReadContractAndDecrypt`, the auto-encryption of `Encryptable.*` values) is additive. + +## Next steps + +- [Components & Portal](/client-sdk/react/components-and-portal) — `CofheEncryptInput`, `CofheFloatingButton`, the custom-token import flow. diff --git a/docs.json b/docs.json index 5c8b34d..1121671 100644 --- a/docs.json +++ b/docs.json @@ -112,6 +112,14 @@ "client-sdk/foundry-plugin/testing" ] }, + { + "group": "React", + "pages": [ + "client-sdk/react/getting-started", + "client-sdk/react/hooks", + "client-sdk/react/components-and-portal" + ] + }, { "group": "Examples", "pages": [