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

# API Calldata AI Coding Reference

> Condensed REST calldata integration reference optimized for AI coding assistants

Copy this page into your AI coding assistant (Cursor, Copilot, Claude, etc.) for accurate Amplify REST calldata API completions — the path that returns ready-to-sign EVM transactions without requiring the TypeScript SDK.

<Info>
  This page is a condensed, single-file reference for the REST calldata API.
  For full documentation with per-language tabs and step-by-step walkthroughs,
  see the [API Calldata Integration
  guide](/v1.0.0/intro/products/earn/developers/guides/api-calldata/index).
</Info>

<Info>
  **Using a skill-aware tool?** The same content is exposed as the
  `amplify-earn-api-calldata` Agent Skill and is auto-discovered at
  [`/.well-known/agent-skills/index.json`](https://docs.paxoslabs.com/.well-known/agent-skills/index.json).
  Prefer the skill in agents that support them — it loads progressively. Use
  this page when you need to paste a single reference into a general-purpose
  AI chat.
</Info>

## When to Use

* Backend transaction builders in any language (Python, Go, Rust, Java, Node)
* Custodial wallets, HSMs, multisig services — fetch calldata, sign elsewhere
* Non-JS stacks that can't consume `@paxoslabs/amplify-sdk`
* Prototyping with `curl` before application code

For the TypeScript SDK with built-in wallet hooks, see the [SDK AI Reference](/v1.0.0/intro/products/earn/developers/sdk-ai-reference). For calling contracts directly without the API, see the [Contract AI Reference](/v1.0.0/intro/products/earn/developers/direct-contract-ai-reference).

## Base URL & Authentication

```
Base URL:   https://api.paxoslabs.com
API prefix: /v2
Auth:       x-api-key: pxl_<public_id>_<secret>
```

* Obtain a key at [https://app.paxoslabs.com](https://app.paxoslabs.com).
* Send the key as a header — never as a query param (it ends up in access logs).

### OpenAPI Spec

* [https://docs.paxoslabs.com/v1.0.0/api-reference/openapi.yml](https://docs.paxoslabs.com/v1.0.0/api-reference/openapi.yml)

## Endpoint Map

### Transaction preparation

| Endpoint                          | Purpose                                                                  |
| --------------------------------- | ------------------------------------------------------------------------ |
| `GET /v2/core/authorization`      | Detect authorization method (`permit` / `approval` / `already_approved`) |
| `GET /v2/amplify/deposit`         | Build deposit calldata                                                   |
| `GET /v2/amplify/withdraw`        | Build withdrawal order calldata                                          |
| `GET /v2/amplify/withdraw/cancel` | Build cancel-order calldata                                              |

### Discovery

| Endpoint                 | Purpose                                                                                                                                                         |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /v2/amplify/vaults` | Accounts grouped by `name` with per-chain `deployments[]`; each deployment carries contract addresses, per-asset flags, fees, supply caps, min order size, SLAs |

### Order status

| Endpoint                             | Purpose                                          |
| ------------------------------------ | ------------------------------------------------ |
| `GET /v2/amplify/withdrawalRequests` | Withdrawal orders with `orderIndex` and `status` |

### Analytics

| Endpoint                              | Purpose                                                                         |
| ------------------------------------- | ------------------------------------------------------------------------------- |
| `GET /v2/amplify/vaultApys`           | Historical APY time series per vault                                            |
| `GET /v2/amplify/vaultTvls`           | Historical TVL time series (+ current on-chain TVL on the final page)           |
| `GET /v2/amplify/vaultAssets`         | Per-asset depositable/withdrawable flags (paginated, flat)                      |
| `GET /v2/amplify/vaultCompositions`   | Current portfolio composition from the rate provider                            |
| `GET /v2/amplify/withdrawalVolumes`   | Historical withdrawal volumes (requires `vaultAddress`, `startTime`, `endTime`) |
| `GET /v2/amplify/liquidityShortfalls` | Pending withdrawal demand in excess of current vault balance                    |

### Display helpers

| Endpoint                                 | Purpose                                                                                               |
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `GET /v2/amplify/calculateWithdrawalFee` | Preview fee for a specific `offerAmount` + `wantAsset` redemption                                     |
| `GET /v2/amplify/supplyCaps`             | Up-to-the-block `totalSupplyInBase`, `supplyCap`, and `percentageFilled` per chain deployment         |
| `GET /v2/amplify/userPositions`          | User shareBalance, positionValueInBase, baseAssetAddress, and exchangeRateToBase per chain deployment |

**On-`/v2/amplify/vaults`** (no dedicated endpoint needed): `depositSupplyCap`, `minimumWithdrawalOrderSize`, `assets[].depositFees`, `assets[].withdrawFees`, `assets[].withdrawalSLAs`.

## Response Format (calldata endpoints only)

`/v2/amplify/deposit`, `/v2/amplify/withdraw`, and `/v2/amplify/withdraw/cancel` accept a `responseFormat` query parameter:

| `responseFormat`      | `data` (hex) | `abi` / `functionName` / `args` | Use when                                                                          |
| --------------------- | ------------ | ------------------------------- | --------------------------------------------------------------------------------- |
| `encoded` *(default)* | ✅            | ❌                               | Signer consumes raw `data` (`eth_sendTransaction`, HSM)                           |
| `full`                | ✅            | ✅                               | Debugging; need raw + decoded views                                               |
| `structured`          | ❌            | ✅                               | Encode locally (viem `encodeFunctionData`, ethers `Interface.encodeFunctionData`) |

## Filter Syntax (`filter` query parameter)

```
filter=field%3Dvalue                          # equality
filter=field1%3Dvalue1%20AND%20field2%3Dvalue2 # conjunction
```

* URL-encode once: `%3D` = `=`, `%20` = space.
* Separate query params (`chainId=1&inDeprecation=false`) are **ignored**.

## Discovery — `GET /v2/amplify/vaults`

Single aggregated endpoint. Params (all optional): `filter` (flags: `name`, `chainId`, `inDeprecation`, `requiresKyt`), `pageSize` (1–100, default 25), `pageToken`.

```bash theme={null}
curl "https://api.paxoslabs.com/v2/amplify/vaults?filter=chainId%3D1%20AND%20inDeprecation%3Dfalse" \
  -H "x-api-key: $AMPLIFY_API_KEY"
```

```json theme={null}
{
  "vaults": [{
    "name": "Amplify USDC Core",
    "deployments": [{
      "chainId": 1,
      "boringVaultAddress": "0xbbbb...",
      "depositorAddress": "0xcccc...",
      "withdrawQueueAddress": "0xdddd...",
      "requiresKyt": false,
      "baseTokenAddress": "0xA0b8...",
      "accountantAddress": "0xaaaa...",
      "tellerAddress": "0xeeee...",
      "depositFeeAddress": null,
      "withdrawFeeAddress": null,
      "inDeprecation": false,
      "depositSupplyCap": { "raw": "1000000000000", "formatted": "1000000.0", "decimals": 6, "hasCap": true },
      "minimumWithdrawalOrderSize": { "raw": "1000000000000000000", "formatted": "1.0", "decimals": 18 },
      "assets": [{
        "assetAddress": "0xA0b8...",
        "depositable": true,
        "withdrawable": true,
        "depositFees": { "bps": 0, "percentage": "0.0000" },
        "withdrawFees": { "bps": 25, "percentage": "0.2500" },
        "withdrawalSLAs": { "expectedDelay": "86400s", "expiryBuffer": "36000s", "internalWithdrawalQueueDelaySLA": "43200s", "externalWithdrawalQueueDelaySLA": "86400s", "internalAccountantRateUpdateDelaySLA": "43200s", "externalAccountantRateUpdateSLA": "86400s" }
      }]
    }]
  }],
  "nextPageToken": null
}
```

### Field → Transaction Parameter Mapping

| Discovery field                            | Used as                                                                                            |
| ------------------------------------------ | -------------------------------------------------------------------------------------------------- |
| `deployments[].boringVaultAddress`         | `vaultAddress` in `/v2/core/authorization` and all calldata endpoints; also the ERC-20 share token |
| `deployments[].depositorAddress`           | `transaction.to` returned by the prepared deposit                                                  |
| `deployments[].withdrawQueueAddress`       | Spender for the share approval before withdrawal                                                   |
| `deployments[].baseTokenAddress`           | Default `depositAsset` / `wantAsset`                                                               |
| `deployments[].requiresKyt: true`          | KYT attestation is resolved server-side — no special client handling required                      |
| `deployments[].depositSupplyCap`           | `{ raw, formatted, decimals, hasCap }`; `hasCap=false` → uncapped                                  |
| `deployments[].minimumWithdrawalOrderSize` | Minimum `shareAmount` accepted by `/v2/amplify/withdraw`                                           |

## Deposit Flow

Three authorization branches handled by one API:

| Method             | Meaning                                                          |
| ------------------ | ---------------------------------------------------------------- |
| `permit`           | EIP-2612 off-chain signature — gas-efficient, single on-chain tx |
| `approval`         | Standard ERC-20 `approve` required first, then the deposit       |
| `already_approved` | Sufficient allowance exists — deposit directly                   |

### Step 1 — Detect authorization

`GET /v2/core/authorization`

| Param          | Required | Notes                                                        |
| -------------- | -------- | ------------------------------------------------------------ |
| `vaultAddress` | Yes      | `deployments[].boringVaultAddress` from `/v2/amplify/vaults` |
| `tokenAddress` | Yes      | ERC-20 deposit token                                         |
| `amount`       | Yes      | Decimal string, token base units                             |
| `userAddress`  | Yes      | Depositor wallet                                             |
| `chainId`      | Yes      | EVM chain ID                                                 |

Response variants:

```json theme={null}
// permit
{
  "method": "permit",
  "permitData": {
    "domain": { "name": "USD Coin", "version": "2", "chainId": 1, "verifyingContract": "0xA0b8..." },
    "types":  { "Permit": [ ... ] },
    "value":  { "owner": "0x1234...", "spender": "0xcccc...", "value": "1000000", "nonce": "0", "deadline": "9999999999" },
    "deadline": "9999999999"
  }
}

// approval
{ "method": "approval", "approvalTransaction": { "encoded": "0x095ea7b3..." } }

// already_approved
{ "method": "already_approved" }
```

### Step 2 — Satisfy authorization

| Branch             | Action                                                                                                                                |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| `permit`           | Sign `domain` + `types` + `value` via `eth_signTypedData_v4` (`primaryType: "Permit"`). Keep signature **and** `permitData.deadline`. |
| `approval`         | Send tx with `to = tokenAddress`, `data = approvalTransaction.encoded`. Wait for receipt.                                             |
| `already_approved` | Skip to step 3.                                                                                                                       |

### Step 3 — Prepare deposit calldata

`GET /v2/amplify/deposit`

| Param             | Required    | Notes                                                                            |
| ----------------- | ----------- | -------------------------------------------------------------------------------- |
| `vaultAddress`    | Yes         | `boringVaultAddress`                                                             |
| `depositAsset`    | Yes         | ERC-20 to deposit                                                                |
| `depositAmount`   | Yes         | Decimal string, token base units                                                 |
| `userAddress`     | Yes         | Wallet that signs and submits; also the default share recipient                  |
| `chainId`         | Yes         | EVM chain ID                                                                     |
| `to`              | No          | Share recipient override (maps to on-chain `to` arg). Defaults to `userAddress`. |
| `permitSignature` | Conditional | Required on permit path                                                          |
| `permitDeadline`  | Conditional | From `permitData.deadline`; required with `permitSignature`                      |
| `responseFormat`  | No          | `encoded` (default), `full`, `structured`                                        |

Response (encoded):

```json theme={null}
{ "transaction": { "to": "0xcccc...", "data": "0x47e7ef24...", "value": "0" } }
```

### Step 4 — Sign & broadcast

Send `{ to, data, value }`. `value` is always `"0"` for ERC-20 deposits.

### Reference implementation (Node / viem)

```ts theme={null}
import { createWalletClient, createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'

const BASE = 'https://api.paxoslabs.com'
const HEADERS = { 'x-api-key': process.env.AMPLIFY_API_KEY! }

// 1. Detect authorization
const permitUrl = new URL(`${BASE}/v2/core/authorization`)
permitUrl.searchParams.set('vaultAddress', VAULT_ADDRESS)
permitUrl.searchParams.set('tokenAddress', DEPOSIT_ASSET)
permitUrl.searchParams.set('amount', AMOUNT)
permitUrl.searchParams.set('userAddress', account.address)
permitUrl.searchParams.set('chainId', '1')
const permit = await fetch(permitUrl, { headers: HEADERS }).then((r) => r.json())

// 2. Build deposit params, branch on method
const depositUrl = new URL(`${BASE}/v2/amplify/deposit`)
depositUrl.searchParams.set('vaultAddress', VAULT_ADDRESS)
depositUrl.searchParams.set('depositAsset', DEPOSIT_ASSET)
depositUrl.searchParams.set('depositAmount', AMOUNT)
depositUrl.searchParams.set('userAddress', account.address)
depositUrl.searchParams.set('chainId', '1')

if (permit.method === 'permit') {
  const sig = await walletClient.signTypedData({
    account,
    domain: permit.permitData.domain,
    types: permit.permitData.types,
    primaryType: 'Permit',
    message: permit.permitData.value,
  })
  depositUrl.searchParams.set('permitSignature', sig)
  depositUrl.searchParams.set('permitDeadline', permit.permitData.deadline)
} else if (permit.method === 'approval') {
  const hash = await walletClient.sendTransaction({
    to: DEPOSIT_ASSET as `0x${string}`,
    data: permit.approvalTransaction.encoded as `0x${string}`,
    chain: mainnet,
    account,
  })
  await publicClient.waitForTransactionReceipt({ hash })
}

// 3. Fetch + submit deposit
const { transaction: tx } = await fetch(depositUrl, { headers: HEADERS }).then((r) => r.json())
await walletClient.sendTransaction({
  to: tx.to as `0x${string}`,
  data: tx.data as `0x${string}`,
  value: BigInt(tx.value),
  chain: mainnet,
  account,
})
```

## Withdrawal Flow

Withdrawals are **asynchronous**. Submitting an order locks shares in the `WithdrawQueue`; the protocol processes the queue off-cycle and transfers the asset on completion.

### Step 1 — Approve share spending

Standard ERC-20 `approve(spender, amount)`:

* Token contract (`to`): `boringVaultAddress`
* `spender`: `withdrawQueueAddress`
* `amount`: share amount to redeem (always 18 decimals)

Wait for a receipt before step 2.

### Step 2 — Prepare withdrawal calldata

`GET /v2/amplify/withdraw`

| Param               | Required | Notes                                                                                              |
| ------------------- | -------- | -------------------------------------------------------------------------------------------------- |
| `vaultAddress`      | Yes      | `boringVaultAddress`                                                                               |
| `wantAsset`         | Yes      | ERC-20 to receive                                                                                  |
| `shareAmount`       | Yes      | Decimal string, 18 decimals                                                                        |
| `userAddress`       | Yes      | Submitter; also the default `intendedDepositor`/`receiver`/`refundReceiver` when those are omitted |
| `chainId`           | Yes      | EVM chain ID                                                                                       |
| `intendedDepositor` | No       | On-chain `SubmitOrderParams.intendedDepositor`. Defaults to `userAddress`.                         |
| `receiver`          | No       | Address that receives `wantAsset` on settlement. Defaults to `userAddress`.                        |
| `refundReceiver`    | No       | Address that receives refunded shares if the order is cancelled. Defaults to `userAddress`.        |
| `responseFormat`    | No       | `encoded` / `full` / `structured`                                                                  |

The server picks `submitOrder` vs `submitOrderAndProcessAll` automatically based on the account's on-chain RolesAuthority configuration — there is no client-side `atomic` flag.

Response:

```json theme={null}
{ "transaction": { "to": "0xdddd...", "data": "0x1a2b3c4d...", "value": "0" } }
```

### Step 3 — Sign & submit

Broadcast. On confirmation, shares are locked under a new `orderIndex`.

### Step 4 — Poll order status

```bash theme={null}
curl "https://api.paxoslabs.com/v2/amplify/withdrawalRequests?\
filter=userAddress%3D0x1234...%20AND%20vaultAddress%3D0xbbbb..." \
  -H "x-api-key: $AMPLIFY_API_KEY"
```

| Status           | Meaning           |
| ---------------- | ----------------- |
| `PENDING`        | In queue          |
| `COMPLETE`       | Asset transferred |
| `PENDING_REFUND` | Being refunded    |
| `REFUNDED`       | Shares returned   |

**Do not** filter on `status=PENDING` while polling — orders disappear the moment they reach a terminal state and you lose visibility into the outcome. Filter on `userAddress` + `vaultAddress` (and optionally `chainId`).

### Reference implementation (Node / viem)

```ts theme={null}
import { encodeFunctionData, erc20Abi } from 'viem'

// 1. Approve shares to the queue
const approveData = encodeFunctionData({
  abi: erc20Abi,
  functionName: 'approve',
  args: [WITHDRAW_QUEUE as `0x${string}`, BigInt(SHARE_AMOUNT)],
})
const approveHash = await walletClient.sendTransaction({
  to: VAULT_ADDRESS as `0x${string}`,
  data: approveData,
  chain: mainnet,
  account,
})
await publicClient.waitForTransactionReceipt({ hash: approveHash })

// 2. Fetch withdraw calldata
const url = new URL('https://api.paxoslabs.com/v2/amplify/withdraw')
url.searchParams.set('vaultAddress', VAULT_ADDRESS)
url.searchParams.set('wantAsset', WANT_ASSET)
url.searchParams.set('shareAmount', SHARE_AMOUNT)
url.searchParams.set('userAddress', account.address)
url.searchParams.set('chainId', '1')
const { transaction: tx } = await fetch(url, { headers: HEADERS }).then((r) => r.json())

// 3. Submit
await walletClient.sendTransaction({
  to: tx.to as `0x${string}`,
  data: tx.data as `0x${string}`,
  value: BigInt(tx.value),
  chain: mainnet,
  account,
})
```

## Cancellation Flow

Only `PENDING` orders are cancellable. The wallet submitting the cancel tx **must be** the same address that submitted the original order (`msg.sender` enforced on-chain).

### Step 1 — Find `orderIndex`

```bash theme={null}
curl "https://api.paxoslabs.com/v2/amplify/withdrawalRequests?\
filter=userAddress%3D0x1234...%20AND%20vaultAddress%3D0xbbbb...%20AND%20status%3DPENDING" \
  -H "x-api-key: $AMPLIFY_API_KEY"
```

`orderIndex` is a **decimal string** — pass it verbatim; never coerce to a JS `number`.

### Step 2 — Prepare cancel calldata

`GET /v2/amplify/withdraw/cancel`

| Param            | Required | Notes                                             |
| ---------------- | -------- | ------------------------------------------------- |
| `vaultAddress`   | Yes      | `boringVaultAddress`                              |
| `orderIndex`     | Yes      | Exact string from `withdrawalRequests.orderIndex` |
| `chainId`        | Yes      | EVM chain ID                                      |
| `responseFormat` | No       | `encoded` / `full` / `structured`                 |

Response:

```json theme={null}
{ "transaction": { "to": "0xdddd...", "data": "0x5c975abb...", "value": "0" } }
```

### Step 3 — Sign & broadcast

Send from the same wallet that submitted the order. On confirmation, locked shares return to that wallet.

## Display Helpers (read-only)

Most display data is returned inline on `/v2/amplify/vaults` (see Discovery above). Three dedicated helpers cover what isn't on the discovery response: fee preview for a specific redemption, up-to-the-block supply-cap utilization, and a user's current position.

| Endpoint                                 | Required params                                                                                                                 | Returns                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /v2/amplify/calculateWithdrawalFee` | `offerAmount`, `wantAsset`, `vaultAddress`, `chainId`                                                                           | `{ feeAmount, offerFeePercentage: { bps, percentage }, flatFee }` — all decimal strings / integers, scaled to human-readable units                                                                                                                                                                                                                                                                                                                      |
| `GET /v2/amplify/supplyCaps`             | optional `filter` (flags: `vaultAddress`, `chainId`); optional `pageSize`, `pageToken`                                          | `{ supplyCaps: [{ vaultAddress, chainId, totalSupplyInBase, supplyCap, percentageFilled }], nextPageToken }` — `supplyCap` / `percentageFilled` are `null` for uncapped vaults. With no filter, every live vault deployment is returned. Filter flags: `vaultAddress` (optional), `chainId` (optional).                                                                                                                                                 |
| `GET /v2/amplify/userPositions`          | required `userAddress` (top-level, hex); optional `filter` (flags: `vaultAddress`, `chainId`); optional `pageSize`, `pageToken` | `{ userPositions: [{ vaultAddress, chainId, shareBalance, positionValueInBase, baseAssetAddress, exchangeRateToBase }], nextPageToken, tokenMetadata }` — `baseAssetAddress` is read from the DB (or via `accountant.base()` for stand-in vaults where the canonical base asset isn't natively deployed). With no filter, the user position is returned for every live vault deployment. Filter flags: `vaultAddress` (optional), `chainId` (optional). |

Fields already on `/v2/amplify/vaults` (no dedicated endpoint):

| Field                                                 | Shape                                       | Notes                                                    |
| ----------------------------------------------------- | ------------------------------------------- | -------------------------------------------------------- |
| `deployments[].depositSupplyCap`                      | `{ raw, formatted, decimals, hasCap }`      | `hasCap: false` → uncapped (maxUint256)                  |
| `deployments[].minimumWithdrawalOrderSize`            | `{ raw, formatted, decimals }`              | Minimum `shareAmount` accepted by `/v2/amplify/withdraw` |
| `deployments[].assets[].depositFees` / `withdrawFees` | `{ bps, percentage }`                       | Per-asset fees                                           |
| `deployments[].assets[].withdrawalSLAs`               | Protobuf duration strings (e.g. `"86400s"`) | Queue + rate-update SLAs                                 |

Client caching of 10–30s is safe; invalidate after any of the caller's own deposits, withdrawals, or cancellations.

## Error Envelope

```json theme={null}
{
  "error": {
    "code": 400,
    "message": "vaultAddress is not a valid hex address",
    "status": "INVALID_ARGUMENT",
    "details": [{
      "@type": "type.paxoslabs.dev/errors/BadRequest",
      "fieldViolations": [{ "field": "vaultAddress", "description": "..." }]
    }]
  }
}
```

| HTTP | `error.status`       | Action                                      |
| ---- | -------------------- | ------------------------------------------- |
| 400  | `INVALID_ARGUMENT`   | Fix request; inspect `fieldViolations`      |
| 401  | `UNAUTHENTICATED`    | Verify `x-api-key` header                   |
| 403  | `PERMISSION_DENIED`  | Rotate the key                              |
| 404  | `NOT_FOUND`          | Re-discover via `/v2/amplify/vaults`        |
| 429  | `RESOURCE_EXHAUSTED` | Back off (respect `Retry-After` if present) |
| 503  | `INTERNAL`           | Retry with exponential backoff              |

Retries: `429` and `503` are safe. `400`, `401`, `403`, `404` are deterministic — do not retry without changing inputs.

## Common Gotchas

| Gotcha                                                        | Consequence                     | Fix                                                                                    |
| ------------------------------------------------------------- | ------------------------------- | -------------------------------------------------------------------------------------- |
| Filter passed as separate query params                        | Predicates silently ignored     | Use single `filter=field%3Dvalue%20AND%20...`                                          |
| `permitSignature` without `permitDeadline`                    | `400 INVALID_ARGUMENT`          | Send both from the permit response                                                     |
| Expired permit deadline                                       | On-chain revert                 | Re-fetch `/v2/core/authorization`                                                      |
| Approval tx not mined before deposit                          | Revert (insufficient allowance) | Wait for receipt before preparing deposit                                              |
| Passing a client-side `atomic` flag to `/v2/amplify/withdraw` | Ignored                         | The server chooses `submitOrder` vs `submitOrderAndProcessAll` based on on-chain roles |
| Deposit `amount` uses wrong decimals                          | Revert / rounding               | USDC/USDT = 6 decimals; shares always 18                                               |
| `shareAmount` uses token decimals                             | Too-small withdrawal or `400`   | Share tokens are always 18 decimals                                                    |
| Polling with `status=PENDING`                                 | Order "vanishes" at completion  | Drop the `status` predicate from the poll query                                        |
| `orderIndex` coerced to `number`                              | Off-by-one for large indices    | Keep as string end-to-end                                                              |
| Cancel from a different wallet                                | On-chain revert                 | Sign from the original submitter                                                       |
| Stale address cache                                           | Calls hit deprecated contracts  | Respect `inDeprecation`; refresh on startup                                            |

## Supported Chains

| Chain          | ID       |
| -------------- | -------- |
| Ethereum       | 1        |
| Sepolia        | 11155111 |
| Base           | 8453     |
| HyperEVM       | 999      |
| Stable Testnet | 2201     |

## Canonical Docs

* Overview: [https://docs.paxoslabs.com/v1.0.0/intro/products/earn/developers/guides/api-calldata/index](https://docs.paxoslabs.com/v1.0.0/intro/products/earn/developers/guides/api-calldata/index)
* Authentication: [https://docs.paxoslabs.com/v1.0.0/intro/products/earn/developers/guides/api-calldata/authentication](https://docs.paxoslabs.com/v1.0.0/intro/products/earn/developers/guides/api-calldata/authentication)
* Discovery: [https://docs.paxoslabs.com/v1.0.0/intro/products/earn/developers/guides/api-calldata/discovery](https://docs.paxoslabs.com/v1.0.0/intro/products/earn/developers/guides/api-calldata/discovery)
* Deposits: [https://docs.paxoslabs.com/v1.0.0/intro/products/earn/developers/guides/api-calldata/deposits](https://docs.paxoslabs.com/v1.0.0/intro/products/earn/developers/guides/api-calldata/deposits)
* Withdrawals: [https://docs.paxoslabs.com/v1.0.0/intro/products/earn/developers/guides/api-calldata/withdrawals](https://docs.paxoslabs.com/v1.0.0/intro/products/earn/developers/guides/api-calldata/withdrawals)
* Cancellations: [https://docs.paxoslabs.com/v1.0.0/intro/products/earn/developers/guides/api-calldata/cancellations](https://docs.paxoslabs.com/v1.0.0/intro/products/earn/developers/guides/api-calldata/cancellations)
* Display helpers: [https://docs.paxoslabs.com/v1.0.0/intro/products/earn/developers/guides/api-calldata/display-helpers/index](https://docs.paxoslabs.com/v1.0.0/intro/products/earn/developers/guides/api-calldata/display-helpers/index)
* OpenAPI spec: [https://docs.paxoslabs.com/v1.0.0/api-reference/openapi.yml](https://docs.paxoslabs.com/v1.0.0/api-reference/openapi.yml)
* Agent Skill: [https://docs.paxoslabs.com/.well-known/agent-skills/index.json](https://docs.paxoslabs.com/.well-known/agent-skills/index.json)
