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

# Catalog token transfers

> How amount_decimal, token, and Mermail's amount guards work for paybox_request_transfer.

Every new Agent Wallet transfer uses `paybox_request_transfer`, including
Circle USDC, native ETH/SOL, and reviewed catalog tokens. Read the current tool
schema and portfolio before every request; do not reuse a stale schema or
invent a fallback path.

On full-profile OAuth, a current workspace member can use this live tool through
the workspace owner's active PayBox connection. The member remains the audited
actor. This does not expose owner-only legacy proposal tools or connection
management and does not broaden the exact transfer the member authorized.

| Path                                               | Tool                                                                        | Amount field                                                    |
| -------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------- |
| New transfer, including USDC/native/catalog tokens | `paybox_request_transfer`                                                   | Exact live-schema amount field, commonly human `amount_decimal` |
| Explicit legacy USDC proposal management           | `create_agent_wallet_transfer_proposal` then `submit_agent_wallet_transfer` | Human USDC `amount`; never use as a fallback for a normal send  |

## Arguments for paybox\_request\_transfer

| Field            | Required           | What to send                                                                                                                                                                  |
| ---------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chain`          | Yes                | CAIP-2 chain id, for example `eip155:8453` for Base                                                                                                                           |
| `token`          | Yes                | The asset's contract address, or `native` for the chain asset. Read it from `paybox_get_portfolio` or `get_agent_wallet_portfolio`; the `token` field is visible to the model |
| `to`             | Yes                | The complete destination address                                                                                                                                              |
| `amount_decimal` | Yes in practice    | The human amount exactly as the user stated it, for example `1` or `0.000053389889845`                                                                                        |
| `amount`         | Only as a fallback | Base units, accepted only when Mermail cannot resolve the asset's decimals                                                                                                    |

```json theme={null}
{
  "chain": "eip155:8453",
  "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
  "to": "0xRecipientAddress",
  "amount_decimal": "1"
}
```

<Warning>
  Never convert the amount to base units yourself. Mermail refuses an integer
  `amount` for any asset whose decimals it can resolve and answers
  `paybox_amount_requires_decimal`, because the same request has produced both
  the intended value and a 1000x-short one.
</Warning>

## How Mermail reads the amount

Mermail resolves the asset's decimals, converts `amount_decimal` to the smallest
unit, and sends that to PayBox.

* Circle USDC and chain native assets come from a built-in table.
* Any other token is resolved through the pricing source (the DefiLlama coins
  API), cached briefly, and memoized once known.
* If the lookup fails, Mermail falls back to the built-in table.
* If no source can prove the decimals, Mermail rejects `amount_decimal` and asks
  for base units in `amount` instead. That is the only case where `amount` is
  the right field.

## Value guards

The same resolved price protects against a scale mistake reaching the chain.

| Guard                      | Effect                                                                                                                                                                                                                     |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Dust floor                 | When Mermail has a trusted unit price, a transfer implying less than about $0.01 is rejected with `paybox_amount_below_dust_floor`. Ask the user for an amount worth at least $0.01, then retry with that `amount_decimal` |
| Declared value cross-check | If you also send `value_cents` and the implied USD value differs by more than 3x, Mermail rejects with `paybox_amount_value_mismatch`                                                                                      |
| Conflicting amounts        | Sending `amount` and `amount_decimal` that disagree is rejected with `paybox_amount_scale_mismatch`. Send `amount_decimal` alone                                                                                           |

The dust floor only fail-closes on a trusted quote (DefiLlama, including a
recent memoized price, or a proven portfolio price). An ambiguous portfolio
balance, or no price at all, fails open — so the amount still has to be
correct.

## Finishing the signature

`paybox_request_transfer` and an explicitly requested legacy
`submit_agent_wallet_transfer` can both require PayBox interaction. Neither
returns a signing plan or approval URL to a model. Those stay browser-only.

* Through MCP, prefer the host-rendered PayBox MCP App. If it is unavailable or
  remains on **Waiting** without a usable action, paste one returned
  invocation-scoped `signing_handoff.console_url`. Never ask the user to paste
  a key or signature and never construct the URL from mailbox/invocation ids.
* In Agent Chat, the response carries
  `next_step: "finish_signing_in_paybox_transfer_widget"` and the user signs in
  the PayBox widget shown in the conversation.

After the user signs, read provider status once with `paybox_get_request`.
`get_paybox_invocation` is MCP audit state, not settlement evidence. Do not poll
in a loop or restart the transfer to check status.

<Card title="Errors and recovery" icon="triangle-exclamation" href="/agent-wallet/errors-and-recovery">
  What each transfer error code means and the safe way to recover.
</Card>
