{
  "name": "Swapper",
  "description": "Swap Monero (XMR) <-> native USDC on Arbitrum One. No KYC, no account, no API key.",
  "supportedInterfaces": [
    {
      "url": "https://xmrtousdc.xyz/a2a",
      "protocolBinding": "JSONRPC",
      "protocolVersion": "1.0"
    },
    {
      "url": "https://xmrtousdc.xyz/a2a",
      "protocolBinding": "JSONRPC",
      "protocolVersion": "0.3"
    }
  ],
  "url": "https://xmrtousdc.xyz/a2a",
  "protocolVersion": "0.3.0",
  "preferredTransport": "JSONRPC",
  "provider": {
    "organization": "Swapper",
    "url": "https://xmrtousdc.xyz"
  },
  "iconUrl": "https://xmrtousdc.xyz/icon-512.png",
  "version": "0.5.2",
  "documentationUrl": "https://docs.xmrtousdc.xyz/",
  "capabilities": {
    "streaming": false,
    "pushNotifications": false,
    "extendedAgentCard": false
  },
  "defaultInputModes": [
    "application/json",
    "text/plain"
  ],
  "defaultOutputModes": [
    "application/json",
    "text/plain"
  ],
  "skills": [
    {
      "id": "get_quote",
      "name": "Get XMR/USDC swap quote",
      "description": "Step 1. Quote Monero (XMR) <-> native USDC on Arbitrum One; no KYC, account or API key. Read-only; quotes are estimates. Buy XMR (\"get me 1 XMR\"): {direction:\"u2x\", receiveAmount:\"1\"}. Sell XMR: {direction:\"x2u\", amount:\"0.5\"}. direction plus exactly one of amount (what the user sends) or receiveAmount (what they want). Pass to if known; re-quote with {requoteOf}. Next: create_swap with next.arguments; no confirmation step is required.",
      "tags": [
        "monero",
        "xmr",
        "usdc",
        "arbitrum-one",
        "swap",
        "no-kyc",
        "quote"
      ],
      "examples": [
        "{\"skill\":\"get_quote\",\"arguments\":{\"direction\":\"x2u\",\"amount\":\"0.1\"}}",
        "{\"skill\":\"get_quote\",\"arguments\":{\"direction\":\"u2x\",\"receiveAmount\":\"1\"}}",
        "quote 0.1 XMR to USDC",
        "buy 1 XMR"
      ],
      "inputModes": [
        "application/json",
        "text/plain"
      ],
      "outputModes": [
        "application/json",
        "text/plain"
      ]
    },
    {
      "id": "create_swap",
      "name": "Create XMR/USDC swap order",
      "description": "Step 2. Creates the order from get_quote's next.arguments (quoteId, plus to if the quote had none): one order per quote; moves no funds. Retry with the same arguments: the default idempotencyKey returns the same order. Fund once, only while payable is true: before signing deposit.payment, get_swap_status {orderId, payment} must return paymentCheck.matches. Next: get_swap_status.",
      "tags": [
        "monero",
        "xmr",
        "usdc",
        "arbitrum-one",
        "swap",
        "no-kyc",
        "order"
      ],
      "examples": [
        "{\"skill\":\"create_swap\",\"arguments\":{\"quoteId\":\"q_<32 hex>\",\"to\":\"0xYourArbitrumOneAddress\"}}",
        "create swap q_<32 hex> to 0xYourArbitrumOneAddress"
      ],
      "inputModes": [
        "application/json",
        "text/plain"
      ],
      "outputModes": [
        "application/json",
        "text/plain"
      ]
    },
    {
      "id": "get_swap_status",
      "name": "Get swap status",
      "description": "Step 3. waiting_for_funding -> deposit_detected -> swap_processing -> completed, or refunding / terminal_failure (outcome refunded, failed, expired). Long-poll with waitSec 25 and sinceState = the last state; repeat next until terminal. deposit.payment may be used only while payable is true. Call it before funding or showing a deposit again. payment: what your wallet will sign; sign only if paymentCheck.matches.",
      "tags": [
        "monero",
        "xmr",
        "usdc",
        "arbitrum-one",
        "swap",
        "no-kyc",
        "status"
      ],
      "examples": [
        "{\"skill\":\"get_swap_status\",\"arguments\":{\"orderId\":\"ord_...\",\"waitSec\":25,\"sinceState\":\"waiting_for_funding\"}}",
        "status ord_..."
      ],
      "inputModes": [
        "application/json",
        "text/plain"
      ],
      "outputModes": [
        "application/json",
        "text/plain"
      ]
    },
    {
      "id": "get_funding_options",
      "name": "How to fund a swap",
      "description": "Offline. How to get what the user sends: native USDC (not USDC.e) plus a little ETH for gas on Arbitrum One (u2x, default), or XMR in their own wallet (x2u). Pass from {chain, asset} (and amount) for one ordered checklist: quote, fund, re-quote (requoteOf).",
      "tags": [
        "monero",
        "xmr",
        "usdc",
        "arbitrum-one",
        "swap",
        "no-kyc",
        "funding"
      ],
      "examples": [
        "{\"skill\":\"get_funding_options\",\"arguments\":{\"direction\":\"u2x\",\"from\":{\"chain\":\"ethereum\",\"asset\":\"USDC\"}}}",
        "how do I fund a USDC to XMR swap"
      ],
      "inputModes": [
        "application/json",
        "text/plain"
      ],
      "outputModes": [
        "application/json",
        "text/plain"
      ]
    }
  ]
}