{
  "openapi": "3.0.0",
  "paths": {
    "/bento/user/auth/eoa/challenge": {
      "post": {
        "operationId": "AuthController_eoaChallenge",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EoaChallengeDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "SIWE message + timestamp + domain + builderAppId"
          }
        },
        "summary": "Get the SIWE message to sign for EOA login/register (bound to builder + domain)",
        "tags": [
          "user-auth"
        ]
      }
    },
    "/bento/user/auth/eoa/login": {
      "post": {
        "operationId": "AuthController_eoaLogin",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EoaLoginDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Login with an EOA-signed SIWE message (tenant-scoped to the builder key)",
        "tags": [
          "user-auth"
        ]
      }
    },
    "/bento/user/auth/eoa/register": {
      "post": {
        "operationId": "AuthController_eoaRegister",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EoaRegisterDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Register a new user using an EOA-signed SIWE message (tenant-scoped to the builder key)",
        "tags": [
          "user-auth"
        ]
      }
    },
    "/bento/user/auth/auth0/login": {
      "post": {
        "operationId": "AuthController_auth0Login",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Auth0LoginDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Login with an Auth0 id_token or access_token",
        "tags": [
          "user-auth"
        ]
      }
    },
    "/bento/user/auth/auth0/register": {
      "post": {
        "operationId": "AuthController_auth0Register",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Auth0RegisterDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Register a new user using Auth0",
        "tags": [
          "user-auth"
        ]
      }
    },
    "/bento/user/auth/check-username": {
      "get": {
        "operationId": "AuthController_checkUsername",
        "parameters": [
          {
            "name": "username",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Check if a username is available",
        "tags": [
          "user-auth"
        ]
      }
    },
    "/bento/user/auth/profile-image": {
      "post": {
        "operationId": "AuthController_uploadProfileImage",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "image": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "image"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Upload profile image and persist URL on the user record",
        "tags": [
          "user-auth"
        ]
      }
    },
    "/bento/user/wallet/sign": {
      "post": {
        "operationId": "WalletController_sign",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SignMessageDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sign a message (personal_sign)",
        "tags": [
          "user-wallet"
        ]
      }
    },
    "/bento/user/wallet/sign-typed-data": {
      "post": {
        "operationId": "WalletController_signTypedData",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SignTypedDataDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sign EIP-712 typed data",
        "tags": [
          "user-wallet"
        ]
      }
    },
    "/bento/user/bulk-register/register-simple": {
      "post": {
        "operationId": "BulkRegisterController_registerSimple",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterSimpleDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Register a single user by address (automation)",
        "tags": [
          "user-bulk-register"
        ]
      }
    },
    "/bento/user/bulk-register/register-bulk": {
      "post": {
        "operationId": "BulkRegisterController_registerBulk",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterBulkDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Register many users by address (max 200)",
        "tags": [
          "user-bulk-register"
        ]
      }
    },
    "/bento/user/bulk-register/check-user": {
      "get": {
        "operationId": "BulkRegisterController_checkUser",
        "parameters": [
          {
            "name": "address",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Check if a user exists for a given address",
        "tags": [
          "user-bulk-register"
        ]
      }
    },
    "/bento/user/withdraw": {
      "post": {
        "operationId": "WithdrawController_withdraw",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WithdrawDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Withdraw USDC via Funkit bridge",
        "tags": [
          "user-withdraw"
        ]
      }
    },
    "/bento/user/withdraw/claim-winnings": {
      "post": {
        "operationId": "WithdrawController_claimWinnings",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClaimWinningsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Claim market winnings (withdrawEarnings)",
        "tags": [
          "user-withdraw"
        ]
      }
    },
    "/bento/user/withdraw/creator-fees": {
      "get": {
        "operationId": "WithdrawController_getCreatorFees",
        "parameters": [
          {
            "name": "collateralStack",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "collateralMode",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get total claimable creator fees",
        "tags": [
          "user-withdraw"
        ]
      }
    },
    "/bento/user/withdraw/claim-fees": {
      "post": {
        "operationId": "WithdrawController_claimFees",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClaimFeesDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Claim all available creator fees",
        "tags": [
          "user-withdraw"
        ]
      }
    },
    "/bento/user/withdrawal-requests/pre-validate": {
      "post": {
        "operationId": "WithdrawalRequestController_preValidate",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Pre-validate a withdrawal before on-chain execution.",
        "tags": [
          "user-withdrawal-requests"
        ]
      }
    },
    "/bento/user/withdrawal-requests/daily-limit": {
      "get": {
        "operationId": "WithdrawalRequestController_dailyLimit",
        "parameters": [
          {
            "name": "user",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "collateralStack",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "collateralMode",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Remaining 24h limit for a user.",
        "tags": [
          "user-withdrawal-requests"
        ]
      }
    },
    "/bento/user/withdrawal-requests": {
      "post": {
        "operationId": "WithdrawalRequestController_create",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Record a withdrawal request.",
        "tags": [
          "user-withdrawal-requests"
        ]
      },
      "get": {
        "operationId": "WithdrawalRequestController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List withdrawal requests (paginated).",
        "tags": [
          "user-withdrawal-requests"
        ]
      }
    },
    "/bento/user/referral-analytics": {
      "get": {
        "operationId": "UserReferralAnalyticsController_mine",
        "parameters": [
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "enum": [
                "usdc",
                "credits"
              ],
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Referral analytics for the authenticated wallet (invite volume & referees)",
        "tags": [
          "user-referral-analytics"
        ]
      }
    },
    "/bento/webhooks/funkit/deposit": {
      "post": {
        "operationId": "FunkitWebhookController_deposit",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "FunKit deposit-completed webhook → push",
        "tags": [
          "webhooks"
        ]
      }
    },
    "/bento/user/aws/generate-presigned-url": {
      "post": {
        "operationId": "AwsController_generatePresignedUrl",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PresignedUrlDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Generate a presigned URL for uploading a file to S3.",
        "tags": [
          "aws"
        ]
      }
    },
    "/bento/user/duels/create": {
      "post": {
        "operationId": "DuelController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDuelDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateDuelResponseDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a new duel on-chain and register in DB",
        "tags": [
          "duels"
        ]
      }
    },
    "/bento/user/duels/canonical": {
      "get": {
        "operationId": "DuelController_listCanonical",
        "parameters": [
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "live = in play (PM live flag or kickoff passed); upcoming = kickoff in the future; all (default) = every open canonical duel.",
            "schema": {
              "type": "string",
              "enum": [
                "live",
                "upcoming",
                "all"
              ]
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Max rows (default 50, cap 100)",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Canonical Polymarket-mirror credits duels, ranked by paired PM 24h volume",
        "tags": [
          "duels"
        ]
      }
    },
    "/bento/user/duels/by-league/{leagueId}": {
      "get": {
        "operationId": "DuelController_listByLeague",
        "parameters": [
          {
            "name": "leagueId",
            "required": true,
            "in": "path",
            "schema": {
              "example": "default",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page index (default 1)",
            "schema": {
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Page size (default 20, max 100)",
            "schema": {
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          },
          {
            "name": "category",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "pending",
                "settled",
                "pending_contest"
              ]
            }
          },
          {
            "name": "includePrivate",
            "required": false,
            "in": "query",
            "description": "Include private duels (admin only)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sortBy",
            "required": false,
            "in": "query",
            "description": "Sort key (whitelisted). `polymarketVolume24h` ranks canonical duels by paired Polymarket volume.",
            "schema": {
              "type": "string",
              "enum": [
                "createdAt",
                "startTime",
                "endTime",
                "polymarketVolume24h"
              ]
            }
          },
          {
            "name": "sortOrder",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Duel list by league (legacy iOS route; `default` = all leagues)",
        "tags": [
          "duels"
        ]
      }
    },
    "/bento/user/duels/get-all-duels": {
      "get": {
        "operationId": "DuelController_getAllDuels",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page index (default 1)",
            "schema": {
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Page size (default 20, max 100)",
            "schema": {
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          },
          {
            "name": "category",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "pending",
                "settled",
                "pending_contest"
              ]
            }
          },
          {
            "name": "includePrivate",
            "required": false,
            "in": "query",
            "description": "Include private duels (admin only)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sortBy",
            "required": false,
            "in": "query",
            "description": "Sort key (whitelisted). `polymarketVolume24h` ranks canonical duels by paired Polymarket volume.",
            "schema": {
              "type": "string",
              "enum": [
                "createdAt",
                "startTime",
                "endTime",
                "polymarketVolume24h"
              ]
            }
          },
          {
            "name": "sortOrder",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "All duels (legacy iOS route)",
        "tags": [
          "duels"
        ]
      }
    },
    "/bento/user/duels/get-duel-by-id/{duelId}": {
      "get": {
        "operationId": "DuelController_getById",
        "parameters": [
          {
            "name": "duelId",
            "required": true,
            "in": "path",
            "schema": {
              "example": "duel_1234",
              "type": "string"
            }
          },
          {
            "name": "userAddress",
            "required": false,
            "in": "query",
            "description": "Address of the requesting user (for participation flag)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Fetch duel by id (public, optional participation)",
        "tags": [
          "duels"
        ]
      }
    },
    "/bento/user/duels/participants/{duelId}": {
      "get": {
        "operationId": "DuelController_getParticipants",
        "parameters": [
          {
            "name": "duelId",
            "required": true,
            "in": "path",
            "schema": {
              "example": "duel_1234",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Participants (aggregated positions + PnL). Enforces membership for private duels.",
        "tags": [
          "duels"
        ]
      }
    },
    "/bento/user/duels/contest": {
      "post": {
        "operationId": "DuelController_submitContest",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitContestDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Submit a contest during contest period",
        "tags": [
          "duels"
        ]
      }
    },
    "/bento/user/duels/contest/{duelId}": {
      "get": {
        "operationId": "DuelController_getContestsForDuel",
        "parameters": [
          {
            "name": "duelId",
            "required": true,
            "in": "path",
            "schema": {
              "example": "duel_1234",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List contests for a duel (public)",
        "tags": [
          "duels"
        ]
      }
    },
    "/bento/user/duels/contest/{duelId}/my-contest": {
      "get": {
        "operationId": "DuelController_getMyContest",
        "parameters": [
          {
            "name": "duelId",
            "required": true,
            "in": "path",
            "schema": {
              "example": "duel_1234",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Current user's contest on a duel",
        "tags": [
          "duels"
        ]
      }
    },
    "/bento/user/duels/{duelId}/contests": {
      "get": {
        "operationId": "DuelController_getCreatorContests",
        "parameters": [
          {
            "name": "duelId",
            "required": true,
            "in": "path",
            "schema": {
              "example": "duel_1234",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Contests for a duel (creator-only view with user addresses)",
        "tags": [
          "duels"
        ]
      }
    },
    "/bento/user/duels/finalize-contest": {
      "post": {
        "operationId": "DuelController_finalizeContest",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FinalizeContestDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Creator-only: finalize contested private duel after contest period",
        "tags": [
          "duels"
        ]
      }
    },
    "/bento/user/duels/resolve": {
      "post": {
        "operationId": "DuelController_resolve",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResolveDuelDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Creator-only: settle one or more closed markets on-chain",
        "tags": [
          "duels"
        ]
      }
    },
    "/bento/public/duels/all": {
      "get": {
        "operationId": "PublicDuelController_listAll",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page index (default 1)",
            "schema": {
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "description": "Page size (default 20, max 100)",
            "schema": {
              "default": 20,
              "type": "number"
            }
          },
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          },
          {
            "name": "category",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "pending",
                "settled",
                "pending_contest"
              ]
            }
          },
          {
            "name": "includePrivate",
            "required": false,
            "in": "query",
            "description": "Include private duels (admin only)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sortBy",
            "required": false,
            "in": "query",
            "description": "Sort key (whitelisted). `polymarketVolume24h` ranks canonical duels by paired Polymarket volume.",
            "schema": {
              "type": "string",
              "enum": [
                "createdAt",
                "startTime",
                "endTime",
                "polymarketVolume24h"
              ]
            }
          },
          {
            "name": "sortOrder",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListPublicDuelsResponseDto"
                }
              }
            }
          }
        },
        "summary": "Paginated list of all duels (public, rate-limited)",
        "tags": [
          "public-duels"
        ]
      }
    },
    "/bento/public/duels/get-duel-by-id/{duelId}": {
      "get": {
        "operationId": "PublicDuelController_getById",
        "parameters": [
          {
            "name": "duelId",
            "required": true,
            "in": "path",
            "schema": {
              "example": "duel_1234",
              "type": "string"
            }
          },
          {
            "name": "userAddress",
            "required": false,
            "in": "query",
            "description": "Address of the requesting user (for participation flag)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicDuelDetailDto"
                }
              }
            }
          }
        },
        "summary": "Get a single duel by id (public, rate-limited)",
        "tags": [
          "public-duels"
        ]
      }
    },
    "/bento/user/duel-invitations/create": {
      "post": {
        "operationId": "DuelInvitationController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDuelInvitationDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Create a duel invitation (on-chain + DB)",
        "tags": [
          "duel-invitations"
        ]
      }
    },
    "/bento/user/duel-invitations/join": {
      "post": {
        "operationId": "DuelInvitationController_join",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JoinDuelDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Server-signer join with invite code (legacy)",
        "tags": [
          "duel-invitations"
        ]
      }
    },
    "/bento/user/duel-invitations/user-join": {
      "post": {
        "operationId": "DuelInvitationController_userJoin",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserJoinDuelDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "JWT-authenticated server-wallet join + DB sync (one-shot)",
        "tags": [
          "duel-invitations"
        ]
      }
    },
    "/bento/user/duel-invitations/add-member": {
      "post": {
        "operationId": "DuelInvitationController_addMember",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DuelMemberMutationDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Add a duel member (private duel admin action)",
        "tags": [
          "duel-invitations"
        ]
      }
    },
    "/bento/user/duel-invitations/remove-member": {
      "post": {
        "operationId": "DuelInvitationController_removeMember",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DuelMemberMutationDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Remove a duel member",
        "tags": [
          "duel-invitations"
        ]
      }
    },
    "/bento/user/duel-invitations/membership/{duelId}/{userAddress}": {
      "get": {
        "operationId": "DuelInvitationController_checkMembership",
        "parameters": [
          {
            "name": "duelId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userAddress",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Check duel membership (DB → chain fallback)",
        "tags": [
          "duel-invitations"
        ]
      }
    },
    "/bento/user/duel-invitations/memberships/{userAddress}": {
      "get": {
        "operationId": "DuelInvitationController_listMemberships",
        "parameters": [
          {
            "name": "userAddress",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List all duel memberships for a user",
        "tags": [
          "duel-invitations"
        ]
      }
    },
    "/bento/user/duel-invitations/duel/{duelId}": {
      "get": {
        "operationId": "DuelInvitationController_listForDuel",
        "parameters": [
          {
            "name": "duelId",
            "required": true,
            "in": "path",
            "schema": {
              "example": "duel_1234",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List active invitations for a duel",
        "tags": [
          "duel-invitations"
        ]
      }
    },
    "/bento/user/duel-invitations/validate-invite": {
      "post": {
        "operationId": "DuelInvitationController_validate",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ValidateInviteDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Validate an invite before joining",
        "tags": [
          "duel-invitations"
        ]
      }
    },
    "/bento/user/duel-invitations/sync-join-success": {
      "post": {
        "operationId": "DuelInvitationController_sync",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SyncJoinSuccessDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Sync DB after frontend blockchain join succeeded",
        "tags": [
          "duel-invitations"
        ]
      }
    },
    "/bento/user/duel-invitations/revoke": {
      "post": {
        "operationId": "DuelInvitationController_revoke",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevokeInviteDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Revoke an invitation (on-chain + DB)",
        "tags": [
          "duel-invitations"
        ]
      }
    },
    "/bento/user/duel-invitations/{inviteCode}": {
      "get": {
        "operationId": "DuelInvitationController_getOnChain",
        "parameters": [
          {
            "name": "inviteCode",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Fetch on-chain invitation data",
        "tags": [
          "duel-invitations"
        ]
      }
    },
    "/bento/user/parent-markets/create": {
      "post": {
        "operationId": "ParentMarketController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateParentMarketDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateParentMarketResponseDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a parent market with one or more sub-markets (on-chain + DB)",
        "tags": [
          "parent-markets"
        ]
      }
    },
    "/bento/user/parent-markets/create-invitation": {
      "post": {
        "operationId": "ParentMarketController_createInvitation",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateParentMarketInvitationDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateParentMarketInvitationResponseDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create invitation code for a private parent market",
        "tags": [
          "parent-markets"
        ]
      }
    },
    "/bento/user/parent-markets/join": {
      "post": {
        "operationId": "ParentMarketController_join",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JoinParentMarketDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JoinParentMarketResponseDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Join a private parent market with an invite code (incl. private children)",
        "tags": [
          "parent-markets"
        ]
      }
    },
    "/bento/user/parent-markets/{id}/add-duel": {
      "post": {
        "operationId": "ParentMarketController_addChildDuel",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddChildDuelDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddChildDuelResponseDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add a new sub-duel to an existing parent market",
        "tags": [
          "parent-markets"
        ]
      }
    },
    "/bento/user/parent-markets/{id}": {
      "get": {
        "operationId": "ParentMarketController_getParentMarket",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userAddress",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Fetch a parent market with its hydrated sub-duels",
        "tags": [
          "parent-markets"
        ]
      }
    },
    "/bento/user/parent-markets/{id}/invitations": {
      "get": {
        "operationId": "ParentMarketController_listInvitations",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List active invitations (creator-only)",
        "tags": [
          "parent-markets"
        ]
      }
    },
    "/bento/user/parent-markets/{id}/members": {
      "get": {
        "operationId": "ParentMarketController_listMembers",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List active members of a parent market",
        "tags": [
          "parent-markets"
        ]
      }
    },
    "/bento/user/parent-markets/validate-invite": {
      "post": {
        "operationId": "ParentMarketController_validateInvite",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ValidateParentInviteDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Validate a parent market invitation code",
        "tags": [
          "parent-markets"
        ]
      }
    },
    "/bento/duels/og-metadata/{duelId}": {
      "get": {
        "operationId": "OgMetadataController_get",
        "parameters": [
          {
            "name": "duelId",
            "required": true,
            "in": "path",
            "schema": {
              "example": "duel_1234",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Public Open Graph metadata for a market",
        "tags": [
          "og-metadata"
        ]
      }
    },
    "/bento/protocol-stats": {
      "get": {
        "operationId": "ProtocolStatsController_getStats",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Current protocol statistics.",
        "tags": [
          "protocol-stats"
        ]
      }
    },
    "/bento/protocol-stats/summary": {
      "get": {
        "operationId": "ProtocolStatsController_getSummary",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Derived summary of key protocol metrics.",
        "tags": [
          "protocol-stats"
        ]
      }
    },
    "/bento/protocol-stats/refresh": {
      "post": {
        "operationId": "ProtocolStatsController_refresh",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Recompute and persist an updated protocol statistics row.",
        "tags": [
          "protocol-stats"
        ]
      }
    },
    "/bento/user/bets/estimated-win": {
      "post": {
        "operationId": "BetController_estimatedWin",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EstimatedWinDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Compute estimated win from current book.",
        "tags": [
          "bets"
        ]
      }
    },
    "/bento/user/bets/estimate-buy": {
      "post": {
        "operationId": "BetController_estimateBuy",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EstimateBuyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/EstimateBuySuccessResponseDto"
                    },
                    {
                      "$ref": "#/components/schemas/EstimateBuyFailureResponseDto"
                    }
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Fetch a pricing-engine buy quote.",
        "tags": [
          "bets"
        ]
      }
    },
    "/bento/user/bets/estimate-sell": {
      "post": {
        "operationId": "BetController_estimateSell",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EstimateSellDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/EstimateSellSuccessResponseDto"
                    },
                    {
                      "$ref": "#/components/schemas/EstimateSellFailureResponseDto"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponseDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Fetch a pricing-engine sell quote (auth).",
        "tags": [
          "bets"
        ]
      }
    },
    "/bento/user/bets/sell-unlock-liquidity/{duelId}": {
      "get": {
        "operationId": "BetController_sellUnlockLiquidity",
        "parameters": [
          {
            "name": "duelId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetSellUnlockLiquidityResponseDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sell-unlock liquidity status for a market.",
        "tags": [
          "bets"
        ]
      }
    },
    "/bento/user/bets/user-shares/{duelId}/{address}": {
      "get": {
        "operationId": "BetController_userShares",
        "parameters": [
          {
            "name": "duelId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "address",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetUserSharesResponseDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Return authenticated user shares for market.",
        "tags": [
          "bets"
        ]
      }
    },
    "/bento/user/bets/user-bet-limit/{address}": {
      "get": {
        "operationId": "BetController_userBetLimit",
        "parameters": [
          {
            "name": "address",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "bets"
        ]
      }
    },
    "/bento/user/bets/create": {
      "post": {
        "operationId": "BetController_createBet",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBetDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateBetResponseDto"
                }
              }
            }
          },
          "401": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponseDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Place a bet (buy).",
        "tags": [
          "bets"
        ]
      }
    },
    "/bento/user/bets/sell": {
      "post": {
        "operationId": "BetController_sellBet",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SellBetDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SellBetResponseDto"
                }
              }
            }
          },
          "401": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiErrorResponseDto"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sell shares from an existing position.",
        "tags": [
          "bets"
        ]
      }
    },
    "/bento/user/bets/yes-percentage-snapshots/{duelId}": {
      "get": {
        "operationId": "BetController_duelSnapshots",
        "parameters": [
          {
            "name": "duelId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "timeRange",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "30M",
                "1H",
                "6H",
                "1D",
                "1W",
                "1M",
                "ALL"
              ]
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "bets"
        ]
      }
    },
    "/bento/user/bets/yes-percentage-snapshots/parent/{parentMarketId}": {
      "get": {
        "operationId": "BetController_parentSnapshots",
        "parameters": [
          {
            "name": "parentMarketId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "timeRange",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "30M",
                "1H",
                "6H",
                "1D",
                "1W",
                "1M",
                "ALL"
              ]
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "bets"
        ]
      }
    },
    "/bento/public/bets/yes-percentage-snapshots/{duelId}": {
      "get": {
        "operationId": "PublicBetController_snapshots",
        "parameters": [
          {
            "name": "duelId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "timeRange",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "30M",
                "1H",
                "6H",
                "1D",
                "1W",
                "1M",
                "ALL"
              ]
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Public chart data (yes% over time).",
        "tags": [
          "public-bets"
        ]
      }
    },
    "/bento/public/bets/sell-unlock-liquidity/{duelId}": {
      "get": {
        "operationId": "PublicBetController_sellUnlock",
        "parameters": [
          {
            "name": "duelId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Sell-unlock liquidity status.",
        "tags": [
          "public-bets"
        ]
      }
    },
    "/bento/public/bets/estimated-win": {
      "post": {
        "operationId": "PublicBetController_estimatedWin",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EstimatedWinDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Deterministic estimated-win calculation.",
        "tags": [
          "public-bets"
        ]
      }
    },
    "/bento/public/bets/estimate-sell": {
      "post": {
        "operationId": "PublicBetController_estimateSell",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicEstimateSellDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Public sell quote (address in body).",
        "tags": [
          "public-bets"
        ]
      }
    },
    "/bento/leaderboard/creators": {
      "get": {
        "operationId": "LeaderboardController_getCreators",
        "parameters": [
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "default": "usdc",
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 200,
              "default": 10,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Paginated creator leaderboard.",
        "tags": [
          "leaderboard"
        ]
      }
    },
    "/bento/leaderboard/traders": {
      "get": {
        "operationId": "LeaderboardController_getTraders",
        "parameters": [
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "default": "usdc",
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 200,
              "default": 10,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Paginated trader leaderboard.",
        "tags": [
          "leaderboard"
        ]
      }
    },
    "/bento/leaderboard/global-aggregate": {
      "get": {
        "operationId": "LeaderboardController_getGlobalAggregate",
        "parameters": [
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "default": "usdc",
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 200,
              "default": 10,
              "type": "number"
            }
          },
          {
            "name": "chartPeriod",
            "required": false,
            "in": "query",
            "schema": {
              "default": "all",
              "type": "string",
              "enum": [
                "all",
                "24h",
                "7d",
                "30d"
              ]
            }
          },
          {
            "name": "search",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sortBy",
            "required": false,
            "in": "query",
            "schema": {
              "default": "pnl",
              "type": "string",
              "enum": [
                "pnl",
                "volume"
              ]
            }
          },
          {
            "name": "sortOrder",
            "required": false,
            "in": "query",
            "schema": {
              "default": "desc",
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Platform-wide stats + chart + merged PnL leaderboard.",
        "tags": [
          "leaderboard"
        ]
      }
    },
    "/bento/leaderboard/creators/pnl": {
      "get": {
        "operationId": "LeaderboardController_getCreatorPnl",
        "parameters": [
          {
            "name": "address",
            "required": true,
            "in": "query",
            "description": "User wallet address.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "default": "usdc",
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "PnL for a single creator address.",
        "tags": [
          "leaderboard"
        ]
      }
    },
    "/bento/leaderboard/traders/pnl": {
      "get": {
        "operationId": "LeaderboardController_getTraderPnl",
        "parameters": [
          {
            "name": "address",
            "required": true,
            "in": "query",
            "description": "User wallet address.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "default": "usdc",
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "PnL for a single trader address.",
        "tags": [
          "leaderboard"
        ]
      }
    },
    "/bento/leaderboard/creators/count": {
      "get": {
        "operationId": "LeaderboardController_getCreatorsCount",
        "parameters": [
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "default": "usdc",
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "default": 1,
              "type": "number"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 200,
              "default": 10,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Number of distinct creators for this stack.",
        "tags": [
          "leaderboard"
        ]
      }
    },
    "/bento/leaderboard/chart/volume": {
      "get": {
        "operationId": "LeaderboardController_getVolumeChart",
        "parameters": [
          {
            "name": "period",
            "required": false,
            "in": "query",
            "schema": {
              "default": "7d",
              "type": "string",
              "enum": [
                "all",
                "24h",
                "7d",
                "30d"
              ]
            }
          },
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "default": "usdc",
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Cumulative volume time-series.",
        "tags": [
          "leaderboard"
        ]
      }
    },
    "/bento/leaderboard/chart/participants": {
      "get": {
        "operationId": "LeaderboardController_getParticipantsChart",
        "parameters": [
          {
            "name": "period",
            "required": false,
            "in": "query",
            "schema": {
              "default": "7d",
              "type": "string",
              "enum": [
                "all",
                "24h",
                "7d",
                "30d"
              ]
            }
          },
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "default": "usdc",
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Cumulative unique participants time-series.",
        "tags": [
          "leaderboard"
        ]
      }
    },
    "/bento/referral-earnings/{address}/summary": {
      "get": {
        "operationId": "ReferralEarningsController_summary",
        "parameters": [
          {
            "name": "address",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Total referral fees earned by an address, per collateral + per surface.",
        "tags": [
          "referral-earnings"
        ]
      }
    },
    "/bento/referral-earnings/{address}/recent": {
      "get": {
        "operationId": "ReferralEarningsController_recent",
        "parameters": [
          {
            "name": "address",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Recent referral fee payouts for an address.",
        "tags": [
          "referral-earnings"
        ]
      }
    },
    "/bento/user/portfolio/accountDetails": {
      "post": {
        "operationId": "PortfolioController_getAccountDetails",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PortfolioAddressBodyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Portfolio KPI summary for a user.",
        "tags": [
          "portfolio"
        ]
      }
    },
    "/bento/user/portfolio/duels": {
      "post": {
        "operationId": "PortfolioController_getDuels",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PortfolioAddressBodyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Duels created by the user + pending approvals.",
        "tags": [
          "portfolio"
        ]
      }
    },
    "/bento/user/portfolio/table/duels": {
      "post": {
        "operationId": "PortfolioController_getTableDuels",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PortfolioAddressBodyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Open bets table (yes/no split) for the user.",
        "tags": [
          "portfolio"
        ]
      }
    },
    "/bento/user/portfolio/pnl-chart": {
      "post": {
        "operationId": "PortfolioController_getPnlChart",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PortfolioPnlChartBodyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "PnL chart series (from PnlSnapshot).",
        "tags": [
          "portfolio"
        ]
      }
    },
    "/bento/user/portfolio/table/history": {
      "post": {
        "operationId": "PortfolioController_getTableHistory",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PortfolioAddressBodyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Historical (settled) bets table for the user.",
        "tags": [
          "portfolio"
        ]
      }
    },
    "/bento/user/portfolio/positions/{address}": {
      "get": {
        "operationId": "PortfolioController_getPositions",
        "parameters": [
          {
            "name": "address",
            "required": true,
            "in": "path",
            "description": "User wallet address.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "default": "usdc",
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Open positions with LMSR-based current valuation and unrealised PnL.",
        "tags": [
          "portfolio"
        ]
      }
    },
    "/bento/auto-mint/mint": {
      "post": {
        "operationId": "AutoMintController_mint",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AutoMintRequestDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Mint testnet tokens (or mainnet Credits).",
        "tags": [
          "auto-mint"
        ]
      }
    },
    "/bento/auto-mint/status": {
      "get": {
        "operationId": "AutoMintController_status",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Auto-mint service readiness + balances.",
        "tags": [
          "auto-mint"
        ]
      }
    },
    "/bento/user/image/generate": {
      "post": {
        "operationId": "ImageController_generate",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateImageDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Generate a Bento-themed, text-free market cover image with AI.",
        "tags": [
          "image"
        ]
      }
    },
    "/bento/agent-action/withdraw": {
      "post": {
        "operationId": "AgentController_withdraw",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentWithdrawBodyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "AgentAccessCode": []
          }
        ],
        "summary": "Withdraw USDC/Credits to an external wallet.",
        "tags": [
          "agent"
        ]
      }
    },
    "/bento/agent-action/withdraw/balance": {
      "get": {
        "operationId": "AgentController_getBalance",
        "parameters": [
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          },
          {
            "name": "collateralMode",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "AgentAccessCode": []
          }
        ],
        "summary": "Agent wallet collateral balance.",
        "tags": [
          "agent"
        ]
      }
    },
    "/bento/agent-action/withdraw/market-winnings": {
      "get": {
        "operationId": "AgentController_getMarketWinnings",
        "parameters": [
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          },
          {
            "name": "collateralMode",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "AgentAccessCode": []
          }
        ],
        "summary": "Claimable market winnings for the agent.",
        "tags": [
          "agent"
        ]
      }
    },
    "/bento/agent-action/withdraw/claim-winnings": {
      "post": {
        "operationId": "AgentController_claimWinnings",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentClaimWinningsBodyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "AgentAccessCode": []
          }
        ],
        "summary": "Claim on-chain market winnings.",
        "tags": [
          "agent"
        ]
      }
    },
    "/bento/agent-action/withdraw/creator-fees": {
      "get": {
        "operationId": "AgentController_getCreatorFees",
        "parameters": [
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          },
          {
            "name": "collateralMode",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "AgentAccessCode": []
          }
        ],
        "summary": "Claimable creator fees for the agent.",
        "tags": [
          "agent"
        ]
      }
    },
    "/bento/agent-action/withdraw/claim-fees": {
      "post": {
        "operationId": "AgentController_claimFees",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentClaimFeesBodyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "AgentAccessCode": []
          }
        ],
        "summary": "Claim all creator fees for the agent.",
        "tags": [
          "agent"
        ]
      }
    },
    "/bento/agent-action/markets": {
      "get": {
        "operationId": "AgentController_listMarkets",
        "parameters": [
          {
            "name": "collateralStack",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          },
          {
            "name": "collateralMode",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "usdc",
                "credits"
              ]
            }
          },
          {
            "name": "category",
            "required": false,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "default": "100",
              "type": "string"
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "schema": {
              "default": "0",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "AgentAccessCode": []
          }
        ],
        "summary": "List active + bootstrap markets (agent view).",
        "tags": [
          "agent"
        ]
      }
    },
    "/bento/agent-action/markets/{marketId}": {
      "get": {
        "operationId": "AgentController_getMarket",
        "parameters": [
          {
            "name": "marketId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "AgentAccessCode": []
          }
        ],
        "summary": "Market details + agent participation flag.",
        "tags": [
          "agent"
        ]
      }
    },
    "/bento/agent-action/markets/{marketId}/price-state": {
      "get": {
        "operationId": "AgentController_getPriceState",
        "parameters": [
          {
            "name": "marketId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "AgentAccessCode": []
          }
        ],
        "summary": "Pricing-engine state for a market.",
        "tags": [
          "agent"
        ]
      }
    },
    "/bento/agent-action/create-market": {
      "post": {
        "operationId": "AgentController_createMarket",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentCreateMarketBodyDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "AgentAccessCode": []
          }
        ],
        "summary": "Create a prediction or versus market.",
        "tags": [
          "agent"
        ]
      }
    },
    "/bento/agent-action/bet/estimate-buy": {
      "post": {
        "operationId": "AgentController_estimateBuy",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentEstimateBuyBodyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "AgentAccessCode": []
          }
        ],
        "summary": "Quote a buy order without executing.",
        "tags": [
          "agent"
        ]
      }
    },
    "/bento/agent-action/bet": {
      "post": {
        "operationId": "AgentController_buy",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentBuyBodyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "AgentAccessCode": []
          }
        ],
        "summary": "Place a bet on a market (buy shares).",
        "tags": [
          "agent"
        ]
      }
    },
    "/bento/agent-action/bet/estimate-sell": {
      "post": {
        "operationId": "AgentController_estimateSell",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentEstimateSellBodyDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "AgentAccessCode": []
          }
        ],
        "summary": "Quote a sell order without executing.",
        "tags": [
          "agent"
        ]
      }
    },
    "/bento/agent-action/bet/sell": {
      "post": {
        "operationId": "AgentController_sell",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentSellBodyDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "AgentAccessCode": []
          }
        ],
        "summary": "Sell shares from an existing position.",
        "tags": [
          "agent"
        ]
      }
    },
    "/bento/user/polymarket/derive-credentials": {
      "post": {
        "operationId": "PolymarketAuthController_deriveCredentials",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeriveCredentialsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Credentials derived and persisted."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Derive Polymarket CLOB L2 credentials.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/deploy-wallet": {
      "post": {
        "operationId": "PolymarketAuthController_deployWallet",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Deploy (or return) the user Polymarket deposit wallet.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/deploy-safe": {
      "post": {
        "operationId": "PolymarketAuthController_deploySafe",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Alias for deploy-wallet (legacy Express path).",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/auth-status": {
      "get": {
        "operationId": "PolymarketAuthController_authStatus",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Check Polymarket auth status for the user.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/refresh-credentials": {
      "post": {
        "operationId": "PolymarketAuthController_refreshCredentials",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Invalidate cached CLOB credentials.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/wallet-status": {
      "get": {
        "operationId": "PolymarketAuthController_walletStatus",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get Polymarket deposit-wallet deployment status.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/safe-status": {
      "get": {
        "operationId": "PolymarketAuthController_safeStatus",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Alias for wallet-status (legacy Express path).",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/approval-status": {
      "get": {
        "operationId": "PolymarketAuthController_approvalStatus",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get on-chain ERC-20/ERC-1155 approval status for trading.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/approve-trading": {
      "post": {
        "operationId": "PolymarketAuthController_approveTrading",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Submit missing approval transactions via the gasless relayer.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/place-order": {
      "post": {
        "operationId": "PolymarketOrdersController_placeOrder",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlaceOrderDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Order submitted."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Place an order on the Polymarket CLOB.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/cancel-order/{orderId}": {
      "delete": {
        "operationId": "PolymarketOrdersController_cancelOrder",
        "parameters": [
          {
            "name": "orderId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel a single open order by id.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/cancel-all": {
      "delete": {
        "operationId": "PolymarketOrdersController_cancelAll",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Cancel all open orders for the authenticated user.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/tick-size": {
      "get": {
        "operationId": "PolymarketOrdersController_getTickSize",
        "parameters": [
          {
            "name": "tokenId",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Minimum price tick for a CLOB token.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/orders": {
      "get": {
        "operationId": "PolymarketOrdersController_listOrders",
        "parameters": [
          {
            "name": "market",
            "required": false,
            "in": "query",
            "description": "Filter orders by market conditionId.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List open orders for the user (optionally filtered).",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/positions": {
      "get": {
        "operationId": "PolymarketPositionsController_getPositions",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List Polymarket positions for the user.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/trades": {
      "get": {
        "operationId": "PolymarketPositionsController_getTrades",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List closed Polymarket positions (realized PnL) for the user.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/polymarket/profile/{wallet}/positions": {
      "get": {
        "operationId": "PolymarketProfileController_getPositions",
        "parameters": [
          {
            "name": "wallet",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Public: Polymarket positions for any wallet.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/polymarket/profile/{wallet}/trades": {
      "get": {
        "operationId": "PolymarketProfileController_getTrades",
        "parameters": [
          {
            "name": "wallet",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Public: closed Polymarket positions (realized) for any wallet.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/deposit": {
      "post": {
        "operationId": "PolymarketDepositWithdrawController_getDepositAddresses",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Fetch bridge deposit addresses for the user deposit wallet.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/deposit-status/{address}": {
      "get": {
        "operationId": "PolymarketDepositWithdrawController_getDepositStatus",
        "parameters": [
          {
            "name": "address",
            "required": true,
            "in": "path",
            "description": "EVM address (0x-prefixed).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Query bridge deposit status for a target address.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/balance": {
      "get": {
        "operationId": "PolymarketDepositWithdrawController_getBalance",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Fetch Polymarket + on-chain USDC.e balances.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/withdraw-clob": {
      "post": {
        "operationId": "PolymarketDepositWithdrawController_withdrawClob",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Sync CLOB-reported balance into on-chain deposit-wallet balance.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/withdraw": {
      "post": {
        "operationId": "PolymarketDepositWithdrawController_withdraw",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WithdrawDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Withdraw pUSD/USDC.e from the deposit wallet to BSC via the Polymarket bridge.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/wrap-legacy-collateral": {
      "post": {
        "operationId": "PolymarketDepositWithdrawController_wrapLegacyCollateral",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Wrap USDC.e on the deposit wallet to pUSD via Collateral Onramp (CLOB V2 collateral migration).",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/redeem": {
      "post": {
        "operationId": "PolymarketDepositWithdrawController_redeemResolved",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Redeem resolved Polymarket positions via gasless relayer (deposit wallet). Idempotent.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/polygon-balances": {
      "get": {
        "operationId": "PolymarketDepositWithdrawController_getPolygonBalances",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get Polygon pUSD/USDC.e balances for the EOA + deposit wallet.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/recover-funds": {
      "post": {
        "operationId": "PolymarketDepositWithdrawController_recoverFunds",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecoverFundsDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Emergency-sweep pUSD from the Polymarket EOA to a destination address.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/relayer-tx/{txId}": {
      "get": {
        "operationId": "PolymarketDepositWithdrawController_getRelayerTx",
        "parameters": [
          {
            "name": "txId",
            "required": true,
            "in": "path",
            "description": "Polymarket relayer transaction id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Get status of a relayer transaction by id.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/discovery/sports-map": {
      "get": {
        "operationId": "PolymarketDiscoveryController_getSportsMap",
        "parameters": [
          {
            "name": "maxSubcategories",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Sports filter map derived from Gamma /sports (category + max 7 subcategories + Others).",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/discovery/events-by-tags": {
      "get": {
        "operationId": "PolymarketDiscoveryController_getEventsByTags",
        "parameters": [
          {
            "name": "limit",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Fetch Gamma events and markets for selected tag IDs (cached).",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/discovery/card-prices": {
      "post": {
        "operationId": "PolymarketDiscoveryController_getCardPrices",
        "parameters": [],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "One-shot CLOB best bid/ask for market cards (upcoming / other markets). Fetched on page load, not polled.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/discovery/live-scores": {
      "get": {
        "operationId": "PolymarketDiscoveryController_getLiveScores",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Current live sports scores from the Polymarket sports WebSocket feed.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/discovery/public-search": {
      "get": {
        "operationId": "PolymarketDiscoveryController_search",
        "parameters": [
          {
            "name": "q",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limitPerType",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Search events via Gamma public-search scoped by selected sports tag IDs.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/copytrade/subscribe": {
      "post": {
        "operationId": "CopyTradeController_subscribe",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CopyTradeSubscribeDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Subscription created/updated."
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Subscribe to copy-trade a leader wallet.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/copytrade/pause": {
      "post": {
        "operationId": "CopyTradeController_pause",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CopyTradeLeaderDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Pause copy-trading a leader (mirroring stops).",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/copytrade/resume": {
      "post": {
        "operationId": "CopyTradeController_resume",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CopyTradeLeaderDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Resume copy-trading a paused leader.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/copytrade/stop": {
      "post": {
        "operationId": "CopyTradeController_stop",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CopyTradeLeaderDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Stop copy-trading a leader.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/copytrade/liquidate": {
      "post": {
        "operationId": "CopyTradeController_liquidate",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CopyTradeLiquidateDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Close all open copied positions for a leader at market (optionally stop).",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/copytrade/list": {
      "get": {
        "operationId": "CopyTradeController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "List the caller copy-trade subscriptions.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/copytrade/copied-tokens": {
      "get": {
        "operationId": "CopyTradeController_copiedTokens",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "TokenIds the caller currently holds via copy-trade (Copied badge).",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/user/polymarket/copytrade/status": {
      "get": {
        "operationId": "CopyTradeController_status",
        "parameters": [
          {
            "name": "leader",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Whether the caller is following a given leader, with allocation.",
        "tags": [
          "polymarket"
        ]
      }
    },
    "/bento/packs": {
      "get": {
        "operationId": "PackController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "List packs for discovery",
        "tags": [
          "packs"
        ]
      }
    },
    "/bento/packs/{id}/leaderboard": {
      "get": {
        "operationId": "PackController_leaderboard",
        "parameters": [
          {
            "name": "limit",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "packs"
        ]
      }
    },
    "/bento/packs/{id}/me": {
      "get": {
        "operationId": "PackController_me",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "packs"
        ]
      }
    },
    "/bento/packs/{id}/payout-proof": {
      "get": {
        "operationId": "PackController_payoutProof",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "packs"
        ]
      }
    },
    "/bento/packs/{id}/payout-summary": {
      "get": {
        "operationId": "PackController_payoutSummary",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "packs"
        ]
      }
    },
    "/bento/packs/{id}/refund-proof": {
      "get": {
        "operationId": "PackController_refundProof",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "packs"
        ]
      }
    },
    "/bento/packs/{id}/refund-summary": {
      "get": {
        "operationId": "PackController_refundSummary",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "packs"
        ]
      }
    },
    "/bento/packs/{id}/price-history-snapshots": {
      "get": {
        "operationId": "PackController_priceHistory",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "packs"
        ]
      }
    },
    "/bento/packs/{id}": {
      "get": {
        "operationId": "PackController_get",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "tags": [
          "packs"
        ]
      }
    },
    "/bento/packs/{id}/enter": {
      "post": {
        "operationId": "PackController_enter",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnterPackDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "packs"
        ]
      }
    },
    "/bento/packs/{id}/picks/estimate": {
      "post": {
        "operationId": "PackController_estimatePick",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EstimatePackPickDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "packs"
        ]
      }
    },
    "/bento/packs/{id}/picks": {
      "post": {
        "operationId": "PackController_placePick",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlacePackPickDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "packs"
        ]
      }
    },
    "/bento/packs/creator/packs": {
      "post": {
        "operationId": "PackCreatorController_createPack",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePackDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Create a user-owned pack",
        "tags": [
          "pack creator"
        ]
      }
    },
    "/bento/packs/creator/packs/{id}/markets": {
      "post": {
        "operationId": "PackCreatorController_addMarket",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddPackMarketDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Add a market to a user-owned pack",
        "tags": [
          "pack creator"
        ]
      }
    },
    "/bento/packs/creator/packs/{id}/publish": {
      "post": {
        "operationId": "PackCreatorController_publish",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Publish a user-owned pack",
        "tags": [
          "pack creator"
        ]
      }
    },
    "/bento/analytics/platform": {
      "get": {
        "operationId": "AnalyticsController_getPlatformAnalytics",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "summary": "Cross-product platform analytics (participants, volume, activity per stack).",
        "tags": [
          "analytics"
        ]
      }
    },
    "/bento/resolution/resolve-duel/{duelId}": {
      "post": {
        "operationId": "ResolutionController_resolveDuel",
        "parameters": [
          {
            "name": "duelId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": ""
          }
        },
        "summary": "Resolve one duel via the automated resolver (internal).",
        "tags": [
          "resolution"
        ]
      }
    },
    "/bento/user/resolution-rules/generate": {
      "post": {
        "operationId": "ResolutionRuleController_generate",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateRulesDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Generate standardized resolution rules + ruleSpec for a market.",
        "tags": [
          "resolution-rules"
        ]
      }
    }
  },
  "info": {
    "title": "Bento Backend",
    "description": "Bento.fun core backend API: duels, bets, portfolios, admin, agents",
    "version": "1.0",
    "contact": {}
  },
  "tags": [],
  "servers": [],
  "components": {
    "securitySchemes": {
      "bearer": {
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "type": "http"
      }
    },
    "schemas": {
      "EoaLoginDto": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7"
          },
          "signature": {
            "type": "string",
            "description": "Signature over the SIWE message from POST /user/auth/eoa/challenge (Bento Sign-In + Domain/Builder)."
          },
          "timestamp": {
            "type": "string",
            "description": "Millisecond timestamp embedded in the signed message"
          },
          "domain": {
            "type": "string",
            "example": "app.bento.fun",
            "description": "Same domain used when building the signed message"
          }
        },
        "required": [
          "address",
          "signature",
          "timestamp",
          "domain"
        ],
        "summary": "Login with an EOA-signed SIWE message (tenant-scoped to the builder key)"
      },
      "EoaRegisterDto": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7"
          },
          "signature": {
            "type": "string"
          },
          "timestamp": {
            "type": "string"
          },
          "username": {
            "type": "string",
            "minLength": 3,
            "maxLength": 30,
            "example": "alice_91",
            "description": "Letters, digits, hyphens, underscores"
          },
          "inviteCode": {
            "type": "string",
            "example": "ABCDE12345"
          },
          "domain": {
            "type": "string",
            "example": "app.bento.fun",
            "description": "Same domain used when building the signed message"
          }
        },
        "required": [
          "address",
          "signature",
          "timestamp",
          "domain",
          "username"
        ]
      },
      "Auth0LoginDto": {
        "type": "object",
        "properties": {
          "auth0Token": {
            "type": "string",
            "description": "Auth0 access or id_token"
          },
          "tokenType": {
            "type": "string",
            "enum": [
              "id_token",
              "access_token"
            ]
          }
        },
        "required": [
          "auth0Token"
        ]
      },
      "Auth0RegisterDto": {
        "type": "object",
        "properties": {
          "auth0Token": {
            "type": "string",
            "description": "Auth0 access or id_token"
          },
          "tokenType": {
            "type": "string",
            "enum": [
              "id_token",
              "access_token"
            ]
          },
          "username": {
            "type": "string",
            "minLength": 3,
            "maxLength": 30
          },
          "inviteCode": {
            "type": "string"
          }
        },
        "required": [
          "auth0Token",
          "username"
        ]
      },
      "SignMessageDto": {
        "type": "object",
        "properties": {
          "message": {
            "description": "Message to sign. Either a string, or an object `{ raw: \"0x...\" }` for raw hex.",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "object",
                "properties": {
                  "raw": {
                    "type": "string"
                  }
                }
              }
            ]
          }
        },
        "required": [
          "message"
        ]
      },
      "SignTypedDataDto": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "object",
            "description": "EIP-712 domain"
          },
          "types": {
            "type": "object",
            "description": "EIP-712 types"
          },
          "primaryType": {
            "type": "string",
            "description": "Primary type name"
          },
          "message": {
            "type": "object",
            "description": "Typed data message"
          }
        },
        "required": [
          "domain",
          "types",
          "primaryType",
          "message"
        ]
      },
      "SendTransactionDto": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string",
            "example": "0x0000000000000000000000000000000000000000"
          },
          "data": {
            "type": "string",
            "example": "0x"
          },
          "value": {
            "type": "string",
            "example": "0x0"
          }
        },
        "required": [
          "to",
          "data"
        ]
      },
      "RegisterSimpleDto": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7"
          }
        },
        "required": [
          "address"
        ]
      },
      "RegisterBulkDto": {
        "type": "object",
        "properties": {
          "addresses": {
            "maxItems": 200,
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "addresses"
        ]
      },
      "WithdrawDto": {
        "type": "object",
        "properties": {
          "amount": {
            "type": "string",
            "description": "USDC amount to withdraw, or the string \"max\".",
            "example": "10.5"
          }
        },
        "required": [
          "amount"
        ]
      },
      "ClaimWinningsDto": {
        "type": "object",
        "properties": {
          "amount": {
            "type": "string",
            "description": "Amount as raw bigint string"
          },
          "collateralStack": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          },
          "collateralMode": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          }
        },
        "required": [
          "amount"
        ]
      },
      "ClaimFeesDto": {
        "type": "object",
        "properties": {
          "collateralStack": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          },
          "collateralMode": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          }
        }
      },
      "PresignedUrlDto": {
        "type": "object",
        "properties": {
          "fileName": {
            "type": "string",
            "description": "File name (safe characters only)."
          },
          "fileType": {
            "type": "string",
            "description": "MIME type, e.g. image/png."
          },
          "userAddress": {
            "type": "string",
            "maxLength": 128
          }
        },
        "required": [
          "fileName",
          "fileType"
        ]
      },
      "CreateDuelDto": {
        "type": "object",
        "properties": {
          "question": {
            "type": "string",
            "maxLength": 140
          },
          "type": {
            "type": "string",
            "enum": [
              "prediction",
              "versus"
            ]
          },
          "category": {
            "type": "string",
            "description": "Sport category (e.g. Cricket, Football)"
          },
          "description": {
            "type": "string"
          },
          "optionA": {
            "type": "string",
            "description": "Versus option A"
          },
          "optionB": {
            "type": "string",
            "description": "Versus option B"
          },
          "coverImageUrl": {
            "type": "string"
          },
          "startTime": {
            "type": "string",
            "description": "ISO 8601 UTC datetime"
          },
          "endTime": {
            "type": "string",
            "description": "ISO 8601 UTC datetime"
          },
          "privacyAccess": {
            "type": "string",
            "enum": [
              "public",
              "private"
            ],
            "default": "public"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "collateralMode": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ],
            "default": "usdc"
          },
          "leagueId": {
            "type": "string",
            "maxLength": 128
          },
          "ruleSpec": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "question",
          "type",
          "category",
          "startTime",
          "endTime"
        ]
      },
      "CreateDuelResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "duelId": {
            "type": "string",
            "example": "duel_abc123"
          },
          "txHash": {
            "type": "string",
            "example": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
          },
          "message": {
            "type": "string",
            "example": "Successfully created prediction market: Will Team A win?"
          }
        },
        "required": [
          "success",
          "duelId",
          "txHash",
          "message"
        ]
      },
      "SubmitContestDto": {
        "type": "object",
        "properties": {
          "duelId": {
            "type": "string"
          },
          "contestType": {
            "type": "string",
            "enum": [
              "favor",
              "against"
            ]
          },
          "contestedOption": {
            "type": "number",
            "minimum": 0
          },
          "reason": {
            "type": "string",
            "maxLength": 1000
          }
        },
        "required": [
          "duelId",
          "contestType",
          "contestedOption"
        ]
      },
      "FinalizeContestDto": {
        "type": "object",
        "properties": {
          "duelId": {
            "type": "string"
          },
          "finalWinningOptionIndex": {
            "type": "number",
            "description": "Index of the final winning option."
          }
        },
        "required": [
          "duelId",
          "finalWinningOptionIndex"
        ]
      },
      "ResolveDuelEntryDto": {
        "type": "object",
        "properties": {
          "duelId": {
            "type": "string"
          },
          "winningOptionIndex": {
            "type": "number",
            "minimum": 0
          },
          "userId": {
            "type": "string"
          }
        },
        "required": [
          "duelId",
          "winningOptionIndex"
        ]
      },
      "ResolveDuelDto": {
        "type": "object",
        "properties": {
          "duelIds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ResolveDuelEntryDto"
            }
          }
        },
        "required": [
          "duelIds"
        ]
      },
      "LiquiditySideDto": {
        "type": "object",
        "properties": {
          "tokenAddress": {
            "type": "string"
          },
          "tokenAmount": {
            "type": "number"
          },
          "usdcAmount": {
            "type": "number"
          }
        },
        "required": [
          "tokenAmount",
          "usdcAmount"
        ]
      },
      "LiquidityBreakdownDto": {
        "type": "object",
        "properties": {
          "option0": {
            "$ref": "#/components/schemas/LiquiditySideDto"
          },
          "option1": {
            "$ref": "#/components/schemas/LiquiditySideDto"
          }
        },
        "required": [
          "option0",
          "option1"
        ]
      },
      "PublicDuelSummaryDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "duelId": {
            "type": "string"
          },
          "createdAt": {
            "type": "number"
          },
          "startAt": {
            "type": "number",
            "nullable": true
          },
          "startTime": {
            "type": "number",
            "nullable": true
          },
          "endTime": {
            "type": "number",
            "nullable": true
          },
          "category": {
            "type": "string"
          },
          "betString": {
            "type": "string"
          },
          "status": {
            "type": "number"
          },
          "betIcon": {
            "type": "string",
            "nullable": true
          },
          "duelType": {
            "type": "string"
          },
          "endsIn": {
            "type": "number"
          },
          "winner": {
            "type": "number"
          },
          "associatedTokens": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "leagueId": {
            "type": "string",
            "nullable": true
          },
          "options": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "privacyAccess": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "collateralMode": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          },
          "contestPeriodEndTime": {
            "type": "number",
            "nullable": true
          },
          "contestStatus": {
            "type": "string",
            "nullable": true
          },
          "totalBetAmount": {
            "type": "number"
          },
          "totalBetAmountUSDC": {
            "type": "number"
          },
          "totalBetAmountUsdc": {
            "type": "number"
          },
          "uniqueParticipants": {
            "type": "number"
          },
          "liquidityBreakdown": {
            "$ref": "#/components/schemas/LiquidityBreakdownDto"
          },
          "parentMarketId": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "duelId",
          "createdAt",
          "category",
          "betString",
          "status",
          "duelType",
          "endsIn",
          "winner",
          "options",
          "privacyAccess",
          "tags",
          "totalBetAmount",
          "totalBetAmountUSDC",
          "totalBetAmountUsdc",
          "uniqueParticipants",
          "liquidityBreakdown"
        ]
      },
      "PaginationDto": {
        "type": "object",
        "properties": {
          "total": {
            "type": "number"
          },
          "limit": {
            "type": "number"
          },
          "offset": {
            "type": "number"
          },
          "hasMore": {
            "type": "boolean"
          }
        },
        "required": [
          "total",
          "limit",
          "offset",
          "hasMore"
        ]
      },
      "ListPublicDuelsResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicDuelSummaryDto"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/PaginationDto"
          }
        },
        "required": [
          "success",
          "data",
          "pagination"
        ]
      },
      "DuelUserPreviewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "auth0Username": {
            "type": "string",
            "nullable": true
          },
          "auth0ImageUrl": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id"
        ]
      },
      "DuelBetOptionPreviewDto": {
        "type": "object",
        "properties": {
          "index": {
            "type": "number"
          },
          "amount": {
            "type": "string",
            "nullable": true
          },
          "amountUSDC": {
            "type": "string",
            "nullable": true
          },
          "quantity": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "index"
        ]
      },
      "DuelBetPreviewDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "userId": {
            "type": "string"
          },
          "totalBetAmount": {
            "type": "string",
            "nullable": true
          },
          "totalBetAmountUSDC": {
            "type": "string",
            "nullable": true
          },
          "options": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DuelBetOptionPreviewDto"
            }
          },
          "user": {
            "$ref": "#/components/schemas/DuelUserPreviewDto"
          }
        },
        "required": [
          "id",
          "userId",
          "options"
        ]
      },
      "PublicDuelDetailDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "duelId": {
            "type": "string"
          },
          "createdAt": {
            "type": "number"
          },
          "startAt": {
            "type": "number",
            "nullable": true
          },
          "startTime": {
            "type": "number",
            "nullable": true
          },
          "endTime": {
            "type": "number",
            "nullable": true
          },
          "category": {
            "type": "string"
          },
          "betString": {
            "type": "string"
          },
          "status": {
            "type": "number"
          },
          "betIcon": {
            "type": "string",
            "nullable": true
          },
          "duelType": {
            "type": "string"
          },
          "endsIn": {
            "type": "number"
          },
          "winner": {
            "type": "number"
          },
          "associatedTokens": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "leagueId": {
            "type": "string",
            "nullable": true
          },
          "options": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "privacyAccess": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "collateralMode": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          },
          "contestPeriodEndTime": {
            "type": "number",
            "nullable": true
          },
          "contestStatus": {
            "type": "string",
            "nullable": true
          },
          "totalBetAmount": {
            "type": "number"
          },
          "totalBetAmountUSDC": {
            "type": "number"
          },
          "totalBetAmountUsdc": {
            "type": "number"
          },
          "uniqueParticipants": {
            "type": "number"
          },
          "liquidityBreakdown": {
            "$ref": "#/components/schemas/LiquidityBreakdownDto"
          },
          "parentMarketId": {
            "type": "string",
            "nullable": true
          },
          "userParticipated": {
            "type": "boolean"
          },
          "user": {
            "$ref": "#/components/schemas/DuelUserPreviewDto"
          },
          "bets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DuelBetPreviewDto"
            }
          }
        },
        "required": [
          "id",
          "duelId",
          "createdAt",
          "category",
          "betString",
          "status",
          "duelType",
          "endsIn",
          "winner",
          "options",
          "privacyAccess",
          "tags",
          "totalBetAmount",
          "totalBetAmountUSDC",
          "totalBetAmountUsdc",
          "uniqueParticipants",
          "liquidityBreakdown",
          "userParticipated"
        ]
      },
      "CreateDuelInvitationDto": {
        "type": "object",
        "properties": {
          "duelId": {
            "type": "string"
          },
          "inviteCode": {
            "type": "string",
            "example": "ABCDE12345",
            "description": "Alphanumeric invite code"
          },
          "expiresAt": {
            "type": "number",
            "description": "UNIX timestamp (seconds). 0 or omitted = never expires"
          },
          "maxUses": {
            "type": "number",
            "description": "Maximum redemptions. 0 or omitted = unlimited"
          },
          "inviterAddress": {
            "type": "string"
          }
        },
        "required": [
          "duelId",
          "inviteCode",
          "inviterAddress"
        ]
      },
      "JoinDuelDto": {
        "type": "object",
        "properties": {
          "inviteCode": {
            "type": "string"
          },
          "walletAddress": {
            "type": "string"
          }
        },
        "required": [
          "inviteCode",
          "walletAddress"
        ]
      },
      "UserJoinDuelDto": {
        "type": "object",
        "properties": {
          "inviteCode": {
            "type": "string"
          }
        },
        "required": [
          "inviteCode"
        ]
      },
      "DuelMemberMutationDto": {
        "type": "object",
        "properties": {
          "duelId": {
            "type": "string"
          },
          "userAddress": {
            "type": "string"
          }
        },
        "required": [
          "duelId",
          "userAddress"
        ]
      },
      "ValidateInviteDto": {
        "type": "object",
        "properties": {
          "inviteCode": {
            "type": "string"
          },
          "userAddress": {
            "type": "string"
          }
        },
        "required": [
          "inviteCode",
          "userAddress"
        ]
      },
      "SyncJoinSuccessDto": {
        "type": "object",
        "properties": {
          "inviteCode": {
            "type": "string"
          },
          "userAddress": {
            "type": "string"
          },
          "txHash": {
            "type": "string"
          }
        },
        "required": [
          "inviteCode",
          "userAddress"
        ]
      },
      "RevokeInviteDto": {
        "type": "object",
        "properties": {
          "inviteCode": {
            "type": "string"
          }
        },
        "required": [
          "inviteCode"
        ]
      },
      "ParentMarketChildDto": {
        "type": "object",
        "properties": {
          "question": {
            "type": "string",
            "maxLength": 140
          },
          "type": {
            "type": "string",
            "enum": [
              "prediction",
              "versus"
            ]
          },
          "category": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "optionA": {
            "type": "string"
          },
          "optionB": {
            "type": "string"
          },
          "coverImageUrl": {
            "type": "string"
          },
          "privacyAccess": {
            "type": "string",
            "enum": [
              "public",
              "private"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "collateralMode": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          }
        },
        "required": [
          "question",
          "type"
        ]
      },
      "CreateParentMarketDto": {
        "type": "object",
        "properties": {
          "parentQuestion": {
            "type": "string",
            "maxLength": 200
          },
          "description": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "coverImageUrl": {
            "type": "string"
          },
          "startTime": {
            "type": "string"
          },
          "endTime": {
            "type": "string"
          },
          "privacyAccess": {
            "type": "string",
            "enum": [
              "public",
              "private"
            ],
            "default": "public"
          },
          "markets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ParentMarketChildDto"
            }
          },
          "collateralMode": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          },
          "groupKind": {
            "type": "string",
            "enum": [
              "multi",
              "pack"
            ]
          }
        },
        "required": [
          "parentQuestion",
          "category",
          "startTime",
          "endTime",
          "markets"
        ]
      },
      "ParentMarketPartialDuelErrorDto": {
        "type": "object",
        "properties": {
          "index": {
            "type": "number"
          },
          "error": {
            "type": "string"
          }
        },
        "required": [
          "index",
          "error"
        ]
      },
      "CreateParentMarketResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "parentMarketId": {
            "type": "string"
          },
          "duelIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "privacyAccess": {
            "type": "string",
            "enum": [
              "public",
              "private"
            ]
          },
          "inviteCode": {
            "type": "string"
          },
          "partialErrors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ParentMarketPartialDuelErrorDto"
            }
          }
        },
        "required": [
          "success",
          "parentMarketId",
          "duelIds",
          "privacyAccess"
        ]
      },
      "CreateParentMarketInvitationDto": {
        "type": "object",
        "properties": {
          "parentMarketId": {
            "type": "string"
          },
          "expiresAt": {
            "type": "number"
          },
          "maxUses": {
            "type": "number"
          }
        },
        "required": [
          "parentMarketId"
        ]
      },
      "CreateParentMarketInvitationResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "inviteCode": {
            "type": "string"
          },
          "parentMarketId": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "success",
          "inviteCode",
          "parentMarketId",
          "message"
        ]
      },
      "JoinParentMarketDto": {
        "type": "object",
        "properties": {
          "inviteCode": {
            "type": "string"
          }
        },
        "required": [
          "inviteCode"
        ]
      },
      "JoinParentMarketResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "alreadyMember": {
            "type": "boolean"
          },
          "parentMarketId": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "success",
          "parentMarketId",
          "message"
        ]
      },
      "AddChildDuelDto": {
        "type": "object",
        "properties": {
          "question": {
            "type": "string",
            "maxLength": 140
          },
          "type": {
            "type": "string",
            "enum": [
              "prediction",
              "versus"
            ]
          },
          "category": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "optionA": {
            "type": "string"
          },
          "optionB": {
            "type": "string"
          },
          "coverImageUrl": {
            "type": "string"
          },
          "privacyAccess": {
            "type": "string",
            "enum": [
              "public",
              "private"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "collateralMode": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          },
          "startTime": {
            "type": "string"
          },
          "endTime": {
            "type": "string"
          }
        },
        "required": [
          "question",
          "type",
          "startTime",
          "endTime"
        ]
      },
      "AddChildDuelResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "duelId": {
            "type": "string"
          },
          "txHash": {
            "type": "string"
          },
          "membershipPropagation": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "success",
          "duelId",
          "txHash"
        ]
      },
      "ValidateParentInviteDto": {
        "type": "object",
        "properties": {
          "inviteCode": {
            "type": "string"
          },
          "userAddress": {
            "type": "string"
          }
        },
        "required": [
          "inviteCode",
          "userAddress"
        ]
      },
      "BuyEstimateDto": {
        "type": "object",
        "properties": {
          "outcome": {
            "type": "string",
            "enum": [
              "yes",
              "no"
            ]
          },
          "usdc_in": {
            "type": "object"
          },
          "shares_out": {
            "type": "number"
          },
          "avg_price_paid": {
            "type": "number"
          },
          "current_yes_price": {
            "type": "number"
          },
          "current_no_price": {
            "type": "number"
          },
          "new_yes_price": {
            "type": "number"
          },
          "new_no_price": {
            "type": "number"
          },
          "price_impact": {
            "type": "number"
          },
          "min_shares_out": {
            "type": "number"
          },
          "quote_timestamp": {
            "type": "number"
          },
          "quote_id": {
            "type": "string"
          }
        },
        "required": [
          "outcome",
          "shares_out",
          "avg_price_paid",
          "current_yes_price",
          "current_no_price",
          "new_yes_price",
          "new_no_price",
          "price_impact",
          "min_shares_out",
          "quote_timestamp",
          "quote_id"
        ]
      },
      "EstimateBuySuccessResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "estimate": {
            "$ref": "#/components/schemas/BuyEstimateDto"
          }
        },
        "required": [
          "success",
          "estimate"
        ]
      },
      "EstimateBuyFailureResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "error": {
            "type": "string",
            "example": "User not found."
          }
        },
        "required": [
          "success",
          "error"
        ]
      },
      "SellEstimateDto": {
        "type": "object",
        "properties": {
          "outcome": {
            "type": "string",
            "enum": [
              "yes",
              "no"
            ]
          },
          "shares_in": {
            "type": "number"
          },
          "payout_usdc": {
            "type": "number"
          },
          "avg_fill_price": {
            "type": "number"
          },
          "current_price": {
            "type": "number"
          },
          "new_price": {
            "type": "number"
          },
          "price_impact": {
            "type": "number"
          },
          "min_payout_usdc": {
            "type": "number"
          },
          "quote_timestamp": {
            "type": "number"
          },
          "quote_id": {
            "type": "string"
          },
          "selling_allowed": {
            "type": "boolean",
            "example": true
          },
          "side_liquidity": {
            "type": "number"
          },
          "liquidity_limit": {
            "type": "number"
          },
          "total_market_liquidity": {
            "type": "number"
          },
          "unlock_threshold": {
            "type": "number"
          }
        },
        "required": [
          "outcome",
          "shares_in",
          "payout_usdc",
          "avg_fill_price",
          "current_price",
          "new_price",
          "price_impact",
          "min_payout_usdc",
          "quote_timestamp",
          "quote_id",
          "selling_allowed",
          "side_liquidity",
          "liquidity_limit",
          "total_market_liquidity",
          "unlock_threshold"
        ]
      },
      "EstimateSellSuccessResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "estimate": {
            "$ref": "#/components/schemas/SellEstimateDto"
          }
        },
        "required": [
          "success",
          "estimate"
        ]
      },
      "EstimateSellFailureResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "error": {
            "type": "string",
            "example": "User not found."
          }
        },
        "required": [
          "success",
          "error"
        ]
      },
      "CreateBetResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          }
        },
        "required": [
          "success"
        ]
      },
      "CreateBetFailureResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "error": {
            "type": "string",
            "example": "Slippage exceeded."
          }
        },
        "required": [
          "success"
        ]
      },
      "SellBetResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          }
        },
        "required": [
          "success"
        ]
      },
      "UserSharesBalanceDto": {
        "type": "object",
        "properties": {
          "option0": {
            "type": "number",
            "example": 0
          },
          "option1": {
            "type": "number",
            "example": 0
          }
        },
        "required": [
          "option0",
          "option1"
        ]
      },
      "GetUserSharesResponseDto": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "shares": {
            "$ref": "#/components/schemas/UserSharesBalanceDto"
          }
        },
        "required": [
          "success",
          "shares"
        ]
      },
      "GetSellUnlockLiquidityResponseDto": {
        "type": "object",
        "properties": {
          "selling_allowed": {
            "type": "boolean"
          },
          "total_market_liquidity": {
            "type": "number"
          },
          "unlock_threshold": {
            "type": "number"
          },
          "remaining_liquidity": {
            "type": "number"
          },
          "progress_percentage": {
            "type": "number"
          },
          "success": {
            "type": "boolean",
            "example": true
          }
        },
        "required": [
          "selling_allowed",
          "total_market_liquidity",
          "unlock_threshold",
          "remaining_liquidity",
          "progress_percentage",
          "success"
        ]
      },
      "ApiErrorResponseDto": {
        "type": "object",
        "properties": {
          "statusCode": {
            "type": "number",
            "example": 401
          },
          "message": {
            "type": "object",
            "example": "Authentication required"
          },
          "error": {
            "type": "string",
            "example": "Unauthorized"
          }
        },
        "required": [
          "statusCode",
          "message"
        ]
      },
      "EstimatedWinDto": {
        "type": "object",
        "properties": {
          "duelId": {
            "type": "string"
          },
          "sharesToMint": {
            "type": "string",
            "description": "Shares to be minted (as string for precision)."
          },
          "optionIndex": {
            "type": "number",
            "enum": [
              0,
              1
            ]
          }
        },
        "required": [
          "duelId",
          "sharesToMint",
          "optionIndex"
        ]
      },
      "EstimateBuyDto": {
        "type": "object",
        "properties": {
          "duelId": {
            "type": "string"
          },
          "optionIndex": {
            "type": "number",
            "enum": [
              0,
              1
            ]
          },
          "betAmountUsdc": {
            "type": "string",
            "description": "Bet amount in collateral token wei (as string to preserve precision)."
          },
          "slippageBps": {
            "type": "number",
            "description": "Slippage tolerance in basis points."
          }
        },
        "required": [
          "duelId",
          "optionIndex",
          "betAmountUsdc"
        ]
      },
      "EstimateSellDto": {
        "type": "object",
        "properties": {
          "duelId": {
            "type": "string"
          },
          "optionIndex": {
            "type": "number",
            "enum": [
              0,
              1
            ]
          },
          "sharesIn": {
            "type": "number",
            "description": "Shares to sell (as decimal number)."
          },
          "slippageBps": {
            "type": "number"
          }
        },
        "required": [
          "duelId",
          "optionIndex",
          "sharesIn"
        ]
      },
      "CreateBetDto": {
        "type": "object",
        "properties": {
          "duelId": {
            "type": "string",
            "description": "Internal market (duel) id."
          },
          "duelType": {
            "type": "string",
            "description": "Legacy duel type marker; forwarded to background jobs."
          },
          "bet": {
            "type": "string",
            "description": "Selected option label (e.g. optionA/optionB)."
          },
          "optionIndex": {
            "type": "number",
            "enum": [
              0,
              1
            ]
          },
          "betAmount": {
            "type": "string",
            "description": "Raw amount in token base units (string)."
          },
          "betAmountUsdc": {
            "type": "string",
            "description": "Amount in collateral wei (string)."
          },
          "tokenDecimals": {
            "type": "number"
          },
          "approveTokenAddress": {
            "type": "string"
          },
          "asset": {
            "type": "string"
          },
          "winCondition": {
            "type": "string"
          },
          "sharesOut": {
            "type": "number",
            "description": "Shares expected from last quote — used as upper bound for slippage."
          },
          "minSharesOut": {
            "type": "number",
            "description": "Minimum shares that must be received, else reject."
          },
          "slippageBps": {
            "type": "number",
            "description": "Slippage tolerance in basis points."
          },
          "quoteId": {
            "type": "string"
          },
          "quoteTimestamp": {
            "type": "number"
          },
          "collateralMode": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ],
            "description": "Collateral stack of the market being bet on. When \"credits\", geo-restrictions are bypassed."
          },
          "twitterUsername": {
            "type": "string",
            "description": "Legacy display field still sent by mobile clients (often empty). Accepted but unused — without it the global ValidationPipe (whitelist + forbidNonWhitelisted) rejected EVERY iOS buy with 400 \"property twitterUsername should not exist\"."
          }
        },
        "required": [
          "duelId",
          "duelType",
          "bet",
          "optionIndex",
          "betAmount",
          "betAmountUsdc",
          "sharesOut",
          "minSharesOut",
          "slippageBps"
        ]
      },
      "SellBetDto": {
        "type": "object",
        "properties": {
          "duelId": {
            "type": "string",
            "description": "Market (duel) id."
          },
          "duelType": {
            "type": "string"
          },
          "optionIndex": {
            "type": "number",
            "enum": [
              0,
              1
            ]
          },
          "sharesAmount": {
            "type": "string",
            "description": "Amount of shares to sell (decimal string)."
          },
          "minPayoutUsdc": {
            "type": "number",
            "description": "Minimum payout in collateral units (USDC)."
          },
          "payoutUsdc": {
            "type": "number",
            "description": "Expected payout in collateral units (USDC)."
          },
          "slippageBps": {
            "type": "number"
          },
          "quoteId": {
            "type": "string"
          },
          "quoteTimestamp": {
            "type": "number"
          },
          "collateralMode": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ],
            "description": "Collateral stack of the market being sold. When \"credits\", geo-restrictions are bypassed."
          }
        },
        "required": [
          "duelId",
          "duelType",
          "optionIndex",
          "sharesAmount",
          "minPayoutUsdc",
          "payoutUsdc",
          "slippageBps"
        ]
      },
      "PublicEstimateSellDto": {
        "type": "object",
        "properties": {
          "duelId": {
            "type": "string"
          },
          "optionIndex": {
            "type": "number",
            "enum": [
              0,
              1
            ]
          },
          "sharesIn": {
            "type": "number",
            "description": "Shares to sell (as decimal number)."
          },
          "slippageBps": {
            "type": "number"
          },
          "address": {
            "type": "string",
            "description": "Optional wallet address override."
          }
        },
        "required": [
          "duelId",
          "optionIndex",
          "sharesIn"
        ]
      },
      "PortfolioAddressBodyDto": {
        "type": "object",
        "properties": {
          "userAddress": {
            "type": "string",
            "description": "User wallet address."
          },
          "collateralStack": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ],
            "default": "usdc"
          }
        },
        "required": [
          "userAddress"
        ]
      },
      "PortfolioPnlChartBodyDto": {
        "type": "object",
        "properties": {
          "userAddress": {
            "type": "string",
            "description": "User wallet address."
          },
          "collateralStack": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ],
            "default": "usdc"
          },
          "period": {
            "type": "string",
            "description": "Window for PnL snapshots.",
            "enum": [
              "24h",
              "7d",
              "30d",
              "all",
              "All Time"
            ],
            "default": "7d"
          }
        },
        "required": [
          "userAddress"
        ]
      },
      "AutoMintRequestDto": {
        "type": "object",
        "properties": {
          "userAddress": {
            "type": "string",
            "description": "User wallet to mint to."
          },
          "chainId": {
            "type": "number",
            "description": "Chain id hint (currently unused)."
          }
        },
        "required": [
          "userAddress"
        ]
      },
      "GenerateImageDto": {
        "type": "object",
        "properties": {
          "question": {
            "type": "string",
            "description": "Market question / title — the main subject of the image."
          },
          "type": {
            "type": "string",
            "description": "Market type: 'prediction' or 'versus'."
          },
          "category": {
            "type": "string",
            "description": "Category / sport, e.g. Football, Crypto, Politics."
          },
          "optionA": {
            "type": "string",
            "description": "Option A label (versus markets)."
          },
          "optionB": {
            "type": "string",
            "description": "Option B label (versus markets)."
          },
          "description": {
            "type": "string",
            "description": "Resolution rules / description — extra context for the scene."
          }
        },
        "required": [
          "question"
        ]
      },
      "AdminLoginDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "example": "admin@bento.fun"
          },
          "password": {
            "type": "string"
          }
        },
        "required": [
          "email",
          "password"
        ]
      },
      "AdminVerifySetupDto": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "6-digit TOTP token."
          }
        },
        "required": [
          "token"
        ]
      },
      "AdminVerify2faDto": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "description": "TOTP token or backup code."
          },
          "isBackupCode": {
            "type": "boolean",
            "description": "Set to true if the supplied token is a backup code."
          }
        },
        "required": [
          "token"
        ]
      },
      "AdminPasswordConfirmDto": {
        "type": "object",
        "properties": {
          "password": {
            "type": "string"
          }
        },
        "required": [
          "password"
        ]
      },
      "CancelExpiredDuelsDto": {
        "type": "object",
        "properties": {
          "duelIds": {
            "description": "Duel IDs to cancel.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "cancelReason": {
            "type": "string",
            "description": "Admin-supplied reason for cancellation."
          }
        },
        "required": [
          "duelIds",
          "cancelReason"
        ]
      },
      "ProcessDurationDto": {
        "type": "object",
        "properties": {
          "duelIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "duelIds"
        ]
      },
      "AutoDistributeDto": {
        "type": "object",
        "properties": {
          "duelId": {
            "type": "string",
            "description": "Optional single duelId to distribute."
          }
        }
      },
      "DiscardDuelsDto": {
        "type": "object",
        "properties": {
          "duelIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "cancelReason": {
            "type": "string"
          }
        },
        "required": [
          "duelIds"
        ]
      },
      "WithdrawalDecisionDto": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "enum": [
              "approved",
              "rejected"
            ]
          }
        },
        "required": [
          "action"
        ]
      },
      "CreateInviteCodeDto": {
        "type": "object",
        "properties": {
          "walletAddress": {
            "type": "string",
            "description": "Admin wallet creating the invite code."
          },
          "customMaxUses": {
            "type": "number"
          },
          "expiresInDays": {
            "type": "number"
          }
        },
        "required": [
          "walletAddress"
        ]
      },
      "CreateBulkInviteCodesDto": {
        "type": "object",
        "properties": {
          "walletAddress": {
            "type": "string",
            "description": "Admin wallet creating the invite code."
          },
          "customMaxUses": {
            "type": "number"
          },
          "expiresInDays": {
            "type": "number"
          },
          "count": {
            "type": "number"
          }
        },
        "required": [
          "walletAddress",
          "count"
        ]
      },
      "AgentWithdrawBodyDto": {
        "type": "object",
        "properties": {
          "accessCode": {
            "type": "string",
            "description": "Agent access code."
          },
          "recipientAddress": {
            "type": "string"
          },
          "amount": {
            "type": "string",
            "description": "Amount in USDC (human readable, e.g. \"100.50\")."
          },
          "collateralStack": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          },
          "collateralMode": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          }
        },
        "required": [
          "accessCode",
          "recipientAddress",
          "amount"
        ]
      },
      "AgentClaimWinningsBodyDto": {
        "type": "object",
        "properties": {
          "accessCode": {
            "type": "string",
            "description": "Agent access code."
          },
          "amount": {
            "type": "string",
            "description": "Amount in smallest unit (wei)."
          },
          "collateralStack": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          },
          "collateralMode": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          }
        },
        "required": [
          "accessCode",
          "amount"
        ]
      },
      "AgentClaimFeesBodyDto": {
        "type": "object",
        "properties": {
          "accessCode": {
            "type": "string",
            "description": "Agent access code."
          },
          "collateralStack": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          },
          "collateralMode": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          }
        },
        "required": [
          "accessCode"
        ]
      },
      "AgentCreateMarketBodyDto": {
        "type": "object",
        "properties": {
          "accessCode": {
            "type": "string",
            "description": "Agent access code."
          },
          "question": {
            "type": "string",
            "maxLength": 140
          },
          "type": {
            "type": "string",
            "enum": [
              "prediction",
              "versus"
            ]
          },
          "category": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "optionA": {
            "type": "string"
          },
          "optionB": {
            "type": "string"
          },
          "coverImageUrl": {
            "type": "string"
          },
          "startTime": {
            "type": "string",
            "description": "ISO 8601 datetime."
          },
          "endTime": {
            "type": "string",
            "description": "ISO 8601 datetime."
          },
          "privacyAccess": {
            "type": "string",
            "enum": [
              "public",
              "private"
            ],
            "default": "public"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "collateralMode": {
            "type": "string",
            "enum": [
              "usdc",
              "credits"
            ]
          }
        },
        "required": [
          "accessCode",
          "question",
          "type",
          "category",
          "startTime",
          "endTime"
        ]
      },
      "AgentEstimateBuyBodyDto": {
        "type": "object",
        "properties": {
          "accessCode": {
            "type": "string",
            "description": "Agent access code."
          },
          "duelId": {
            "type": "string"
          },
          "optionIndex": {
            "type": "number",
            "enum": [
              0,
              1
            ]
          },
          "amount": {
            "type": "number",
            "minimum": 5
          },
          "slippageBps": {
            "type": "number",
            "default": 100
          }
        },
        "required": [
          "accessCode",
          "duelId",
          "optionIndex",
          "amount"
        ]
      },
      "AgentBuyBodyDto": {
        "type": "object",
        "properties": {
          "accessCode": {
            "type": "string",
            "description": "Agent access code."
          },
          "duelId": {
            "type": "string"
          },
          "optionIndex": {
            "type": "number",
            "enum": [
              0,
              1
            ]
          },
          "amount": {
            "type": "number",
            "minimum": 5
          },
          "slippageBps": {
            "type": "number"
          },
          "minSharesOut": {
            "type": "number"
          },
          "sharesOut": {
            "type": "number"
          }
        },
        "required": [
          "accessCode",
          "duelId",
          "optionIndex",
          "amount",
          "slippageBps",
          "minSharesOut",
          "sharesOut"
        ]
      },
      "AgentEstimateSellBodyDto": {
        "type": "object",
        "properties": {
          "accessCode": {
            "type": "string",
            "description": "Agent access code."
          },
          "duelId": {
            "type": "string"
          },
          "optionIndex": {
            "type": "number",
            "enum": [
              0,
              1
            ]
          },
          "sharesIn": {
            "type": "number",
            "minimum": 0
          },
          "slippageBps": {
            "type": "number",
            "default": 100
          }
        },
        "required": [
          "accessCode",
          "duelId",
          "optionIndex",
          "sharesIn"
        ]
      },
      "AgentSellBodyDto": {
        "type": "object",
        "properties": {
          "accessCode": {
            "type": "string",
            "description": "Agent access code."
          },
          "duelId": {
            "type": "string"
          },
          "optionIndex": {
            "type": "number",
            "enum": [
              0,
              1
            ]
          },
          "sharesAmount": {
            "type": "number"
          },
          "slippageBps": {
            "type": "number"
          },
          "minPayoutUsdc": {
            "type": "number"
          },
          "payoutUsdc": {
            "type": "number"
          }
        },
        "required": [
          "accessCode",
          "duelId",
          "optionIndex",
          "sharesAmount",
          "slippageBps",
          "minPayoutUsdc",
          "payoutUsdc"
        ]
      },
      "DeriveCredentialsDto": {
        "type": "object",
        "properties": {
          "force": {
            "type": "boolean",
            "description": "Force re-derivation of CLOB credentials, bypassing cache."
          }
        }
      },
      "PlaceOrderDto": {
        "type": "object",
        "properties": {
          "tokenId": {
            "type": "string",
            "description": "Polymarket CLOB token id (stringified bigint)."
          },
          "side": {
            "type": "string",
            "enum": [
              "BUY",
              "SELL"
            ]
          },
          "size": {
            "type": "number",
            "description": "Size: number of conditional tokens for limit/SELL, USDC amount for market BUY."
          },
          "price": {
            "type": "number",
            "description": "Limit price between 0 and 1."
          },
          "orderType": {
            "type": "string",
            "enum": [
              "FOK",
              "GTC",
              "GTD",
              "FAK"
            ],
            "default": "FOK"
          },
          "negRisk": {
            "type": "boolean",
            "description": "Override neg-risk detection. When omitted the CLOB /neg-risk endpoint is used."
          },
          "expiration": {
            "type": "number",
            "description": "Unix-second expiration for GTD orders."
          }
        },
        "required": [
          "tokenId",
          "side",
          "size",
          "price"
        ]
      },
      "RecoverFundsDto": {
        "type": "object",
        "properties": {
          "destinationAddress": {
            "type": "string",
            "description": "Destination EVM address. Defaults to the authenticated wallet."
          }
        }
      },
      "CopyTradeSubscribeDto": {
        "type": "object",
        "properties": {
          "leaderAddress": {
            "type": "string",
            "description": "Leader wallet address to copy-trade."
          },
          "allocationUsd": {
            "type": "number",
            "description": "USD allocation to mirror the leader with."
          }
        },
        "required": [
          "leaderAddress",
          "allocationUsd"
        ]
      },
      "CopyTradeLeaderDto": {
        "type": "object",
        "properties": {
          "leaderAddress": {
            "type": "string",
            "description": "Leader wallet address."
          }
        },
        "required": [
          "leaderAddress"
        ]
      },
      "CopyTradeLiquidateDto": {
        "type": "object",
        "properties": {
          "leaderAddress": {
            "type": "string",
            "description": "Leader wallet address."
          },
          "stop": {
            "type": "boolean",
            "description": "Also stop the subscription after closing positions."
          }
        },
        "required": [
          "leaderAddress"
        ]
      },
      "EnterPackDto": {
        "type": "object",
        "properties": {}
      },
      "EstimatePackPickDto": {
        "type": "object",
        "properties": {}
      },
      "PlacePackPickDto": {
        "type": "object",
        "properties": {}
      },
      "CreatePackDto": {
        "type": "object",
        "properties": {}
      },
      "AddPackMarketDto": {
        "type": "object",
        "properties": {}
      },
      "ResolvePackMarketDto": {
        "type": "object",
        "properties": {}
      },
      "VoidPackMarketDto": {
        "type": "object",
        "properties": {}
      },
      "GenerateRulesDto": {
        "type": "object",
        "properties": {
          "question": {
            "type": "string",
            "description": "Market question / title."
          },
          "type": {
            "type": "string",
            "enum": [
              "prediction",
              "versus"
            ]
          },
          "category": {
            "type": "string",
            "description": "Sport / category, e.g. Football."
          },
          "optionA": {
            "type": "string",
            "description": "Option A (versus) / Yes label."
          },
          "optionB": {
            "type": "string",
            "description": "Option B (versus) / No label."
          }
        },
        "required": [
          "question",
          "type"
        ]
      },
      "EoaChallengeDto": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "example": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7"
          },
          "domain": {
            "type": "string",
            "example": "app.bento.fun",
            "description": "Hostname of the app requesting sign-in (SIWE Domain)"
          }
        },
        "required": [
          "address",
          "domain"
        ]
      }
    }
  }
}
