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

# Integrate withdrawals

Build a Nullark withdrawal from note recovery through proof generation, preflight, submission, and final pool events.

A withdrawal touches recovery, tree state, proving files, fee state, calldata, transport, and settlement. Build it in stages, and do not change the public withdrawal intent after generating its proof.

## Recover

Parse the recovery material in memory controlled by your application. Reject the wrong chain, pool, runtime, template, commitment, checksum, or encrypted payload before making RPC calls.

A restored record is only a candidate note until membership and spent-state checks pass. Never log it or send it through analytics and error-reporting hooks.

## Synchronize

Read from the runtime RPC starting at the configured deployment block:

- Commitment insertion and leaf index
- Merkle path to a currently accepted root
- Nullifier spent state
- Active fee and bounded fee policy
- Pool and verifier bytecode identity where required

RPC results need to match the bundled runtime. Stop when the chain or contract differs.

## Prove

Build one fixed withdrawal intent containing the accepted root, child nullifier, destination, gross amount, fee, chain, pool, proof context, and encrypted cover-payload hash. Load only proving files authenticated by the independent manifest pin.

```text
private note + Merkle witness
  + immutable public intent
  + authenticated prover artifacts
  = proof package
```

Verify the generated proof locally and compare every public input by name and position. A response with the right array length can still contain the wrong statement.

## Preflight

Immediately before submission:

1. Recheck RPC chain ID.
2. Recheck nullifier remains unspent.
3. Recheck active fee and user bounds.
4. Simulate exact zero-value transaction with `eth_call`.
5. Run remote `eth_estimateGas` against MegaETH.

If the root, fee, destination, amount, chain, pool, proof context, or encrypted payload changes, build a fresh proof package.

## Submit

Send the exact prepared transaction through the user's connected wallet after preflight. Relayer requests and deadlines are still pending in the SDK, so keep them out of calldata wrappers for now.

An unknown wallet result needs investigation, not an automatic retry. See [Submission transport](/developers/relayer-integration.md) for the boundary any future transport must preserve.

## Reconcile

Resolve success from the configured pool:

- Transaction succeeded at expected pool
- Pool `nullifiers` marks the intended child nullifier as spent
- `Withdrawal` matches nullifier, destination, gross amount, net amount, fee, and encrypted payload
- Any unspent sibling child remains in the restored bundle inventory

## Negative test matrix

| Mutation | Expected result |
| --- | --- |
| Different destination or gross amount | Proof-intent rejection |
| Stale fee | Fresh proof required |
| Wrong public-input order | Artifact or proof-package rejection |
| Already-spent nullifier | Preflight and contract rejection |
| Wrong pool or chain | Runtime rejection |
| Submitter changes selector, target, value, or calldata | Preflight or contract rejection |
| Receipt lacks expected settlement events | Unresolved, not complete |

The [TypeScript SDK](/developers/sdk.md) performs these checks around the local prover. See [Withdrawal public inputs](/reference/public-inputs.md) and [Where a Nullark flow can fail](/reference/failure-boundaries.md) for exact stop conditions.
