> ## Documentation Index
> Fetch the complete documentation index at: https://docs.daimo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Web

> Pre-built deposit UI for web apps

For web apps, render the hosted Daimo flow with **`DaimoFrame`**: a drop-in
React component that handles the entire deposit, withdraw, or transfer flow,
from chain selection and wallet connection through transaction signing and
status updates. It works without wallet libraries or providers.

`DaimoFrame` supports two layouts:

* **`modal`** (default): a dimmed, full-screen overlay with a rounded sheet
  sized to the content. Daimo owns the presentation, including iOS safe areas.
* **`embed`**: an inline iframe rendered exactly where you place the
  component. You own the presentation: wrap it in your own modal, drawer, or
  page layout.

## Installation

```bash theme={null}
npm install @daimo/sdk
```

Peer dependencies: `react >= 18`.

## Modal layout

1. Create a session on your server (see [Quickstart](/quickstart))
2. Pass `sessionId` and `clientSecret` to `<DaimoFrame layout="modal" />`

```tsx theme={null}
import { DaimoFrame } from "@daimo/sdk/web";

function DepositPage({ sessionId, clientSecret }) {
  const [open, setOpen] = useState(true);
  if (!open) return null;

  return (
    <DaimoFrame
      layout="modal"
      sessionId={sessionId}
      clientSecret={clientSecret}
      onClose={() => setOpen(false)}
    />
  );
}
```

The `sessionId` and `clientSecret` come from the session object returned by
`POST /v1/sessions`.

The modal layout renders the flow in an iframe inside a fixed, dimmed overlay
and sizes itself to the content. It handles iOS safe areas for you, with no
extra CSS.

## Embed layout

Use `layout="embed"` to render the deposit flow inside your own UI, such as a
modal or drawer that matches the rest of your app.

```tsx theme={null}
import { DaimoFrame } from "@daimo/sdk/web";

function DepositDialog({ sessionId, clientSecret, onDismiss }) {
  return (
    <YourModal onDismiss={onDismiss}>
      <DaimoFrame
        layout="embed"
        sessionId={sessionId}
        clientSecret={clientSecret}
      />
    </YourModal>
  );
}
```

Sizing and dismissal:

* The embed fills its container's width; its height follows the content and
  animates as the user moves through the flow. Content centers itself at a
  maximum width of 512px, so keep the container at or below that width.
* The embed never scrolls internally. If your container has a fixed height,
  give it `overflow-y: auto`.
* You own dismissal: render your own close affordance. `onClose` still fires
  if the flow closes itself (for example, after a completed deposit).

## Props

| Prop           | Type                 | Default             | Description                                                     |
| -------------- | -------------------- | ------------------- | --------------------------------------------------------------- |
| `sessionId`    | `string`             | -                   | Unique session ID. Sessions are created server-side. (required) |
| `clientSecret` | `string`             | -                   | Unique client secret, returned at session creation. (required)  |
| `layout`       | `"modal" \| "embed"` | `"modal"`           | Presentation layout: Daimo-owned overlay, or inline in your UI. |
| `onClose`      | `() => void`         | -                   | Called when the user dismisses the flow.                        |
| `baseUrl`      | `string`             | `https://daimo.com` | Hosted flow origin. Override only for staging / self-hosted.    |

## Tracking payment status

`DaimoFrame` surfaces dismissal via `onClose`. To act on payment progress, poll
[`GET /v1/sessions/{id}`](/api-reference/retrieve-session) after the session
completes. See [Step 3 of the Quickstart](/quickstart#step-3-handle-completion).

## Inline React components

If you need the flow rendered as native React components (not an iframe), for
example to skip the payment-method picker, use the lower-level **`DaimoModal`**
component. It renders the same flow directly in your page and exposes richer
hooks.

```tsx theme={null}
import { DaimoSDKProvider, DaimoModal } from "@daimo/sdk/web";
import "@daimo/sdk/web/theme.css";

function App({ sessionId, clientSecret }) {
  return (
    <DaimoSDKProvider>
      <DaimoModal
        sessionId={sessionId}
        clientSecret={clientSecret}
        embedded
        onPaymentStarted={() => console.log("deposit initiated")}
        onPaymentCompleted={() => console.log("deposit succeeded")}
      />
    </DaimoSDKProvider>
  );
}
```

`DaimoModal` must be wrapped in `DaimoSDKProvider` and requires the theme
stylesheet. Selected props:

For recipient-first stablecoin sending, use the sibling
[`DaimoWithdrawal` component](/guides/withdrawals). It collects the recipient
and destination route before creating an open-amount session.

| Prop                       | Type      | Default | Description                                                    |
| -------------------------- | --------- | ------- | -------------------------------------------------------------- |
| `sessionId`                | `string`  | -       | Unique session ID. (required)                                  |
| `clientSecret`             | `string`  | -       | Unique client secret. (required)                               |
| `embedded`                 | `boolean` | `false` | Render inline instead of as a floating modal.                  |
| `defaultOpen`              | `boolean` | `true`  | Whether the modal starts open.                                 |
| `connectToInjectedWallets` | `boolean` | `false` | Skip the payment method picker; auto-connect injected wallets. |
| `connectToAddress`         | `Address` | -       | Skip the picker; use an already-connected EVM wallet.          |
| `returnUrl`                | `string`  | -       | URL to navigate to after successful payment.                   |

Event handlers: `onPaymentStarted`, `onPaymentCompleted`, `onOpen`, `onClose`.

## Customization

Set your org theme in the Daimo dashboard to match the deposit flow to your
brand. The SDK loads it automatically from the session.

See [Customization](/guides/customization) for the dashboard flow and token
list.
