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

# Portal deposits

# Portal Deposit Addresses

Give a user a reusable, public, exchange-style deposit address. Anyone can fund
it with standard ERC-20 transfers, and the funds are credited into the owner's
shielded balance without revealing which account was credited. See
[Portal Deposit Addresses](/sdk/concepts/portal-deposits) for the concept and
trust model.

WASM exposes the supported portal lifecycle as methods on your `PrivacyBoost`
instance. `createPortal` derives the portal EOA from the recovered nullifying key and keeps
the key inside core.

## Lifecycle at a glance

1. **Check support** — `sdk.portalDelegateAddress()`.
2. **Create** — `sdk.createPortal()` derives `E`, gaslessly delegates and
   registers it, then publishes discovery.
3. **Share** — senders fund the returned `portal.address` with ordinary ERC-20.
4. **Sweep / credit** — a keeper normally runs this, or you can call
   `sdk.sweepPortal(...)` as a backstop.
5. **Recover** — use `sdk.reclaimPortalDeposit(...)` for uncredited swept
   deposits, then `sdk.withdrawPortal(...)` if raw funds are resting at `E`.

## Check support

```typescript theme={null}
const delegate = sdk.portalDelegateAddress();
if (!delegate) {
  throw new Error('This server does not support portal deposits.');
}
```

## Create a portal

```typescript theme={null}
const portal = await sdk.createPortal(); // or sdk.createPortal(0)

console.log(portal.address); // share this public deposit address
console.log(portal.index);   // seed-derivation index for recovery actions
console.log(portal.bindH);   // public on-chain binding
```

`createPortal` is resumable. If the same seed-derived portal is already created,
the method returns it as a no-op. Passing an explicit index recreates that
deterministic portal; omitting it picks the next free index.

## List portals and deposits

```typescript theme={null}
const portals = await sdk.listPortalsPage(undefined, 100);
const deposits = await sdk.listPortalDepositsPage(portal.address, undefined, 100);
const status = await sdk.getPortalStatus(portal.address);
```

## Sweep and reclaim

Sweeping is permissionless, and deployments normally run a keeper. If you need
to trigger it yourself:

```typescript theme={null}
const txHash = await sdk.sweepPortal(portal.address, tokenId);
```

If a swept deposit remains uncredited past the cancel delay:

```typescript theme={null}
const txHash = await sdk.reclaimPortalDeposit(portalDepositId);
```

`reclaimPortalDeposit` returns funds to the portal address `E`, not to the caller.
To move raw funds from `E`, build a signed transaction and broadcast it yourself:

```typescript theme={null}
const rawTx = sdk.withdrawPortal(
  portal.index,
  tokenAddress,
  destination,
  amountWei,
  nonce.toString(),
  gasLimit.toString(),
  maxFeePerGasWei,
  maxPriorityFeePerGasWei,
);
```

`E` must hold native gas for the withdrawal transaction.

## Low-level escape hatches

The module still exports two low-level helpers for custodial integrations that
manage their own portal EOA key:

```typescript theme={null}
import { generatePortalEoa, encodePortalWithdraw } from '@sunnyside-io/privacy-boost-wasm';

const eoa = generatePortalEoa(); // privateKey is SECRET
const calldata = encodePortalWithdraw(tokenAddress, destination, amountWei);
```

The seed-derived `createPortal` flow does not use or expose `eoa.privateKey`.

## Types

```typescript theme={null}
interface Portal {
  address: string;
  index: number;
  bindH: string;
}

interface PortalInfo {
  address: string;
  index?: number;
  status: PortalStatus;
}

interface PortalStatus {
  registered: boolean;
  delegated: boolean;
  published: boolean;
}

interface PortalDeposit {
  portalDepositId: string;
  portal: string;
  tokenId: number;
  grossAmount: string;
  netAmount: string;
  sweepFeeBps: number;
  feeAmount: string;
  state: 'pending_sweep' | 'credited' | 'cancellable' | 'cancelled' | 'unknown';
  requestBlock: number;
  cancellableAtBlock: number;
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.