Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 63 additions & 5 deletions client-sdk/quick-start/react.mdx
Original file line number Diff line number Diff line change
@@ -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"
---

<Info>
`@cofhe/react` is currently in development. This page will be updated with a full quick start guide once the React library is available.
</Info>
`@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

<CodeGroup>

```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
```

</CodeGroup>

## 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 <CofheProvider config={config}>{children}</CofheProvider>;
}
```

## 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 <SignPermitButton />;

return <div>Balance: {balance?.toString() ?? '…'}</div>;
}
```

## 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.
120 changes: 120 additions & 0 deletions client-sdk/react/components-and-portal.mdx
Original file line number Diff line number Diff line change
@@ -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 (
<CofheEncryptInput
placeholder="Enter value to encrypt…"
options={FheTypesList}
showProgressBar
onEncryptComplete={(data) => 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 (
<CofheProvider config={config}>
<YourApp />
<CofheFloatingButtonWithProvider />
</CofheProvider>
);
}
```

### 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.
143 changes: 143 additions & 0 deletions client-sdk/react/getting-started.mdx
Original file line number Diff line number Diff line change
@@ -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.

<Note>
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.
</Note>

## Installation

<CodeGroup>

```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
```

</CodeGroup>

### Peer dependencies

| Package | Range |
| --- | --- |
| `react` | `^16.8.0 \|\| ^17 \|\| ^18 \|\| ^19` |
| `react-dom` | same range as `react` |
| `viem` | `^2.38.6` |

<Note>
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.
</Note>

## 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.

<CodeGroup>

```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 <CofheProvider config={config}>{children}</CofheProvider>;
}
```

```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 <CofheProvider cofheClient={client}>{children}</CofheProvider>;
}
```

</CodeGroup>

`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 (
<CofheProvider config={config}>
<YourApp />
<CofheFloatingButtonWithProvider />
</CofheProvider>
);
}
```

<Tip>
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.
</Tip>

## 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.
Loading