<!--
Parallel Documentation — this page, as markdown.
Index of every page: https://docs.parallel.best/llms.txt
The whole documentation in one file: https://docs.parallel.best/llms-full.txt
-->

# How transactions work

The server prepares; **your wallet decides**. No write tool signs, broadcasts or custodies anything — each returns an **unsigned** transaction object you inspect, sign and submit yourself (from a wallet, a script, or an agent runtime).

## The transaction object

Every write tool returns the same shape — raw calldata, no signature anywhere in it:

```json
{
  "to": "0xC3BEF21Ea7dEB5C34CF33E918c8e28972C8048eD",
  "data": "0x...",
  "value": "0",
  "chainId": 8453,
  "gas": "210000",
  "simulation": { "success": true },
  "warnings": []
}
```

* `to`, `data`, `value`, `chainId` — pass them to your wallet as-is.
* `gas` is a best-effort estimate; it can be absent (for `bridge` the field is named `gasEstimate`). Never block on it — your wallet estimates anyway.
* Most tools return a single `tx` (plus an `approvalTx` when needed). Some staking flows return more: `stake` for sPRL2 returns an `approvalTxs` array and a `txs` array, and `claim_rewards` returns a `txs` array that can span several chains. Check whether you got `tx` or `txs`, and check each transaction's `chainId` before sending.

## Approvals

When the operation spends a token the contract cannot pull yet, the response carries an `approvalTx` alongside the main transaction:

```
sign & submit approvalTx  →  wait for it to confirm on-chain  →  sign & submit tx
```

Submitting the main transaction before the approval confirms makes it revert.

:::tip
The approval is **bounded**: the calldata grants exactly `approvalAmount` — the amount this transaction spends — to the specific spender contract. Each operation ships its own approval, so there is no standing unlimited allowance to track or revoke.
:::

## Pre-flight simulation

Every write is statically simulated before it reaches you:

* `simulation.success: false` comes with a `revertReason`. When the response bundles an `approvalTx`, a revert on allowance is the expected pre-approval state and is flagged `PENDING_APPROVAL` with severity `info` — submit the approval first, then the transaction. Any other revert is flagged `SIMULATION_FAILED` with severity `error`: the transaction would fail on-chain, don't send it.
* `warnings[]` also surfaces business risks before you sign: an sPRL1 early-unstake penalty (`EARLY_UNSTAKE_PENALTY`), a ParaBoost about to be lost on unstake (`PARABOOST_LOST`) or locked on stake (`PARABOOST_LOCK`).

Each warning has a `severity` (`info`, `warning`, `error`) and a human-readable `message` — surface them to whoever approves the transaction.

## When the server refuses

Impossible operations fail with a structured error code instead of doomed calldata: a sunset chain (`CHAIN_SUNSET`), a chain without a Parallelizer deployment (`PARALLELIZER_NOT_DEPLOYED`), a redeem or mint beyond the deposited collateral (`EXCEEDS_CAP`, with the remaining capacity), a bridge route that does not exist (`ROUTE_UNAVAILABLE` — same-chain, or a destination without a bridgeable token), a bridge amount above the daily capacity (`EXCEEDS_BRIDGE_LIMIT`, with the reset time), or an unknown collateral (`COLLATERAL_NOT_SUPPORTED`, with the valid list).

## Partial reads

Multi-chain aggregates never fake completeness. When a chain read fails, the response carries `partial: true` and a `failedChains` list, and the totals exclude those chains — a lower bound, never a silently amputated number. Partial results are also never cached, so the next call retries the failed chains.

Some reads go further and refuse to answer at all rather than mislead — `get_proof_of_solvency` (a ratio computed on incomplete data could declare the protocol insolvent when it is not) and the savings rate reads, whose partial answer would be structurally wrong. These fail with a `PARTIAL_READ` error naming the chains that could not be read.

**How to handle it:** `PARTIAL_READ` is transient — a retry a few seconds later usually succeeds. If it persists, `parallel_health_check` tells you which chain's RPCs are down.

## Data freshness

Read tools cache briefly: savings and exchange rates 30 s, TVL/supply/staking 60 s, collaterals and fees 120 s, chain list 5 min. Bridge status and history are always live. If an RPC degrades, the server serves the last known value for up to 10 minutes rather than failing.

## Next steps

* [Tools reference](/agents/mcp/tools) — which tools return transactions
* [Connect your AI](/agents/mcp) — setup in 2 minutes
* [x402 payments](/agents/x402) — payments that settle without your wallet ever holding gas

