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

<Warning>
  **Preview feature — pending external audit, and enabled per deployment.**
  Several fields are launch-limited; see [Launch
  limitations](/sdk/concepts/portal-deposits#launch-limitations).
</Warning>

React Native exposes the supported portal lifecycle as methods on your
`PrivacyBoost` instance. `createPortal` derives the portal EOA from the account
seed 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** — the operator runs this at launch, 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(undefined); // 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.listPortals();
const deposits = await sdk.listPortalDeposits(portal.address);
const status = await sdk.getPortalStatus(portal.address);
```

<Info>
  `status.delegated` is launch-limited: the server may report `false` even for a
  portal just created by `createPortal`. Do not gate readiness on that field.
</Info>

## Sweep and reclaim

At launch, sweeping is normally operator-run. 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,
  gasLimit,
  maxFeePerGasWei,
  maxPriorityFeePerGasWei,
);
```

`nonce` and `gasLimit` are `bigint` values in the React Native binding. `E`
must hold native gas for the withdrawal transaction.

## Low-level escape hatches

The package 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-react-native';

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;
}

enum PortalDepositState {
  PendingSweep = 'PendingSweep',
  Credited = 'Credited',
  Cancellable = 'Cancellable',
  Cancelled = 'Cancelled',
  Unknown = 'Unknown',
}

interface PortalDeposit {
  portalDepositId: string;
  portal: string;
  tokenId: number;
  grossAmount: string;
  netAmount: string;
  state: PortalDepositState;
  requestBlock: bigint;
  cancellableAtBlock: bigint;
}
```
