{
  "openapi": "3.1.0",
  "info": {
    "title": "WAGMI Bot Trading API",
    "version": "1.4.0",
    "description": "Unattended swaps, arbitrage, Morpho Earn and Aave V3 withdrawals. Same-chain ERC-20 swaps use LI.FI; cross-chain swaps use direct Across canonical-USDC transfers or available THORChain EVM token pools. Optional USDC funding sequences withdraw Aave and bridge before trading. Enable cross-chain/funding permissions once in Settings. Settlement requires finalized delivery or refund evidence; submission is not a fill."
  },
  "servers": [
    {
      "url": "https://{host}/v1",
      "variables": {
        "host": {
          "default": "YOUR-WAGMI-API-HOST",
          "description": "Use the configured wagmi-api deployment host."
        }
      }
    }
  ],
  "paths": {
    "/me": {
      "get": {
        "summary": "GET /me",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/capabilities": {
      "get": {
        "summary": "GET /capabilities",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/bot/authorizations": {
      "post": {
        "summary": "POST /bot/authorizations",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Policy"
              }
            }
          }
        }
      }
    },
    "/bot/authorizations/token": {
      "post": {
        "summary": "POST /bot/authorizations/token",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "device_code"
                ],
                "properties": {
                  "device_code": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/bot/grants/current": {
      "get": {
        "summary": "GET /bot/grants/current",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "wallet_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/bot/grants/{id}": {
      "delete": {
        "summary": "DELETE /bot/grants/{id}",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/arbs/active": {
      "get": {
        "summary": "GET /arbs/active",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "wallet_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "executable_only",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": true
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200
            }
          }
        ]
      }
    },
    "/arbs/{id}/quote": {
      "post": {
        "summary": "POST /arbs/{id}/quote",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "wallet_id",
                  "sell_amount"
                ],
                "properties": {
                  "wallet_id": {
                    "type": "string"
                  },
                  "sell_amount": {
                    "type": "string",
                    "pattern": "^\\d+(\\.\\d+)?$"
                  },
                  "opportunity_revision": {
                    "type": "string"
                  },
                  "slippage_bps": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 30
                  },
                  "venue": {
                    "type": "string"
                  },
                  "adapter": {
                    "type": "string",
                    "enum": [
                      "lifi",
                      "across",
                      "thorchain"
                    ]
                  },
                  "funding": {
                    "$ref": "#/components/schemas/Funding"
                  }
                }
              }
            }
          }
        },
        "description": " Cross-chain and funded quotes require suitable owner-configured execution permissions. Funding costs are included in economics; arbitrage quotes must remain profitable after all stages. Discovery providers may differ from the explicitly returned execution adapter. No funds move during quoting."
      }
    },
    "/arbs/{id}/execute": {
      "post": {
        "summary": "POST /arbs/{id}/execute",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "wallet_id",
                  "quote_id",
                  "client_order_id"
                ],
                "properties": {
                  "wallet_id": {
                    "type": "string"
                  },
                  "quote_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "client_order_id": {
                    "type": "string",
                    "maxLength": 100
                  }
                }
              }
            }
          }
        }
      }
    },
    "/executions": {
      "get": {
        "summary": "GET /executions",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "wallet_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/executions/{id}": {
      "get": {
        "summary": "GET /executions/{id}",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "description": "bridging/refund_pending are nonterminal. filled requires destination-finalized evidence. Verified refunds end failed with failure_code=bridge_refunded, partial outcomes with bridge_partial_fill, and actual amounts in bridge. funding shows stage/total_stages/completed_stages. If a later trade fails after funding, failure_code starts funding_completed_; settled funding remains in the wallet. Never repeat the original funding request blindly."
      }
    },
    "/executions/{id}/cancel": {
      "post": {
        "summary": "POST /executions/{id}/cancel",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/executions/{id}/reconcile": {
      "post": {
        "summary": "Resume observation of the existing execution",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "description": "Idempotent recovery of persisted transaction hashes and bridge delivery/refund evidence. No body, new recipient, calldata, second deposit or forced refund. THORChain and Across return protocol-managed refunds to the owned source wallet. A known hash remains pending until evidence is conclusive. Revocation stops new signatures; the worker continues observing existing transfers."
      }
    },
    "/executions/{id}/resume": {
      "post": {
        "summary": "Resume observation of the existing execution",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "description": "Idempotent recovery of persisted transaction hashes and bridge delivery/refund evidence. No body, new recipient, calldata, second deposit or forced refund. THORChain and Across return protocol-managed refunds to the owned source wallet. A known hash remains pending until evidence is conclusive. Revocation stops new signatures; the worker continues observing existing transfers."
      }
    },
    "/executions/{id}/recover": {
      "post": {
        "summary": "Resume observation of the existing execution",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "description": "Idempotent recovery of persisted transaction hashes and bridge delivery/refund evidence. No body, new recipient, calldata, second deposit or forced refund. THORChain and Across return protocol-managed refunds to the owned source wallet. A known hash remains pending until evidence is conclusive. Revocation stops new signatures; the worker continues observing existing transfers."
      }
    },
    "/balances": {
      "get": {
        "summary": "GET /balances",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Balances with next_cursor (string or null) and coverage: mode (requested_assets or curated_and_recent_activity), complete_wallet_inventory (false), discovery_truncated (whether the recent-activity candidate limit was hit). Amounts are atomic decimal strings; divide by 10^decimals."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "wallet_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "asset_id",
            "in": "query",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "maxItems": 30,
              "items": {
                "type": "string"
              }
            },
            "description": "Optional ERC-20 identifiers to read; repeat asset_id for multiple tokens."
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{1,4}$"
            },
            "description": "Opaque next_cursor from a default discovery page. Omit for the first page; do not combine with explicit asset_id requests."
          }
        ],
        "description": "Default discovery reads curated dashboard ERC-20 tokens plus assets in recent wallet activity and the current grant. It is not a complete inventory or a list of Earn positions. Follow next_cursor until null; native gas balances repeat on each page. To read a specific token, repeat asset_id (up to 30); explicit requests do not use cursor. Every amount is read on-chain. An omitted token is not a zero balance. RPC failures return null amounts and can_spend=false."
      }
    },
    "/volume/today": {
      "get": {
        "summary": "GET /volume/today",
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "2XX": {
            "description": "Success. Execution admission is asynchronous; poll status until settled."
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "wallet_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "description": "Includes settled funding bridge input volume once, including when the final trade fails. Additional fields settled_funding_swaps and funding_swap_volume_usd identify these stages. Aave withdrawals and approvals are not funding swaps."
      }
    },
    "/swaps/quote": {
      "post": {
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "201": {
            "description": "Success"
          }
        },
        "summary": "Quote a general swap without an arbitrage listing",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "wallet_id",
                  "source_asset_id",
                  "destination_asset_id",
                  "sell_amount"
                ],
                "properties": {
                  "wallet_id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 150
                  },
                  "source_asset_id": {
                    "type": "string",
                    "pattern": "^(BASE|ETH|ARB|BSC|AVAX|OP)\\.[A-Za-z0-9_]+-0x[0-9a-fA-F]{40}$",
                    "maxLength": 150,
                    "description": "Full identifier from /v1/assets; never shorten the contract address."
                  },
                  "destination_asset_id": {
                    "type": "string",
                    "pattern": "^(BASE|ETH|ARB|BSC|AVAX|OP)\\.[A-Za-z0-9_]+-0x[0-9a-fA-F]{40}$",
                    "maxLength": 150,
                    "description": "Full identifier from /v1/assets; never shorten the contract address."
                  },
                  "sell_amount": {
                    "type": "string",
                    "pattern": "^\\d{1,24}(\\.\\d{1,18})?$",
                    "description": "Positive decimal string in whole source-token units. \"1000\" means 1,000 tokens, not 1,000 smallest units."
                  },
                  "slippage_bps": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 30
                  },
                  "venue": {
                    "type": "string"
                  },
                  "adapter": {
                    "type": "string",
                    "enum": [
                      "lifi",
                      "across",
                      "thorchain"
                    ]
                  },
                  "funding": {
                    "$ref": "#/components/schemas/Funding"
                  }
                }
              },
              "example": {
                "wallet_id": "YOUR_WALLET_ID",
                "source_asset_id": "BASE.BRETT-0x532f27101965dd16442E59d40670FaF5eBB142E4",
                "destination_asset_id": "BASE.USDC-0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                "sell_amount": "1000",
                "slippage_bps": 30
              }
            }
          }
        },
        "description": "Use the exact field names below and full identifiers from /v1/assets. sell_amount is a decimal string in whole source-token units, not atomic units. The granted slippage limit may be below this endpoint\u2019s maximum. Quotes read the source token balance directly on-chain; the token does not need to be present in default /balances discovery. Cross-chain and funded quotes require suitable owner-configured execution permissions. Funding costs are included in economics; arbitrage quotes must remain profitable after all stages. Discovery providers may differ from the explicitly returned execution adapter. No funds move during quoting."
      }
    },
    "/swaps/execute": {
      "post": {
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "202": {
            "description": "Success"
          }
        },
        "summary": "Execute a quoted general swap; requires swaps:execute",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "wallet_id",
                  "quote_id",
                  "client_order_id"
                ],
                "properties": {
                  "wallet_id": {
                    "type": "string"
                  },
                  "quote_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "client_order_id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ]
      }
    },
    "/earn/vaults": {
      "get": {
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "summary": "Discover supported Morpho vaults",
        "parameters": [
          {
            "name": "chain",
            "in": "query",
            "schema": {
              "enum": [
                "ETH",
                "BASE",
                "ARB"
              ]
            }
          },
          {
            "name": "adapter",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "morpho",
                "aave"
              ],
              "default": "morpho"
            }
          }
        ],
        "description": "Morpho is the default. adapter=aave discovers V3 canonical-USDC reserves on ETH, BASE, ARB, OP and AVAX. Aave supports withdrawal only."
      }
    },
    "/earn/positions": {
      "get": {
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success"
          },
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "summary": "Read tracked positions, or inspect a specific vault",
        "parameters": [
          {
            "name": "wallet_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "vault_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "adapter",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "morpho",
                "aave"
              ],
              "default": "morpho"
            }
          },
          {
            "name": "asset_id",
            "in": "query",
            "style": "form",
            "explode": true,
            "schema": {
              "type": "array",
              "maxItems": 12,
              "items": {
                "type": "string"
              }
            },
            "description": "For Aave, full underlying ERC-20 identifiers; repeat to inspect additional reserves. Default is canonical USDC on supported chains. Unknown RPC responses are not zero balances."
          }
        ],
        "description": "Morpho is the default. adapter=aave discovers V3 canonical-USDC reserves on ETH, BASE, ARB, OP and AVAX. Aave supports withdrawal only. Aave positions report assets, liquid_assets, health_factor, available and coverage. Liquid assets are not a guaranteed withdrawable amount: health and simulation are checked by the withdrawal quote."
      }
    },
    "/earn/deposit/quote": {
      "post": {
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "201": {
            "description": "Success"
          }
        },
        "summary": "Quote Morpho deposit; amount is underlying assets, shares is receipt-token units",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "wallet_id",
                  "vault_id",
                  "amount"
                ],
                "properties": {
                  "wallet_id": {
                    "type": "string"
                  },
                  "vault_id": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^\\d{1,24}(\\.\\d{1,18})?$"
                  },
                  "slippage_bps": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 30
                  }
                }
              }
            }
          }
        }
      }
    },
    "/earn/deposit": {
      "post": {
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "202": {
            "description": "Success"
          }
        },
        "summary": "Execute a quoted Morpho deposit; requires earn:deposit",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "wallet_id",
                  "quote_id",
                  "client_order_id"
                ],
                "properties": {
                  "wallet_id": {
                    "type": "string"
                  },
                  "quote_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "client_order_id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ]
      }
    },
    "/earn/withdraw/quote": {
      "post": {
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "201": {
            "description": "Success"
          }
        },
        "summary": "Quote a Morpho redemption or Aave V3 withdrawal",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "wallet_id",
                  "vault_id"
                ],
                "properties": {
                  "wallet_id": {
                    "type": "string"
                  },
                  "vault_id": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^\\d{1,24}(\\.\\d{1,18})?$"
                  },
                  "slippage_bps": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 30
                  },
                  "shares": {
                    "type": "string",
                    "pattern": "^\\d{1,24}(\\.\\d{1,18})?$"
                  }
                },
                "oneOf": [
                  {
                    "required": [
                      "amount"
                    ],
                    "not": {
                      "required": [
                        "shares"
                      ]
                    }
                  },
                  {
                    "required": [
                      "shares"
                    ],
                    "not": {
                      "required": [
                        "amount"
                      ]
                    }
                  }
                ]
              }
            }
          }
        },
        "description": "For Aave use vault_id=aave:CHAIN:underlying-address and amount in whole underlying units. shares is not supported for Aave. Withdrawals stay in the owned wallet and enforce liquidity plus a conservative post-withdraw health factor (default 1.2, owner-configurable)."
      }
    },
    "/earn/withdraw": {
      "post": {
        "security": [
          {
            "BotCredential": []
          }
        ],
        "responses": {
          "default": {
            "description": "Typed error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "202": {
            "description": "Success"
          }
        },
        "summary": "Execute a quoted Earn withdrawal; requires earn:withdraw",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "wallet_id",
                  "quote_id",
                  "client_order_id"
                ],
                "properties": {
                  "wallet_id": {
                    "type": "string"
                  },
                  "quote_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "client_order_id": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BotCredential": {
        "type": "http",
        "scheme": "bearer",
        "description": "wagmi_bot_ key for scoped reads/quotes; wagmi_exec_ session token for execute/cancel."
      }
    },
    "schemas": {
      "Policy": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "wallet_id",
          "mode",
          "allowed_chains",
          "allowed_adapters",
          "allowed_venues",
          "allowed_assets",
          "max_trade_usd",
          "max_daily_input_volume_usd",
          "max_open_exposure_usd",
          "max_daily_loss_usd",
          "min_expected_net_profit_usd",
          "min_conservative_net_profit_usd",
          "max_gas_usd_per_execution",
          "min_net_edge_bps",
          "max_slippage_bps",
          "max_inflight_executions",
          "allow_cross_chain",
          "allow_earn_actions",
          "allow_external_recipients",
          "allow_partial_fills",
          "expires_in_seconds"
        ],
        "properties": {
          "wallet_id": {
            "type": "string"
          },
          "mode": {
            "type": "string",
            "enum": [
              "shadow",
              "live"
            ],
            "default": "shadow"
          },
          "allowed_chains": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "BASE",
                "ETH",
                "ARB",
                "BSC",
                "AVAX",
                "OP"
              ]
            },
            "minItems": 1,
            "maxItems": 6
          },
          "allowed_adapters": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "lifi",
                "morpho",
                "across",
                "thorchain",
                "aave"
              ]
            },
            "maxItems": 5
          },
          "allowed_venues": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "allowed_assets": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "max_trade_usd": {
            "type": "string"
          },
          "max_daily_input_volume_usd": {
            "type": "string"
          },
          "max_open_exposure_usd": {
            "type": "string"
          },
          "max_daily_loss_usd": {
            "type": "string"
          },
          "min_expected_net_profit_usd": {
            "type": "string"
          },
          "min_conservative_net_profit_usd": {
            "type": "string"
          },
          "max_gas_usd_per_execution": {
            "type": "string"
          },
          "min_net_edge_bps": {
            "type": "integer"
          },
          "max_slippage_bps": {
            "type": "integer"
          },
          "max_inflight_executions": {
            "type": "integer",
            "const": 1
          },
          "allow_cross_chain": {
            "type": "boolean",
            "default": false
          },
          "allow_earn_actions": {
            "type": "boolean",
            "default": false
          },
          "allow_external_recipients": {
            "type": "boolean",
            "const": false
          },
          "allow_partial_fills": {
            "type": "boolean",
            "const": false
          },
          "expires_in_seconds": {
            "type": "integer",
            "minimum": 300,
            "maximum": 3600
          },
          "allowed_actions": {
            "type": "array",
            "items": {
              "enum": [
                "arbitrage",
                "swap",
                "earn_deposit",
                "earn_withdraw"
              ]
            },
            "default": [
              "arbitrage"
            ]
          },
          "any_asset": {
            "type": "boolean",
            "default": false
          },
          "any_venue": {
            "type": "boolean",
            "default": false
          },
          "allow_funding": {
            "type": "boolean",
            "default": false
          },
          "min_aave_health_factor": {
            "type": "string",
            "default": "1.2",
            "description": "Decimal string from 1.2 through 10."
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "request_id": {
                "type": "string"
              },
              "retryable": {
                "type": "boolean"
              },
              "details": {
                "type": "array",
                "description": "For invalid_request schema errors: field names and constraints, with no submitted values.",
                "items": {
                  "type": "object",
                  "required": [
                    "field",
                    "code",
                    "message"
                  ],
                  "properties": {
                    "field": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "Funding": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "source_asset_id",
          "location",
          "amount"
        ],
        "properties": {
          "source_asset_id": {
            "type": "string",
            "description": "Full canonical USDC identifier on the funding source network."
          },
          "location": {
            "type": "string",
            "enum": [
              "spot",
              "aave"
            ]
          },
          "amount": {
            "type": "string",
            "description": "Maximum exact amount to withdraw/bridge in whole USDC units; must cover fees and required trade input."
          },
          "adapter": {
            "type": "string",
            "enum": [
              "across",
              "thorchain"
            ],
            "description": "Explicit funding bridge. Across is preferred for supported canonical USDC pairs."
          }
        },
        "description": "At most Aave withdrawal + funding bridge before the requested trade. No arbitrary destination, gas top-up or automatic redeposit. Already-funded wallets skip funding. Every stage is freshly quoted before signing; all input and costs count toward grant limits."
      }
    }
  }
}
