diff --git a/docs-main/sdks-tools/development-tools/x402-agent.mdx b/docs-main/sdks-tools/development-tools/x402-agent.mdx
new file mode 100644
index 00000000..2fbf6cb2
--- /dev/null
+++ b/docs-main/sdks-tools/development-tools/x402-agent.mdx
@@ -0,0 +1,155 @@
+---
+title: "x402 Agent Integration"
+description: "Make automated Canton Coin 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 LOCKs Canton Coin in an allocation on the ledger (naming the merchant as receiver and the facilitator as executor), attaches the payment proof, and retries automatically. The facilitator then settles the locked funds directly to the merchant.
+
+## Install
+
+```bash
+npm i -g @ftptech/canton-agent-wallet@latest
+```
+
+
+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
+export CANTON_AGENT_NETWORK=canton:mainnet
+```
+
+
+## CLI Commands
+
+### Create a wallet
+
+Generates an Ed25519 key pair, allocates a Canton party, and saves the wallet to `~/.canton-agent/wallet.json`.
+
+```bash
+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
+canton-agent-wallet address
+# my-agent::1220...
+```
+
+### Balance
+
+```bash
+canton-agent-wallet balance --relay-url https://facilitator.ftptech.xyz
+# CC ( holdings)
+```
+
+### Claim
+
+Accept incoming CC transfers (e.g. the initial funding from a wallet):
+
+```bash
+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
+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
+# 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).
+
+### Export / Import
+
+Back up and restore the wallet key:
+
+```bash
+# 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 |
+| `HTTPS_PROXY` | HTTP proxy for outbound requests |
+
+
+`CANTON_AGENT_NETWORK` defaults to `canton:testnet`. Always set it to `canton:mainnet` when connecting to mainnet.
+
+
+## SDK Usage
+
+For programmatic use (e.g. embedding payments in a backend service):
+
+```typescript
+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 is a two-transaction delivery-versus-payment (DVP). When the agent pays an x402-gated URL, it first LOCKs funds by exercising `AllocationFactory_Allocate` on the Canton ledger (receiver = merchant, executor = facilitator):
+
+1. `POST /v2/interactive-submission/prepare` → gets `preparedTransactionHash`
+2. Agent signs the hash with its Ed25519 key
+3. `POST /v2/interactive-submission/execute` with the signature
+4. Agent resolves the `allocationCid` from the resulting `updateId`
+5. Retries the original request with `PAYMENT-SIGNATURE: `
+
+That is the **allocate** leg. The merchant's server then calls the facilitator's `/verify` and `/settle`, and the facilitator performs the **execute** leg: `DirectSettlementConsent_Execute`, a single sponsored-gas transaction that moves the locked CC directly to the merchant and archives the allocation. The agent never pays gas and the facilitator never holds custody.
+
+## 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.
+
+## Related Pages
+
+- [x402 HTTP Payments](/sdks-tools/development-tools/x402-payments) -- Protocol overview and error codes
+- [x402 Merchant Integration](/sdks-tools/development-tools/x402-merchant) -- How to gate your own API endpoints
diff --git a/docs-main/sdks-tools/development-tools/x402-merchant.mdx b/docs-main/sdks-tools/development-tools/x402-merchant.mdx
new file mode 100644
index 00000000..0d0ff19a
--- /dev/null
+++ b/docs-main/sdks-tools/development-tools/x402-merchant.mdx
@@ -0,0 +1,229 @@
+---
+title: "x402 Merchant Integration"
+description: "Gate your Express or Next.js API endpoints behind Canton Coin payments with x402 middleware."
+---
+
+You are a **merchant** if you have an HTTP API and want to charge Canton Coin (CC) per request. Your callers (agents, wallets, or any x402-compatible client) pay before your handler runs.
+
+**You do not need a CC balance.** You are receiving, not sending. Settlement uses the `allocation-direct` method: the payer LOCKs funds in an allocation naming you as receiver, and the facilitator settles it directly to your party in a single transaction.
+
+## Before You Start
+
+You need:
+
+- A Canton party ID (your receiver identity on Canton mainnet)
+- A one-time `MerchantConsent` onboarded for your facilitator (see Step 1); the `allocation-direct` path has no `TransferPreapproval`
+- A facilitator URL, party ID, and synchronizer ID (Step 2)
+
+## Step 1: Onboard for Direct Settlement
+
+Before any agent can pay you, your party needs a standing `MerchantConsent` for your facilitator. This is a once-total authorization; it **moves no funds** and is not per-request. Without it, `/settle` returns `success:false` at the consent-resolution step (the `{sender, merchant}` pair isn't onboarded) and the middleware answers your callers with a 402 instead of the resource.
+
+Install the CLI:
+
+```bash
+npm i -g @ftptech/canton-agent-wallet # provides the `canton-agent-wallet` binary
+```
+
+Pick the mode that matches how your party is hosted.
+
+### Mode A: external-party merchant
+
+Your party is an Ed25519 self-custody wallet managed through the relay.
+
+```bash
+# 1. create the wallet once (idempotent)
+canton-agent-wallet create --relay-url https://facilitator.ftptech.xyz
+
+# 2. sign your standing MerchantConsent
+canton-agent-wallet merchant-onboard \
+ --facilitator "::1220..." \
+ --synchronizer "global-domain::1220..."
+# → prints: MerchantConsent updateId: <...>
+```
+
+`--facilitator` / `--synchronizer` also read from `CANTON_X402_FACILITATOR` / `CANTON_SYNCHRONIZER_ID`.
+
+### Mode B: hosted-party merchant
+
+Your party lives on your OWN Canton node and authorizes directly on its JSON Ledger API (`actAs:[merchant]`), with no wallet, relay, or Ed25519 key.
+
+> One-time: upload + vet the [`x402-direct` DAR](https://github.com/Denend/x402-dar) on your participant first (the `MerchantConsent` template lives there). External (Mode A) parties don't need this.
+
+```bash
+# OIDC secrets come from ENV ONLY (never on argv, which is visible in `ps`/shell history)
+export OIDC_TOKEN_ENDPOINT=...
+export OIDC_CLIENT_ID=...
+export OIDC_CLIENT_SECRET=...
+export LEDGER_API_AUDIENCE=...
+# optional: export OIDC_SCOPE=...
+
+canton-agent-wallet merchant-onboard-hosted \
+ --party "::1220..." \
+ --facilitator "::1220..." \
+ --participant-url https://your-node:7575 \
+ --synchronizer "global-domain::1220..." \
+ --user-id your-ledger-user
+# → "MerchantConsent created (cid ...)"
+# idempotent: re-run → "already onboarded, nothing to do"
+```
+
+`--participant-url` / `--synchronizer` / `--user-id` fall back to `CANTON_PARTICIPANT_URL` / `CANTON_SYNCHRONIZER_ID` / `CANTON_USER_ID`. OIDC values are read from ENV only, never as flags.
+
+## Step 2: Get Facilitator Parameters
+
+Call `GET /supported` on your facilitator to get the values you need:
+
+```bash
+curl https://facilitator.ftptech.xyz/supported
+```
+
+```json
+{
+ "kinds": [{
+ "x402Version": 2,
+ "scheme": "exact",
+ "network": "canton:mainnet",
+ "extra": {
+ "transferMethods": ["allocation-direct"],
+ "synchronizerId": "global-domain::1220..."
+ }
+ }],
+ "signers": {
+ "canton:*": ["::1220..."]
+ }
+}
+```
+
+From this response: `signers["canton:*"][0]` is your `feePayer`, and `extra.synchronizerId` is your synchronizer. Get the DSO party id (for `instrumentId.admin`) from your Canton Scan API.
+
+## Step 3: Install
+
+```bash
+# Express
+npm i @ftptech/x402-canton-core @ftptech/x402-canton-express
+
+# Next.js App Router
+npm i @ftptech/x402-canton-core @ftptech/x402-canton-next
+```
+
+## Step 4: Define PaymentRequirements
+
+```typescript
+import type { PaymentRequirements } from "@ftptech/x402-canton-core";
+
+const paymentReq: PaymentRequirements = {
+ scheme: "exact",
+ network: "canton:mainnet",
+ amount: "10000000000", // atomic units (1 CC = 10^10 units)
+ asset: "CC",
+ payTo: "::1220...", // your Canton party id; CC lands here
+ maxTimeoutSeconds: 120,
+ extra: {
+ assetTransferMethod: "allocation-direct",
+ feePayer: "::1220...",
+ synchronizerId: "global-domain::1220...",
+ instrumentId: { admin: "::1220...", id: "Amulet" },
+ allocateBeforeSeconds: 30,
+ settleBeforeSeconds: 60,
+ // memo: "invoice-2024-001" // optional reconciliation tag (not validated)
+ },
+};
+```
+
+**Amount format:** an integer string of atomic units (1 CC = 10^10 units). The facilitator compares by value (BigInt atomic units), so `"10000000000"` = 1 CC and `"100000000"` = 0.01 CC; a mismatch returns `invalid_exact_canton_amount_mismatch`.
+
+**Field notes:**
+
+- `feePayer`: the facilitator party (== `settlement.executor` in the allocation). Clients MUST NOT alter it.
+- `instrumentId`: Canton Coin is `{ admin: "", id: "Amulet" }`. The direct path settles Amulet/CC only.
+- `allocateBeforeSeconds` / `settleBeforeSeconds`: relative deadlines (seconds from request time). `settleBeforeSeconds` MUST be strictly greater than `allocateBeforeSeconds`.
+- `memo` (optional): a string the client stamps into the allocation's settlement metadata; the facilitator does not validate it.
+
+> These field names follow the x402-ENVELOPE convention. `synchronizerId` may be omitted; clients fall back to the value advertised by `GET /supported`.
+
+## Step 5: Add Middleware
+
+### Express
+
+```typescript
+import express from "express";
+import { cantonPaymentMiddleware } from "@ftptech/x402-canton-express";
+
+const app = express();
+app.use(express.json());
+
+app.use(
+ cantonPaymentMiddleware({
+ facilitatorUrl: "https://facilitator.ftptech.xyz",
+ routes: {
+ "POST /api/data": {
+ accepts: [paymentReq],
+ description: "Access to premium data", // shown to clients in 402 body
+ mimeType: "application/json",
+ },
+ "GET /api/data": { accepts: [paymentReq] },
+ },
+ })
+);
+
+// Handler runs only after payment is verified and settled
+app.post("/api/data", (req, res) => {
+ res.json({ result: "..." });
+});
+
+app.listen(3000);
+```
+
+Route keys use `"METHOD /path"` format, matched exactly against `${req.method} ${req.path}`. Unregistered routes pass through ungated.
+
+### Next.js App Router
+
+```typescript
+// app/api/data/route.ts
+import { withCantonPayment } from "@ftptech/x402-canton-next";
+
+export const POST = withCantonPayment(
+ async (req) => Response.json({ result: "..." }),
+ {
+ accepts: [paymentReq],
+ facilitatorUrl: "https://facilitator.ftptech.xyz",
+ }
+);
+```
+
+## Step 6: Verify It Works
+
+Call your gated endpoint without payment:
+
+```bash
+curl -si https://your-api.com/api/data \
+ -H "Content-Type: application/json" \
+ -d '{}'
+```
+
+Expected:
+```
+HTTP/2 402
+payment-required:
+```
+
+Decode to confirm your requirements are correct:
+
+```bash
+echo "" | base64 -d | jq '.accepts[0]'
+```
+
+You should see your `amount`, `payTo`, and `feePayer` values.
+
+## Security Notes
+
+- **Your `accepts[]` is authoritative.** The middleware ignores any amount the client claims. A client cannot request a 1 CC resource for 0.01 CC by tampering with the payment payload.
+- **The proven payer is on-ledger.** The facilitator binds the payer to the allocation's `transferLeg.sender`, not to anything the client puts in the payload, so a spoofed `payer` field cannot impersonate.
+- **Settlement happens before your handler.** If your handler throws after a successful `/settle`, the payer already paid. Handle errors gracefully; do not retry settlement.
+- **Keep `payTo` correct.** CC goes to whatever `payTo` says. If your party ID changes, update `paymentReq` AND re-run onboarding (Step 1) for the new party.
+
+## Related Pages
+
+- [x402 HTTP Payments](/sdks-tools/development-tools/x402-payments) -- Protocol overview and facilitator setup
+- [x402 Agent Integration](/sdks-tools/development-tools/x402-agent) -- How your callers pay (the payer side)
diff --git a/docs-main/sdks-tools/development-tools/x402-payments.mdx b/docs-main/sdks-tools/development-tools/x402-payments.mdx
new file mode 100644
index 00000000..5f5eda78
--- /dev/null
+++ b/docs-main/sdks-tools/development-tools/x402-payments.mdx
@@ -0,0 +1,134 @@
+---
+title: "x402 HTTP Payments"
+description: "Gate any HTTP endpoint behind Canton Coin payments using the x402 protocol and the exact scheme."
+---
+
+The [x402 protocol](https://x402.org) is an HTTP payment standard built around the `402 Payment Required` status code. A server responds with payment requirements; the client pays on-chain and retries. There are no API keys and no billing accounts; the payment itself is the credential.
+
+On Canton Network, x402 uses the `exact` scheme with the `allocation-direct` settlement method (a CIP-56 delivery-versus-payment flow). The client LOCKs Canton Coin in an allocation naming the merchant as receiver and the facilitator as executor; the facilitator then settles directly to the merchant in a single sponsored-gas transaction. There is no escrow, no facilitator custody, and no per-merchant preapproval.
+
+## How It Works
+
+This is a two-transaction DVP: the payer's **allocate** (lock) and the facilitator's **execute** (settle).
+
+```mermaid
+sequenceDiagram
+ participant C as Client / Agent
+ participant R as Resource Server
+ participant F as Facilitator
+ participant L as Canton Ledger
+
+ C->>R: GET /resource
+ R->>C: 402 Payment Required
(PAYMENT-REQUIRED header)
+ C->>L: AllocationFactory_Allocate
(lock funds; receiver = merchant,
executor = facilitator)
+ C->>R: GET /resource + PAYMENT-SIGNATURE
+ R->>F: POST /verify
+ F-->>R: VerifyResponse (valid)
+ R->>F: POST /settle
+ F->>L: DirectSettlementConsent_Execute
(1 tx, CC lands on merchant directly)
+ L-->>F: updateId
+ F-->>R: SettlementResponse (updateId)
+ R->>C: 200 + PAYMENT-RESPONSE
+```
+
+The allocation's `executor` is the facilitator, so only the facilitator can exercise the settlement. The funds are locked the moment the allocation is created. The facilitator never holds custody and never advances its own funds; it pays only the sequencer traffic (gas) as executor.
+
+## Scheme: `exact`
+
+| Field | Value |
+|---|---|
+| `scheme` | `exact` |
+| `asset` | `CC` |
+| `assetTransferMethod` | `allocation-direct` |
+| Networks | `canton:mainnet`, `canton:testnet` |
+
+### PaymentRequirements structure
+
+```json
+{
+ "scheme": "exact",
+ "network": "canton:mainnet",
+ "amount": "10000000000",
+ "asset": "CC",
+ "payTo": "::1220...",
+ "maxTimeoutSeconds": 60,
+ "extra": {
+ "assetTransferMethod": "allocation-direct",
+ "feePayer": "::1220...",
+ "synchronizerId": "global-domain::1220...",
+ "instrumentId": { "admin": "::1220...", "id": "Amulet" },
+ "allocateBeforeSeconds": 30,
+ "settleBeforeSeconds": 60,
+ "memo": "invoice-2024-001"
+ }
+}
+```
+
+- `amount` is an integer string of **atomic units** (1 CC = 10^10 units), so `"10000000000"` = 1 CC. The facilitator compares by value (BigInt atomic units), so a 10×/0.1× error provably never folds, but the form must be a valid integer string.
+- `feePayer` is the facilitator party; it becomes `settlement.executor` in the allocation. Clients MUST NOT alter it.
+- `instrumentId` is the Canton Coin instrument `{ admin: "", id: "Amulet" }`. The direct path settles Amulet/CC only.
+- `allocateBeforeSeconds` / `settleBeforeSeconds` are relative deadlines (seconds from request time) the client uses to compute the absolute `allocateBefore` / `settleBefore`. `settleBeforeSeconds` MUST be strictly greater than `allocateBeforeSeconds`.
+- `memo` (optional) is a seller-defined string the client stamps into the allocation's settlement metadata; the facilitator does not validate it.
+
+> `feePayer`, `synchronizerId`, and `instrumentId.admin` (the DSO party) are deployment values. Get `feePayer` and `synchronizerId` from `GET /supported` on your facilitator; get the DSO party id from your Canton Scan API.
+
+## The Facilitator
+
+A facilitator is a service that bridges x402 and the Canton ledger. It holds a Canton party, reads the locked `Allocation` from its ACS, resolves or mints the standing `DirectSettlementConsent` for the `{sender, merchant}` pair, and exercises `DirectSettlementConsent_Execute` alone, paying the merchant directly in one transaction. The facilitator sponsors sequencer traffic fees; the merchant pays nothing per-request.
+
+The facilitator exposes two endpoints that the resource server calls:
+
+- `POST /verify` validates the locked `Allocation` against `PaymentRequirements`
+- `POST /settle` exercises `DirectSettlementConsent_Execute` and returns the ledger `updateId`
+
+Use `GET /supported` on any facilitator to discover its party ID, advertised method, and the networks it serves:
+
+```json
+{
+ "kinds": [{
+ "x402Version": 2,
+ "scheme": "exact",
+ "network": "canton:mainnet",
+ "extra": {
+ "transferMethods": ["allocation-direct"],
+ "synchronizerId": "global-domain::1220..."
+ }
+ }],
+ "signers": {
+ "canton:*": ["::1220..."]
+ }
+}
+```
+
+Because `/supported` advertises `synchronizerId`, a 402 `extra` MAY omit it and clients will fall back to this value.
+
+> Hosted-party merchants must upload + vet the [`x402-direct` DAR](https://github.com/Denend/x402-dar) on their own participant; external (relay-hosted) parties don't.
+
+## Replay Protection
+
+Canton provides native replay protection. `DirectSettlementConsent_Execute` runs `Allocation_ExecuteTransfer`, which archives the `AmuletAllocation`; a second execute on the same `allocationCid` fails at the ledger. The facilitator also records each settled allocation in a single-use store, so a repeat `/settle` for the same allocation is rejected with `invalid_exact_canton_payment_already_settled` before any submit. Treat that code as confirmation that the original settlement succeeded.
+
+## Error Codes
+
+| Code | Meaning |
+|---|---|
+| `invalid_exact_canton_missing_proof` | Payload carried neither `allocationCid` nor `allocationInstructionCid` |
+| `invalid_exact_canton_allocation_pending` | Only an `allocationInstructionCid` was supplied; funds are not yet in an executable lock |
+| `invalid_exact_canton_allocation_not_found` | `allocationCid` is not in the facilitator's ACS: never created, already settled, or wrong cid |
+| `invalid_exact_canton_amount_mismatch` | `Allocation.transferLeg.amount` ≠ `PaymentRequirements.amount` (by value) |
+| `invalid_exact_canton_merchant_mismatch` | Allocation receiver ≠ `payTo` |
+| `invalid_exact_canton_instrument_id_mismatch` | Allocation instrument ≠ `extra.instrumentId` (or a non-Amulet instrument was locked) |
+| `invalid_exact_canton_executor_mismatch` | Allocation executor ≠ `feePayer` (the facilitator) |
+| `invalid_exact_canton_expired` | `settleBefore` is past or within the 5-second safety margin, or `allocateBefore` ≥ `settleBefore` |
+| `invalid_exact_canton_holding_locked` | The backing lock is held by a party other than the instrument admin (DSO) |
+| `invalid_exact_canton_self_payment` | The proven payer is the facilitator / fee payer; the facilitator must never move its own funds |
+| `invalid_exact_canton_execute_failed` | `DirectSettlementConsent_Execute` rolled back, or committed without moving funds to the merchant |
+| `invalid_exact_canton_payment_already_settled` | This allocation was already settled (replay) |
+| `invalid_exact_canton_insufficient_balance` | Optional balance check: the proven payer's holdings are below the required amount |
+| `unexpected_canton_ledger_error` | Network mismatch, missing onboarding/consent, or a Scan/ledger error not covered above |
+
+## Related Pages
+
+- [x402 Merchant Integration](/sdks-tools/development-tools/x402-merchant) -- Add x402 to your Express or Next.js API
+- [x402 Agent Integration](/sdks-tools/development-tools/x402-agent) -- Make x402 payments from an automated agent
+- [Wallet Gateway](/integrations/wallet-gateway/download) -- Canton wallet integration for end users