Use this guide for client integrations built on the Solana Privacy Layer SDK. Identify the last completed stage before retrying an operation.
Wallet authorization, proof generation, relayer acceptance, Solana confirmation, indexer availability, private-state discovery, and client reconciliation are separate stages. Success at one stage does not prove that every later stage has completed.
If a withdrawal or swap has a jobId, check that job before submitting the proof again. The relayer detects duplicate proofs while an earlier job is pending or processing, and a client-side timeout does not cancel the job.

Quick triage

SymptomBoundary to checkFirst action
The client does not initializeRPC and environment configurationConfirm the RPC, indexer, relayer, and deployed program belong to the same Solana environment.
The private balance does not loadWallet signature, indexer scan, or local private-state cacheConfirm the wallet and environment, then verify that the indexer exposes the expected commitment.
Proof preparation failsIndexer tree state, Merkle proof, or proof artifactsCheck the current root and the commitment proof before generating a new proof.
A withdrawal or swap remains in progressRelayer jobPreserve the jobId and read its current status.
A transaction signature exists but the product action is incompleteConfirmation, indexer, or client reconciliationCheck Solana confirmation, then indexed private state, then the client record.
The program rejects the transactionProgram constraintUse the exact program error to identify the failed proof, amount, mint, fee, recipient, or swap constraint.

Configuration and connectivity

The client requires VITE_SOLANA_RPC_HOST. It also uses VITE_INDEXER_URL and VITE_RELAYER_URL for private-state and relayer operations.Confirm that:
  1. VITE_SOLANA_RPC_HOST resolves to the intended Solana environment.
  2. VITE_INDEXER_URL resolves to the indexer for the same environment and program.
  3. VITE_RELAYER_URL resolves to the relayer for that deployment.
  4. The indexer PROGRAM_ID matches the program used by the client SDK.
Do not mix localnet, devnet, or production endpoints. A healthy endpoint from another environment still produces inconsistent roots, commitments, and transaction state.Resolved when: The client initializes and all three services resolve inside the same environment.
The SDK reads the current tree from GET /root, commitment pages from GET /commitments, and Merkle proofs from GET /proof/:commitment.Check GET /health first. Then verify that GET /root returns the current root and next index. If those calls fail, do not attempt to build a new private operation from cached tree data.Messages such as Failed to fetch Merkle root and nextIndex, Failed to fetch tree state from indexer, or API request failed identify the indexer boundary.Resolved when: Health, root, commitment, and proof reads succeed for the configured program.
The client considers the relayer available only when GET /health reports status: ok and the relayer is enabled. Relayer configuration also requires a valid relayer key and sufficient operational balance.Failed to connect to relayer means the client received no usable response. Confirm the configured URL and health response before preparing another proof.Resolved when: The health response reports an enabled relayer and a new job can be accepted.

Wallet and request validation

Private-state discovery derives its decryption context from a wallet signature. The same connected wallet must authorize the scan and operation.Messages include Wallet not connected, Failed to get wallet signature, and Failed to get signature. Please ensure your wallet is connected.
  1. Reconnect the intended wallet.
  2. Confirm that the wallet is connected to the configured Solana environment.
  3. Approve the signature request through the wallet.
  4. Restart the private-state scan before retrying the operation.
Do not send the resulting wallet signature to support. It is used to derive private state.Resolved when: The intended wallet signs the request and its private-state scan starts.
Client validation can return:
MessageCorrection
Enter amountProvide an amount.
Use a positive decimal amountUse digits with an optional decimal fraction.
Amount must be greater than 0Enter a positive amount.
This token supports up to <n> decimal placesUse no more than the token’s supported precision.
Amount exceeds available balanceReduce the amount to the available balance.
Wallet address must be valid base58Correct the Solana address.
Wallet address must decode to 32 bytesUse a valid 32-byte Solana public key.
Correct the request before generating a proof. Repeating an unchanged request cannot resolve a validation error.
The deposit flow performs its configured compliance check before fetching private inputs or generating a proof. AML compliance check failed. Please contact support means the operation stopped at that control.Do not bypass the check or retry with modified identity data. Preserve the public wallet address, UTC time, environment, and exact response, then use the approved escalation path.

Private balance and commitments

The client obtains commitment pages from the indexer, attempts to decrypt encrypted outputs for the connected wallet, checks whether each UTXO has been spent, and caches the resulting private state by program and wallet.Check in this order:
  1. Confirm the deposit signature on the configured Solana environment.
  2. Confirm the indexer is following the same program.
  3. Verify that GET /commitments includes the expected public transaction signature or commitment.
  4. Confirm that the same wallet approved the private-state signature request.
  5. Run a controlled private-state rescan if the client integration exposes one.
If the commitment is not indexed, local cache changes cannot recover it. If the commitment is indexed but the intended wallet cannot discover it, preserve the program ID, wallet public key, commitment, and transaction signature for escalation. Do not share the encrypted output or wallet signature.Resolved when: The unspent private output is discovered and reflected in the client balance.
Withdrawals and swaps require an unspent private input for the selected mint. Messages include:
  • Need at least 1 unspent UTXO to perform a withdrawal;
  • No balance available;
  • Insufficient balance;
  • No unspent UTXOs found for the input mint. Please deposit first;
  • Insufficient balance in UTXO.
Confirm the selected mint, private balance, spent status, amount, and required fee. Do not treat a public wallet balance as available private balance.Resolved when: The selected private inputs cover the operation and its fee.

Tree state and proof generation

Proof generation requires a current indexer root and a Merkle path for each real input commitment.
  • Failed to fetch tree state from indexer means the SDK could not obtain the root and next index.
  • Failed to fetch Merkle proof means the commitment proof was unavailable.
Verify indexer health, environment, program ID, commitment presence, and the current root. Generate a new proof only after those reads are consistent.
Root is not known in the tree means the proof uses a root the program does not accept as part of its current root history. This commonly indicates stale or cross-environment tree state.Do not resubmit the same proof. Refresh the indexer state, confirm the program boundary, fetch current Merkle paths, and generate a new proof.Resolved when: The proof is generated from a root accepted by the deployed program.
Proof is invalid and External data hash does not match the one in the proof mean the proof and submitted transaction data are not consistent.Rebuild the operation from the original client intent. Do not edit proof bytes, recipient, mint, fee, amount, encrypted output, or swap data after proof generation.Escalate if a newly generated proof fails against a confirmed current root and unchanged transaction data.

Deposit issues

The deposit flow checks compliance, scans private state, encrypts outputs, generates a proof, builds and signs the transaction, sends it, and waits for confirmation.If the client reports a blockhash expiry, it can rebuild with a new blockhash. If it reports Transaction confirmation timeout after polling or Failed to confirm transaction after maximum retries, first determine whether a transaction signature was produced.
  • If a signature exists, query that signature on the configured Solana environment before retrying.
  • If the transaction is confirmed, wait for the indexer and private-state scan.
  • If no signature exists, preserve the last displayed stage and exact error.
Resolved when: The signature is confirmed and its new commitments are available through the indexer.
ALT not found: <address> means the configured Address Lookup Table is not available through the current RPC environment. Confirm the deployment’s ALT address and network. Do not substitute an address from another deployment.
MessageMeaning
Unsupported mint addressThe selected mint is not configured for the deployed program.
Deposit limit exceededThe requested deposit exceeds the configured program limit.
Public amount is invalidThe submitted public amount does not satisfy the program constraint.
Correct the mint or amount through the client product. Program limits must be changed only through the authorized deployment process.

Relayer, withdrawal, and swap issues

The relayer processes withdrawals and swaps asynchronously.
StatusMeaningAction
pendingThe job is waiting in the queue.Preserve the jobId and continue status checks.
processingThe relayer is executing the job.Do not submit the proof again.
completedThe relayer returned a successful result and transaction signature.Confirm the signature, then reconcile indexed private state.
failedThe relayer recorded a final error.Use the stored error to correct or escalate the operation.
Withdrawal processing timed out. Check job status later and Swap processing timed out. Check job status later refer to client polling, not necessarily to the relayer result.If GET /relayer/status/:jobId returns Job not found, preserve the jobId, UTC submission time, environment, and operation type for escalation.
Use the exact message:
MessageCheck
Insufficient funds for withdrawalPrivate input value and requested amount
Insufficient funds for feePrivate balance available for the configured fee
Fee recipient does not match global configurationDeployment and relayer configuration
Fee amount is below minimum requiredFee calculation for the current deployment
Recipient account does not match the ExtData recipientRecipient used during proof generation and submission
Generate a new proof after correcting the source request. Do not modify the existing proof payload.
Use the exact message:
MessageCheck
Invalid Jupiter swap dataQuote and Jupiter instruction used to build the operation
Insufficient swap output: received amount is less than minimum requiredQuote freshness, minimum output, and configured slippage
Unsupported mint addressInput and output mints configured for the deployment
Obtain a current quote and rebuild the operation. Do not reuse an old proof with new swap data.

Reconcile the final state

For every client-visible operation, determine the last confirmed stage:
StageEvidence
Request validatedFinal validated amount, mint, recipient, and client reference
Proof generatedOperation reached proof completion without changing its inputs
Relayer acceptedjobId and initial job status
Solana confirmedPublic transaction signature on the configured environment
Commitments indexedExpected encrypted outputs and commitments available from the indexer
Client reconciledClient system of record reflects the confirmed operation
A transaction is not operationally complete until the client system of record has reconciled the confirmed and indexed result.

Escalate safely

Collect:
  • UTC date and time;
  • Solana environment and program ID;
  • client operation reference;
  • wallet public key;
  • input and output mint addresses;
  • relayer jobId, if created;
  • public transaction signature, if created;
  • last completed stage and exact error;
  • indexer health state and current root, where relevant.
Never include a wallet secret key, recovery phrase, wallet signature used to derive private state, relayer private key, proof witness, decrypted UTXO, unredacted encrypted output, or private client ledger data.

How it works

Review the private transaction flow.

Support home

Choose another product or network.

Contact support

Review the escalation path.