> ## Documentation Index
> Fetch the complete documentation index at: https://ftp-tech.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# x402 Agent Integration

> Make automated Canton Coin or CIP-56 token payments from an agent or backend service using the canton-agent-wallet CLI and SDK.

An **agent** (or payer) is any client that calls x402-gated endpoints. When the server returns `402 Payment Required`, the agent signs a `TransferFactory_Transfer` (naming the merchant as receiver) but does **not** submit it — it attaches the payer-signed transfer as the payment proof and retries automatically. The facilitator relays that signed transfer and pays the network traffic fee; because the merchant holds a standing `TransferPreapproval`, it settles directly to the merchant in a single transaction.

## Install

```bash theme={null}
npm i -g @ftptech/canton-agent-wallet@latest
```

<Note>
  These examples target **mainnet** via the `facilitator.ftptech.xyz` relay. The CLI defaults to `canton:testnet`, so select mainnet first, otherwise a testnet wallet hits the mainnet facilitator and payments fail with a network mismatch:

  ```bash theme={null}
  export CANTON_AGENT_NETWORK=canton:mainnet
  ```
</Note>

## CLI Commands

### Create a wallet

Generates an Ed25519 key pair, allocates a Canton party, and saves the wallet to `~/.canton-agent/wallet.json`.

```bash theme={null}
canton-agent-wallet create --relay-url https://facilitator.ftptech.xyz
# wallet ready (canton:mainnet)
#   party:   my-agent::1220...
#   fund me: send CC to that party id, then run: canton-agent-wallet claim
#   keyfile: ~/.canton-agent/wallet.json  <- back it up
```

### Address

Print the party ID. Use this to receive CC from a wallet or another agent.

```bash theme={null}
canton-agent-wallet address
# my-agent::1220...
```

### Balance

```bash theme={null}
canton-agent-wallet balance --relay-url https://facilitator.ftptech.xyz
# <amount> CC  (<n> holdings)
```

### Claim

Accept incoming CC transfers (e.g. the initial funding from a wallet):

```bash theme={null}
canton-agent-wallet claim --relay-url https://facilitator.ftptech.xyz
# claimed 1 incoming transfer(s)
```

### Pay

Fetch a URL, automatically paying any x402 `402` challenge:

```bash theme={null}
canton-agent-wallet pay --relay-url https://facilitator.ftptech.xyz https://api.example.com/resource
```

For POST endpoints (e.g. LLM inference with a request body), use `makePayingFetch` from the SDK instead.

### Withdraw

Send CC to any Canton party:

```bash theme={null}
# Partial amount
canton-agent-wallet withdraw --relay-url https://facilitator.ftptech.xyz --to "recipient::1220..." --amount 5.0000000000

# Full balance
canton-agent-wallet withdraw --relay-url https://facilitator.ftptech.xyz --to "recipient::1220..."
```

`--amount` is in **CC (decimal)**, so `5.0` = 5 CC. This differs from `PaymentRequirements.amount` in the 402 challenge, which is in **atomic units** (10^10 per CC).

### Registry tokens (e.g. USDCx)

The wallet handles CIP-56 registry tokens (like USDCx) alongside Canton Coin. Two
independent opt-ins keep them safe by default:

* **Trust** a token's registrar to *verify and receive* it — set
  `CANTON_AGENT_REGISTRY_TRUSTED_PARTIES` (USDCx's registrar is trusted out of the
  box). An untrusted registrar's incoming transfers are skipped by `claim`.
* **Consent** to *spend* a token — set
  `CANTON_AGENT_PAYABLE_INSTRUMENTS="<registrar>|USDCx"`. The default is Canton
  Coin only, so a merchant cannot make you pay in a token you did not opt into.

```bash theme={null}
# See every instrument held (CC + registry tokens)
canton-agent-wallet balance

# Receive USDCx one-shot (direct): self-provision your own registry preapproval
canton-agent-wallet preapproval --admin <registrar>::1220... --id USDCx

# Accept a pending incoming USDCx transfer (registrar must be trusted)
canton-agent-wallet claim

# Pay an x402 endpoint priced in USDCx (opt in to spending it first)
export CANTON_AGENT_PAYABLE_INSTRUMENTS="<registrar>::1220...|USDCx"
canton-agent-wallet pay https://api.example.com/resource

# Withdraw a registry token instead of CC
canton-agent-wallet withdraw --to "recipient::1220..." --amount 1.0 --admin <registrar>::1220... --id USDCx
```

`--admin`/`--id` always travel together. `pay` needs no `--admin`/`--id` — the
instrument comes from the merchant's 402 challenge; you only opt in to spending it.

### Export / Import

Back up and restore the wallet key:

```bash theme={null}
# Export (prints private key; store securely)
canton-agent-wallet export > my-agent.pem

# Restore on a new machine
canton-agent-wallet import --relay-url https://facilitator.ftptech.xyz --key-file my-agent.pem
```

## Environment Variables

| Variable                                | Description                                                                                       |
| --------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `CANTON_AGENT_RELAY_URL`                | Facilitator URL (alternative to `--relay-url` on every command)                                   |
| `CANTON_AGENT_NETWORK`                  | Canton network (default: `canton:testnet`; set to `canton:mainnet` for mainnet)                   |
| `CANTON_AGENT_API_KEY`                  | API key if the facilitator requires one                                                           |
| `CANTON_AGENT_REGISTRY_TRUSTED_PARTIES` | Registrars to trust for verifying/claiming CIP-56 tokens (USDCx is built in)                      |
| `CANTON_AGENT_PAYABLE_INSTRUMENTS`      | Registry tokens you consent to **spend**, e.g. `"<registrar>\|USDCx"` (default: Canton Coin only) |
| `HTTPS_PROXY`                           | HTTP proxy for outbound requests                                                                  |

<Warning>
  `CANTON_AGENT_NETWORK` defaults to `canton:testnet`. Always set it to `canton:mainnet` when connecting to mainnet.
</Warning>

## SDK Usage

For programmatic use (e.g. embedding payments in a backend service):

```typescript theme={null}
import { makePayingFetch } from "@ftptech/canton-agent-wallet";

// Creates or loads wallet, resolves Canton party
const payFetch = await makePayingFetch({
  relayUrl: "https://facilitator.ftptech.xyz",
  network:  "canton:mainnet",
});

// Drop-in fetch replacement; 402 is detected, paid, and retried automatically
const res = await payFetch("https://api.example.com/resource", {
  method:  "POST",
  headers: { "Content-Type": "application/json" },
  body:    JSON.stringify({ prompt: "hello" }),
});
const data = await res.json();
```

## Wallet File

The wallet is stored at `~/.canton-agent/wallet.json` with permissions `0600`. It contains the Ed25519 private key and the allocated Canton party ID. **Back it up; losing the file loses access to the funds it holds.**

## How Payment Works

Payment settles in a single transaction. When the agent pays an x402-gated URL it signs — but does **not** submit — a `TransferFactory_Transfer` (CIP-56 Token Standard transfer instruction) naming the merchant as receiver:

1. `POST /v2/interactive-submission/prepare` → gets `preparedTransactionHash`
2. Agent signs the hash with its Ed25519 key (does **not** execute/submit)
3. Retries the original request with `PAYMENT-SIGNATURE: <base64 PaymentPayload>` carrying the payer-signed transfer inline (the prepared transaction plus the signature)

The merchant's server then calls the facilitator's `/verify` and `/settle`. The facilitator **relays** the payer-signed transfer — it submits the transaction and pays the sequencer traffic fee. Because the merchant holds a live `TransferPreapproval`, the transfer resolves directly and moves CC from the payer's own holdings to the merchant in one transaction. The agent never pays gas; the facilitator never holds custody and signs nothing on the payer's behalf.

## First-Request Latency

The first payment after a cold start is slower than subsequent ones. SV Scan caches `AmuletRules` (5 min TTL) and `OpenMiningRound` (30 s TTL); these caches are empty on startup, so the first request warms them. Subsequent payments typically complete in 10 to 25 seconds on Canton mainnet.
