# DepositWidget

The drop-in deposit UI component. Handles the full flow: burner key generation, EIP-7702 authorization, session creation, QR code display, deposit detection via SSE, and status updates. Must be rendered inside a `PeltierProvider`.

> **Per-flow entry points**
>
> `DepositWidget` is the configurable core. For clarity, the SDK also exports thin, intention-revealing wrappers — one per flow (all rendered inside `PeltierProvider`):
>
> - `<PeltierCheckout sessionId clientSecret publishableKey destinationAddress destinationChainId />` — **Flow A** (merchant checkout): payer UI bound to a server-created payment session; the burner is attached via `POST /sessions/:id/register` under the pk_ + client_secret guard.
> - `<PeltierRequest destinationAddress destinationChainId />` — **Flow B** (request / receive): the recipient signs the open-token, destination-pinned Intent at creation and shares a link/QR; a relayer settles any token with no recipient online.
> - `<PeltierSend provider recipient allowedRouters />` — **Flow C** (push / send): the sender pushes any token → USDC from their own wallet, with mandatory client-side calldata verification before signing.

```typescript
import { PeltierProvider, DepositWidget } from '@peltier/react'
import '@peltier/react/styles.css'

function PaymentPage() {
  return (
    <PeltierProvider
      apiUrl="https://api.peltier.dev"
      publishableKey="pk_live_…"
    >
      <DepositWidget
        destinationAddress="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
        destinationChainId={8453}
        chains={[8453, 42161, 10]}
        theme="dark"
        onStatusChange={(status) => console.log('Status:', status)}
        onComplete={(txHash) => console.log('Done:', txHash)}
        className="max-w-md mx-auto"
      />
    </PeltierProvider>
  )
}
```

## Props

### Core

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `destinationAddress` | string | No | Address where USDC settles (`0x…` EVM, or base58 for a Solana destination). When **omitted**, the widget shows an editable **Destination** panel (self-serve) and holds off session registration until the user enters one; when **provided**, the destination is fixed and the panel is hidden. `<PeltierCheckout>` and `<PeltierRequest>` require it. |
| `destinationChainId` | number | Yes | Chain ID for USDC settlement. Any supported destination: `1`, `42161`, `8453`, `10`, `137`, `143` (Monad), `999` (HyperEVM, destination-only), or the Solana sentinel `7565164`. |
| `chains` | number[] | No | Limit which **source** chains the user may deposit from. Defaults to all deposit-capable chains — the 6 EVM chains that support burner deposits (HyperEVM is settle-only) plus Solana. |
| `theme` | "light" \| "dark" | No | Widget color scheme. Defaults to `"light"`. |
| `onStatusChange` | (status: SessionStatus) => void | No | Fires whenever the session status changes (see the status table below). |
| `onComplete` | (ref: string) => void | No | Fires when settlement is confirmed. On the deposit/checkout/request path it receives the **session id** (that engine has no single tx hash — settlement can span a sweep and a bridge); on the embedded "Pay from Wallet" (Flow C) path it receives the final **tx hash**. `<PeltierSend>` always passes a tx hash. |
| `onWalletConnect` | () => void | No | Fired by "Pay from Wallet" when no `walletProvider` is supplied — the integrator runs their own connect flow and passes the provider back in. |
| `onPeerOnramp` | () => void | No | Callback when user selects a peer-to-peer onramp method. |
| `className` | string | No | CSS class passthrough for the widget root element. |

### Intent bounds (EIP-712)

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `amount` | string | No | Requested settlement USDC (base units, 6 dp). Seeds the Intent's `minOut` (and `maxIn` for a direct-USDC payment) so the contract enforces the requested amount. |
| `minOut` | string | No | Floor on USDC delivered after both fees (base units). Overrides `amount`; falls back to `amount`, else 0. |
| `maxIn` | string | No | Cap on the deposit amount this Intent may settle (base units). |
| `inToken` | \`0x${string}\` | No | Pin a fixed deposit token. Omit for the any-token flow (the Intent binds to the *detected* token after detection). |
| `intentTtlSeconds` | number | No | Signed-Intent validity. Default `1800` (30 min). |

### Merchant checkout mode (Flow A)

Supply **all three** together to attach to a server-created checkout session; if any is missing the widget silently falls back to the anonymous flow. Prefer `<PeltierCheckout>`, which makes the trio required at the type level.

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `sessionId` | string | No | Existing checkout session id (from `createPaymentSession`). |
| `clientSecret` | string | No | Per-session `client_secret` gating the browser calls. |
| `publishableKey` | string | No | Publishable `pk_…` key authenticating browser calls in merchant mode. |

### Flow B (request) & Flow C (send)

| Prop | Type | Required | Description                                                                                                          |
| --- | --- | --- |----------------------------------------------------------------------------------------------------------------------|
| `flow` | Flow | No | `'p2p_request'` renders the Flow B request-create view. Omit (or `'checkout'`) for the deposit view.                 |
| `appBaseUrl` | string | No | Base URL for the Flow B shareable link `…/p2p/{id}?burner=<addr>`. Defaults to `https://peltier.dev`.                |
| `onRequestCreated` | (link, sessionId) => void | No | Fires once a Flow B request is created + committed, with the shareable link.                                         |
| `walletProvider` | EIP-1193 provider | No | Connected provider enabling the in-widget Flow C Send view (quote → verify → approve → swap → poll).                 |
| `allowedRouters` | string[] | No | Whitelist of acceptable `tx.to` router / spoke-pool targets for the Flow C calldata check (fails closed when empty). |

## Session Status Values

| Status | Description |
| --- | --- |
| `idle` | Widget loaded, no session yet. User is choosing deposit method. |
| `registering` | Generating burner key and registering session with backend. |
| `pending` | Session registered. Waiting for the user to fund the deposit — send tokens to the EVM burner address, or on Solana sign the transaction that funds the non-custodial vault. SSE connection active. |
| `detected` | Incoming deposit detected by the indexer. Preparing to sweep. |
| `sweeping` | Sweeper is executing the swap/bridge transaction(s). |
| `bridging` | Cross-chain only: source-chain bridge tx confirmed; waiting for delivery on the destination chain. |
| `swept` | USDC has been delivered to the destination address. Terminal success state. |
| `failed` | Sweep failed. The session can be refunded. Check `error_message` for details. |
| `bounced` | Terminal failure auto-refunded to the session's refund target — on Solana the on-chain-pinned `refund_address`, on EVM any session with a **standing refund** on file (a per-chain poller bounces the balance automatically). Distinct from `failed`, where funds await a manual refund claim. |
| `expired` | No deposit received within the 30-minute TTL. |
