# Troubleshooting

## I lost my note

You cannot recover the deposit. This is not a software problem; it's the design. If a third party could recover from a lost note, they could also steal from you with no warning.

For the future: see [Managing your note](/using-tonado-cash/managing-your-note.md) for backup recommendations.

## `note check` says `Spent: YES` but I never withdrew

Two possibilities:

1. **You did withdraw and forgot.** Search your wallet history for incoming `denomination - fee` transactions.
2. **Someone else with your note withdrew.** The note was leaked. There is no recovery; the funds are at the recipient address chosen by whoever submitted the proof. This is why notes are sensitive.

## My deposit transaction succeeded but `note check` still says `Spent: NO` and the indexer doesn't see it

Wait a few more seconds; TON settlement is \~5 seconds and the indexer's poll interval may add a small delay. If after 30+ seconds the relayer hasn't picked up the deposit:

* Confirm the transaction landed on a block explorer like [tonviewer.com](https://tonviewer.com) (or testnet.tonviewer.com).
* If the tx exists but the relayer hasn't indexed it, the relayer may be lagging or disconnected. Check the relayer's `/status` endpoint and `sync_lag`.
* If the tx doesn't exist, your wallet may have failed to send. Check your wallet's outgoing message history.

## My deposit transaction failed with `ERR_WRONG_DENOMINATION` (exit code from your wallet)

You sent the wrong amount. The pool only accepts deposits of *exactly* the pool's denomination plus gas. The CLI automatically attaches the right amount; if you got this error, something interfered with the message construction. Re-run `tonado deposit ...` rather than retrying the wallet's send.

## My deposit transaction failed with `ERR_DUPLICATE_COMMITMENT`

The commitment you tried to insert is already in the pool. This means either:

* You re-used a note that you've already deposited (don't; generate a fresh one).
* Two of your wallets used the same random seed (vanishingly unlikely with proper randomness).

Generate a new note and try again.

## My withdrawal fails with `ERR_UNKNOWN_ROOT`

The Merkle root your proof references is no longer in the pool's 30-deep root-history ring. This happens when 30+ new deposits land between your proof generation and submission. Solution: rebuild the proof against a fresher root and resubmit.

If you're using a relayer, the relayer should handle this automatically. If you're self-relaying, re-run `tonado withdraw self`.

## My withdrawal fails with `ERR_ALREADY_SPENT`

Your nullifier hash is already in the pool's nullifier dict. The note has been withdrawn, by you or by someone with the note. See "`Spent: YES` but I never withdrew" above.

## My withdrawal fails with `ERR_PROOF_INVALID`

The proof's public inputs don't match what the on-chain verifier expects. Possible causes:

* **Recipient mismatch.** The recipient bound in the proof doesn't match the recipient field in the message. (The CLI prevents this; if you constructed the call manually, double-check.)
* **Relayer mismatch.** The relayer field bound in the proof doesn't match the actual broadcasting wallet. The relayer should reject this before broadcasting, but if it slips through, the on-chain verifier catches it.
* **Stale circuit artifacts.** If you're running custom-built artifacts, the proving key and verifier may be out of sync. Re-run `pnpm circuits:compile && pnpm verifier:export` and redeploy.
* **Pool-side bug.** If you have a fresh build and clean inputs and it still fails, file an issue.

## The relayer is unreachable

```
tonado withdraw relay ...
Error: relayer at <url> did not respond
```

Try:

* Another relayer URL. If multiple relayers exist, switch.
* `tonado relayer status --url <url>` to confirm the relayer is up.
* Falling back to `tonado withdraw self` if you must withdraw urgently. Accept the privacy loss.

## I want to withdraw to a wallet that doesn't exist yet

That works. TON addresses can receive funds before the wallet contract is deployed. The recipient address just needs to be a valid TON address (workchain + hash). When the recipient eventually deploys their wallet, the funds will be there waiting.

This is, in fact, a privacy-strengthening pattern: deploy your recipient wallet *after* the withdrawal, so the address has no on-chain history before the funds arrive.

## My proof generation takes forever

Proof generation is a snarkjs Groth16 prover running over a \~30,000-constraint circuit. Expected wall-clock time:

* Modern laptop: 5–15 seconds.
* Older machine or slow node: 30–60 seconds.
* Mobile-class device: not currently supported (snarkjs WASM is too slow).

If you're seeing >2 minutes, check that you're not running the prover under a debugger, that your machine isn't memory-constrained, and that the proving key (`withdraw_final.zkey`, \~50MB) is local rather than being fetched on each call.

## Something else

Open an issue: [github.com/tonadocash/monorepo/issues](https://github.com/tonadocash/monorepo/issues). Include the exact command you ran, the network, the error message, and the relevant addresses (note: do **not** post your note itself).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tonadocash.com/using-tonado-cash/troubleshooting.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
