{
  "openapi": "3.1.0",
  "info": {
    "title": "AFK Crypto API",
    "description": "AFK Crypto - Non-custodial wallet automation. Simple REST APIs for EVM and Solana.",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.afkcrypto.com/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "apiKeyAuth": []
    }
  ],
  "paths": {
    "/wallets/balances": {
      "get": {
        "summary": "Get balances for caller wallet",
        "description": "Retrieve native balance and optionally token balances for the caller's wallet on a chain.",
        "parameters": [
          { "name": "chain", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Chain slug (e.g., base, base-sepolia, solana, solana-devnet)" },
          { "name": "address", "in": "query", "required": false, "schema": { "type": "string" }, "description": "Optional wallet address; defaults to caller's default wallet for the chain" },
          { "name": "tokens", "in": "query", "required": false, "schema": { "type": "string" }, "description": "CSV of token addresses (EVM) or mints (Solana) to include (max 50)" },
          { "name": "includeZero", "in": "query", "required": false, "schema": { "type": "boolean" }, "description": "Include zero balances (default false)" },
          { "name": "fresh", "in": "query", "required": false, "schema": { "type": "boolean" }, "description": "Bypass short-lived cache (default false)" }
        ],
        "responses": {
          "200": {
            "description": "Balances response",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetBalancesResponse" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } }, "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } } },
          "404": { "description": "Wallet not found or not owned", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } }, "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } } },
          "429": { "description": "Rate limited", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } }, "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" }, "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds until next window" } } },
          "default": { "$ref": "#/components/responses/ErrorResponse" }
        }
      }
    },
    
    "/wallets": {
      "get": {
        "summary": "List caller wallets",
        "description": "Defaults to all wallets; default wallets first.",
        "parameters": [
          {
            "name": "chain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["ethereum", "solana"]
            },
            "description": "Filter by chain type"
          },
          {
            "name": "defaultOnly",
            "in": "query",
            "required": false,
            "schema": { "type": "boolean" },
            "description": "Return only default wallets."
          },
          {
            "name": "automationOnly",
            "in": "query",
            "required": false,
            "schema": { "type": "boolean" },
            "description": "Return only wallets with automation enabled."
          }
        ],
        "responses": {
          "200": {
            "description": "Wallet list",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/GetWalletsResponse" }
              }
            },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "403": {
            "description": "Forbidden",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "401": {
            "description": "Unauthorized",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "429": {
            "description": "Rate limited",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": {
              "x-request-id": { "$ref": "#/components/headers/XRequestId" },
              "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds until next window" }
            }
          },
          "default": { "$ref": "#/components/responses/ErrorResponse" }
        }
      }
    },
    "/tx/{id}": {
      "get": {
        "summary": "Get transaction by id",
        "description": "Look up a transaction created by AFK for the authenticated user.",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "AFK transaction id." }
        ],
        "responses": {
          "200": {
            "description": "Transaction",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Transaction" }
              }
            },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "403": {
            "description": "Forbidden",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "404": {
            "description": "Not found",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "401": {
            "description": "Unauthorized",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "429": {
            "description": "Rate limited",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": {
              "x-request-id": { "$ref": "#/components/headers/XRequestId" },
              "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds until next window" }
            }
          },
          "default": { "$ref": "#/components/responses/ErrorResponse" }
        }
        }
      },
    "/send": {
      "post": {
        "summary": "Send native assets and tokens",
        "description": "Send native and token assets on EVM and Solana.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Provide a unique Idempotency-Key per user to ensure single submission."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": { "schema": { "$ref": "#/components/schemas/SendRequest" } }
          }
        },
        "responses": {
          "200": {
            "description": "Submission accepted",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/SubmissionResponse" } }
            },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "403": {
            "description": "Forbidden",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "401": {
            "description": "Unauthorized",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "429": {
            "description": "Rate limited",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": {
              "x-request-id": { "$ref": "#/components/headers/XRequestId" },
              "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds until next window" }
            }
          },
          "default": { "$ref": "#/components/responses/ErrorResponse" }
        }
      }
    },
    "/token/approve": {
      "post": {
        "summary": "Approve ERC20 allowance (EVM)",
        "description": "Approve ERC20 allowance on EVM.",
        "parameters": [
          { "name": "Idempotency-Key", "in": "header", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "Provide a unique Idempotency-Key per user to ensure single submission." }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApproveRequest" } } }
        },
        "responses": {
          "200": {
            "description": "Submission accepted",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/SubmissionResponse" } }
            },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "403": {
            "description": "Forbidden",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "401": {
            "description": "Unauthorized",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "429": {
            "description": "Rate limited",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": {
              "x-request-id": { "$ref": "#/components/headers/XRequestId" },
              "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds until next window" }
            }
          },
          "default": { "$ref": "#/components/responses/ErrorResponse" }
        }
      }
    },
    "/contracts/send": {
      "post": {
        "summary": "Send contract transaction (EVM)",
        "description": "Send a generic EVM contract transaction.",
        "parameters": [
          { "name": "Idempotency-Key", "in": "header", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "Provide a unique Idempotency-Key per user to ensure single submission." }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContractsSendRequest" } } }
        },
        "responses": {
          "200": {
            "description": "Submission accepted",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/SubmissionResponse" } }
            },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "403": {
            "description": "Forbidden",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "401": {
            "description": "Unauthorized",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "429": {
            "description": "Rate limited",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": {
              "x-request-id": { "$ref": "#/components/headers/XRequestId" },
              "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds until next window" }
            }
          },
          "default": { "$ref": "#/components/responses/ErrorResponse" }
        }
      }
    },
    "/trade/quote": {
      "post": {
        "summary": "Get trade quote (EVM + Solana)",
        "description": "Get swap quotes on EVM and Solana; may include router and approval info.",
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TradeQuoteRequest" } } }
        },
        "responses": {
          "200": {
            "description": "Quote response",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TradeQuoteResponse" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "403": {
            "description": "Forbidden",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "401": {
            "description": "Unauthorized",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "429": {
            "description": "Rate limited",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": {
              "x-request-id": { "$ref": "#/components/headers/XRequestId" },
              "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds until next window" }
            }
          },
          "default": { "$ref": "#/components/responses/ErrorResponse" }
        }
      }
    },
    "/trade/swap": {
      "post": {
        "summary": "Execute trade via aggregator (EVM + Solana)",
        "description": "Execute a token swap on EVM or Solana using inline build.",
        "parameters": [
          { "name": "Idempotency-Key", "in": "header", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "Provide a unique Idempotency-Key per user to ensure single submission." }
        ],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TradeSwapRequest" } } }
        },
        "responses": {
          "200": {
            "description": "Submission accepted",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SubmissionResponse" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "403": {
            "description": "Forbidden",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "401": {
            "description": "Unauthorized",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
          },
          "429": {
            "description": "Rate limited",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } } },
            "headers": {
              "x-request-id": { "$ref": "#/components/headers/XRequestId" },
              "Retry-After": { "schema": { "type": "integer" }, "description": "Seconds until next window" }
            }
          },
          "default": { "$ref": "#/components/responses/ErrorResponse" }
        }
      }
    }
  },
  "components": {
    "headers": {
      "XRequestId": {
        "description": "Unique request identifier",
        "schema": { "type": "string" }
      }
    },
    "schemas": {
      "WalletBalance": {
        "type": "object",
        "properties": {
          "chainType": { "type": "string", "enum": ["ethereum", "solana"], "description": "Chain family for the balance." },
          "chainId": { "type": "integer", "description": "EVM: numeric chainId; Solana: sentinel values 0=mainnet, -2=testnet, -3=devnet." },
          "address": { "type": "string", "description": "Wallet address the balance pertains to." },
          "asset": { "type": "string", "enum": ["native", "erc20", "spl"], "description": "Asset type: native coin or token standard." },
          "token": { "type": ["string", "null"], "description": "Token address (EVM) or mint (Solana) for token balances; null for native." },
          "raw": { "type": "string", "description": "Balance in base units as a string." },
          "decimals": { "type": ["integer", "null"], "description": "Number of decimals for the asset (may be null if metadata unavailable)." },
          "symbol": { "type": ["string", "null"], "description": "Asset symbol, e.g., ETH or USDC (may be null if metadata unavailable)." },
          "updatedAt": { "type": "string", "format": "date-time", "description": "Timestamp when the balance was last refreshed." }
        },
        "required": ["chainType", "chainId", "address", "asset", "raw", "decimals", "symbol", "updatedAt"]
      },
      "GetBalancesResponse": {
        "type": "object",
        "properties": {
          "balances": { "type": "array", "items": { "$ref": "#/components/schemas/WalletBalance" } }
        },
        "required": ["balances"]
      },
      "Wallet": {
        "type": "object",
        "properties": {
          "address": { "type": "string", "description": "Wallet address." },
          "chainType": { "type": "string", "enum": ["ethereum", "solana"], "description": "Chain family for this wallet." },
          "isDefault": { "type": "boolean", "description": "Whether this is the user's default wallet for its chain." },
          "automationEnabled": { "type": "boolean", "description": "Automation/delegation enabled for this wallet." },
          "providerType": { "type": "string", "description": "Wallet provider type (e.g., embedded)." },
          "clientType": { "type": "string", "description": "Client integration type (e.g., privy)." }
        },
        "required": ["address", "chainType", "isDefault", "automationEnabled"]
      },
      "GetWalletsResponse": {
        "type": "object",
        "properties": {
          "wallets": { "type": "array", "items": { "$ref": "#/components/schemas/Wallet" } }
        },
        "required": ["wallets"]
      },
      "Transaction": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "description": "AFK transaction id." },
          "status": { "type": "string", "enum": ["PENDING", "SUBMITTED", "CONFIRMED", "FAILED"], "description": "Current transaction status." },
          "hash": { "type": ["string", "null"], "description": "On-chain transaction hash/signature when available." },
          "explorerUrl": { "type": ["string", "null"], "description": "Direct link to the transaction on a chain explorer. Null until a hash/signature exists." },
          "chainType": { "type": "string", "enum": ["ethereum", "solana"], "description": "Chain family for the transaction." },
          "chainId": { "type": "integer", "description": "EVM: numeric chainId; Solana: sentinel values 0=mainnet, -2=testnet, -3=devnet" },
          "chainName": { "type": "string", "description": "Human-readable chain name for display (e.g., Base, Ethereum, Solana)." },
          "to": { "type": ["string", "null"], "description": "Destination address, if applicable." },
          "value": { "type": ["string", "null"], "description": "Native value sent in base units, if applicable." },
          "error": { "type": ["string", "null"], "description": "Error message if the transaction failed." },
          "createdAt": { "type": "string", "format": "date-time", "description": "Creation timestamp." },
          "updatedAt": { "type": "string", "format": "date-time", "description": "Last updated timestamp." }
        },
        "required": ["id", "status", "explorerUrl", "chainType", "chainId", "chainName", "createdAt", "updatedAt"]
      },
      "SendRequest": {
        "type": "object",
        "properties": {
          "chain": { "type": "string", "description": "Chain slug (e.g., base, base-sepolia, solana-devnet)." },
          "from": { "type": ["string", "null"], "description": "Optional sender wallet; defaults to user's default wallet for the chain." },
          "to": { "type": "string", "description": "Recipient wallet address (owner for token transfers)." },
          "asset": { "type": "string", "enum": ["native", "erc20", "spl"], "description": "Asset type to send." },
          "token": { "type": ["string", "null"], "description": "Token address (EVM) or mint (Solana) when sending tokens." },
          "amount": { "type": "string", "description": "Amount in base units (wei/lamports/token units)." }
        },
        "required": ["chain", "to", "asset", "amount"]
      },
      "ApproveRequest": {
        "type": "object",
        "properties": {
          "chain": { "type": "string", "description": "EVM chain slug." },
          "from": { "type": ["string", "null"], "description": "Optional sender wallet; defaults to user's default wallet for the chain." },
          "token": { "type": "string", "description": "ERC20 token address to approve." },
          "spender": { "type": "string", "description": "Spender (router) address to approve." },
          "amount": { "type": "string", "description": "Allowance amount in token units (uint256 string)." }
        },
        "required": ["chain", "token", "spender", "amount"]
      },
      "ContractsSendRequest": {
        "type": "object",
        "properties": {
          "chain": { "type": "string", "description": "EVM chain slug." },
          "from": { "type": ["string", "null"], "description": "Optional sender wallet; defaults to user's default wallet for the chain." },
          "to": { "type": "string", "description": "Target contract address." },
          "data": { "type": "string", "description": "Calldata hex string (0x-prefixed)." },
          "value": { "type": ["string", "null"], "description": "Optional native value in wei as a string." }
        },
        "required": ["chain", "to", "data"]
      },
      "TradeQuoteRequest": {
        "oneOf": [
          { "$ref": "#/components/schemas/EvmTradeQuoteRequest" },
          { "$ref": "#/components/schemas/SolanaTradeQuoteRequest" }
        ]
      },
      "EvmTradeQuoteRequest": {
        "title": "EVM",
        "type": "object",
        "properties": {
          "chain": { "type": "string", "description": "EVM chain slug" },
          "fromToken": { "type": "string" },
          "toToken": { "type": "string" },
          "amount": { "type": "string", "description": "Amount in wei (decimal or 0x-hex)" },
          "from": { "type": ["string", "null"], "description": "Wallet address for allowance checks (optional)" },
          "includeGas": { "type": ["boolean", "null"], "description": "Include gas estimates (optional)" },
          "protocols": { "type": ["string", "null"], "description": "Comma-separated allowlist of protocols (optional)" },
          "excludeProtocols": { "type": ["string", "null"], "description": "Comma-separated blocklist of protocols (optional)" }
        },
        "required": ["chain", "fromToken", "toToken", "amount"]
      },
      "SolanaTradeQuoteRequest": {
        "title": "Solana",
        "type": "object",
        "properties": {
          "chain": { "type": "string", "description": "Solana chain slug" },
          "fromToken": { "type": "string" },
          "toToken": { "type": "string" },
          "amount": { "type": "string", "description": "Amount in base units" },
          "slippage": { "type": "number", "description": "Percentage (e.g., 1 = 1%). Optional; defaults to 1%.", "default": 1 }
        },
        "required": ["chain", "fromToken", "toToken", "amount"]
      },
      "TradeQuoteResponse": {
        "type": "object",
        "properties": {
          "quote": {
            "type": "object",
            "properties": {
              "srcAmount": { "type": "string", "description": "Input amount in base units." },
              "dstAmount": { "type": ["string", "null"], "description": "Estimated output amount in base units (may be null if upstream omits)." },
              "fromToken": { "type": ["string", "null"], "description": "Input token or native indicator (EVM native uses 0xEeee...)." },
              "toToken": { "type": ["string", "null"], "description": "Output token address or mint." },
              "approvalNeeded": { "type": ["boolean", "null"], "description": "Whether ERC20 approval is required (EVM)." },
              "spender": { "type": ["string", "null"], "description": "Router address to approve (EVM)." },
              "allowanceTarget": { "type": ["string", "null"], "description": "Alias of spender for some providers (EVM)." },
              "raw": { "type": "object", "additionalProperties": true, "description": "Raw upstream quote payload for transparency." }
            },
            "required": ["srcAmount"]
          }
        },
        "required": ["quote"]
      },
      "TradeSwapRequest": {
        "oneOf": [
          { "$ref": "#/components/schemas/EvmTradeSwapInlineRequest" },
          { "$ref": "#/components/schemas/SolanaTradeSwapInlineRequest" }
        ]
      },
      "EvmTradeSwapInlineRequest": {
        "title": "EVM",
        "type": "object",
        "properties": {
          "chain": { "type": "string", "description": "EVM chain slug." },
          "from": { "type": ["string", "null"], "description": "Optional sender wallet; defaults to user's default wallet for the chain." },
          "fromToken": { "type": "string", "description": "Token or native address (0xEeee... for native)" },
          "toToken": { "type": "string", "description": "Output token address (0x...)." },
          "amount": { "type": "string", "description": "Amount in wei (decimal or 0x-hex supported for EVM)." },
          "slippage": { "type": "number", "description": "Percentage (e.g., 1 = 1%). Optional; defaults to 1%.", "default": 1 },
          "includeGas": { "type": ["boolean", "null"], "description": "Include gas estimates in the build (optional)." },
          "protocols": { "type": ["string", "null"], "description": "Comma-separated allowlist of protocols (optional)." },
          "excludeProtocols": { "type": ["string", "null"], "description": "Comma-separated blocklist of protocols (optional)." }
        },
        "required": ["chain", "fromToken", "toToken", "amount"]
      },
      "SolanaTradeSwapInlineRequest": {
        "title": "Solana",
        "type": "object",
        "properties": {
          "chain": { "type": "string", "description": "Solana chain slug (solana, solana-testnet, solana-devnet)." },
          "from": { "type": ["string", "null"], "description": "Optional sender public key; improves route calculation." },
          "fromToken": { "type": "string", "description": "Input mint address." },
          "toToken": { "type": "string", "description": "Output mint address." },
          "amount": { "type": "string", "description": "Amount in base units (SPL token units)." },
          "slippage": { "type": "number", "description": "Percentage (e.g., 1 = 1%). Optional; defaults to 1%.", "default": 1 }
        },
        "required": ["chain", "fromToken", "toToken", "amount"]
      },
      "SubmissionResponse": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "description": "AFK transaction id for the submitted action." },
          "status": { "type": "string", "enum": ["SUBMITTED"], "description": "Submission status." },
          "hash": { "type": ["string", "null"], "description": "On-chain transaction hash/signature (may be null at submission time)." },
          "explorerUrl": { "type": ["string", "null"], "description": "Direct link to the transaction on a chain explorer. Null until a hash/signature exists." },
          "chainName": { "type": "string", "description": "Human-readable chain name for display (e.g., Base, Ethereum, Solana)." }
        },
        "required": ["id", "status", "hash", "explorerUrl", "chainName"]
      },
      "ApiError": {
        "type": "object",
        "properties": {
          "error": { "type": "string", "description": "Human-readable error message." },
          "code": { "type": "string", "enum": [
            "FORBIDDEN",
            "UNAUTHORIZED",
            "RATE_LIMITED",
            "INVALID_INPUT",
            "WALLET_NOT_FOUND",
            "USER_NOT_LINKED",
            "WALLET_NOT_DELEGATED",
            "WALLET_ID_REQUIRED",
            "CHAIN_UNKNOWN",
            "IDEMPOTENT_BODY_MISMATCH",
            "IDEMPOTENT_REPLAY",
            "PRIVY_RPC_ERROR",
            "SEND_FAILED",
            "SERVICE_UNAVAILABLE",
            "QUOTE_FAILED",
            "NOT_FOUND",
            "INSUFFICIENT_FUNDS",
            "INTERNAL_ERROR"
          ], "description": "Stable error code for programmatic handling." },
          "requestId": { "type": ["string", "null"], "description": "Unique request identifier (also in x-request-id header)." }
        },
        "required": ["error"]
      }
    },
    "responses": {
      "ErrorResponse": {
        "description": "Error envelope",
        "content": {
          "application/json": { "schema": { "$ref": "#/components/schemas/ApiError" } }
        },
        "headers": { "x-request-id": { "$ref": "#/components/headers/XRequestId" } }
      }
    },
    "securitySchemes": {
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      }
    }
  }
}