improvement(tools): updated kalshi and polymarket tools and blocks (#3021)

This commit is contained in:
Waleed
2026-01-26 21:01:33 -08:00
committed by GitHub
parent d8df08d3d3
commit 077e702dd8
48 changed files with 5779 additions and 1709 deletions

View File

@@ -101,7 +101,6 @@ import {
ShopifyIcon,
SlackIcon,
SmtpIcon,
SpotifyIcon,
SQSIcon,
SshIcon,
STTIcon,
@@ -182,7 +181,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
jina: JinaAIIcon,
jira: JiraIcon,
jira_service_management: JiraServiceManagementIcon,
kalshi: KalshiIcon,
kalshi_v2: KalshiIcon,
knowledge: PackageSearchIcon,
langsmith: LangsmithIcon,
lemlist: LemlistIcon,
@@ -229,7 +228,6 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
shopify: ShopifyIcon,
slack: SlackIcon,
smtp: SmtpIcon,
spotify: SpotifyIcon,
sqs: SQSIcon,
ssh: SshIcon,
stagehand: StagehandIcon,

View File

@@ -47,6 +47,7 @@ Runs a browser automation task using BrowserUse
| `save_browser_data` | boolean | No | Whether to save browser data |
| `model` | string | No | LLM model to use \(default: gpt-4o\) |
| `apiKey` | string | Yes | API key for BrowserUse API |
| `profile_id` | string | No | Browser profile ID for persistent sessions \(cookies, login state\) |
#### Output

View File

@@ -6,7 +6,7 @@ description: Access prediction markets and trade on Kalshi
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="kalshi"
type="kalshi_v2"
color="#09C285"
/>
@@ -36,7 +36,7 @@ Integrate Kalshi prediction markets into the workflow. Can get markets, market,
### `kalshi_get_markets`
Retrieve a list of prediction markets from Kalshi with optional filtering
Retrieve a list of prediction markets from Kalshi with all filtering options (V2 - full API response)
#### Input
@@ -52,12 +52,12 @@ Retrieve a list of prediction markets from Kalshi with optional filtering
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `markets` | array | Array of market objects |
| `paging` | object | Pagination cursor for fetching more results |
| `markets` | array | Array of market objects with all API fields |
| `cursor` | string | Pagination cursor for fetching more results |
### `kalshi_get_market`
Retrieve details of a specific prediction market by ticker
Retrieve details of a specific prediction market by ticker (V2 - full API response)
#### Input
@@ -69,11 +69,62 @@ Retrieve details of a specific prediction market by ticker
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `market` | object | Market object with details |
| `market` | object | Market object with all API fields |
| ↳ `ticker` | string | Market ticker |
| ↳ `event_ticker` | string | Event ticker |
| ↳ `market_type` | string | Market type |
| ↳ `title` | string | Market title |
| ↳ `subtitle` | string | Market subtitle |
| ↳ `yes_sub_title` | string | Yes outcome subtitle |
| ↳ `no_sub_title` | string | No outcome subtitle |
| ↳ `open_time` | string | Market open time |
| ↳ `close_time` | string | Market close time |
| ↳ `expected_expiration_time` | string | Expected expiration time |
| ↳ `expiration_time` | string | Expiration time |
| ↳ `latest_expiration_time` | string | Latest expiration time |
| ↳ `settlement_timer_seconds` | number | Settlement timer in seconds |
| ↳ `status` | string | Market status |
| ↳ `response_price_units` | string | Response price units |
| ↳ `notional_value` | number | Notional value |
| ↳ `tick_size` | number | Tick size |
| ↳ `yes_bid` | number | Current yes bid price |
| ↳ `yes_ask` | number | Current yes ask price |
| ↳ `no_bid` | number | Current no bid price |
| ↳ `no_ask` | number | Current no ask price |
| ↳ `last_price` | number | Last trade price |
| ↳ `previous_yes_bid` | number | Previous yes bid |
| ↳ `previous_yes_ask` | number | Previous yes ask |
| ↳ `previous_price` | number | Previous price |
| ↳ `volume` | number | Total volume |
| ↳ `volume_24h` | number | 24-hour volume |
| ↳ `liquidity` | number | Market liquidity |
| ↳ `open_interest` | number | Open interest |
| ↳ `result` | string | Market result |
| ↳ `cap_strike` | number | Cap strike |
| ↳ `floor_strike` | number | Floor strike |
| ↳ `can_close_early` | boolean | Can close early |
| ↳ `expiration_value` | string | Expiration value |
| ↳ `category` | string | Market category |
| ↳ `risk_limit_cents` | number | Risk limit in cents |
| ↳ `strike_type` | string | Strike type |
| ↳ `rules_primary` | string | Primary rules |
| ↳ `rules_secondary` | string | Secondary rules |
| ↳ `settlement_source_url` | string | Settlement source URL |
| ↳ `custom_strike` | object | Custom strike object |
| ↳ `underlying` | string | Underlying asset |
| ↳ `settlement_value` | number | Settlement value |
| ↳ `cfd_contract_size` | number | CFD contract size |
| ↳ `yes_fee_fp` | number | Yes fee \(fixed-point\) |
| ↳ `no_fee_fp` | number | No fee \(fixed-point\) |
| ↳ `last_price_fp` | number | Last price \(fixed-point\) |
| ↳ `yes_bid_fp` | number | Yes bid \(fixed-point\) |
| ↳ `yes_ask_fp` | number | Yes ask \(fixed-point\) |
| ↳ `no_bid_fp` | number | No bid \(fixed-point\) |
| ↳ `no_ask_fp` | number | No ask \(fixed-point\) |
### `kalshi_get_events`
Retrieve a list of events from Kalshi with optional filtering
Retrieve a list of events from Kalshi with optional filtering (V2 - exact API response)
#### Input
@@ -90,11 +141,12 @@ Retrieve a list of events from Kalshi with optional filtering
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `events` | array | Array of event objects |
| `paging` | object | Pagination cursor for fetching more results |
| `milestones` | array | Array of milestone objects \(if requested\) |
| `cursor` | string | Pagination cursor for fetching more results |
### `kalshi_get_event`
Retrieve details of a specific event by ticker
Retrieve details of a specific event by ticker (V2 - exact API response)
#### Input
@@ -107,11 +159,23 @@ Retrieve details of a specific event by ticker
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `event` | object | Event object with details |
| `event` | object | Event object with full details matching Kalshi API response |
| ↳ `event_ticker` | string | Event ticker |
| ↳ `series_ticker` | string | Series ticker |
| ↳ `title` | string | Event title |
| ↳ `sub_title` | string | Event subtitle |
| ↳ `mutually_exclusive` | boolean | Mutually exclusive markets |
| ↳ `category` | string | Event category |
| ↳ `collateral_return_type` | string | Collateral return type |
| ↳ `strike_date` | string | Strike date |
| ↳ `strike_period` | string | Strike period |
| ↳ `available_on_brokers` | boolean | Available on brokers |
| ↳ `product_metadata` | object | Product metadata |
| ↳ `markets` | array | Nested markets \(if requested\) |
### `kalshi_get_balance`
Retrieve your account balance and portfolio value from Kalshi
Retrieve your account balance and portfolio value from Kalshi (V2 - exact API response)
#### Input
@@ -125,11 +189,12 @@ Retrieve your account balance and portfolio value from Kalshi
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `balance` | number | Account balance in cents |
| `portfolioValue` | number | Portfolio value in cents |
| `portfolio_value` | number | Portfolio value in cents |
| `updated_ts` | number | Unix timestamp of last update \(milliseconds\) |
### `kalshi_get_positions`
Retrieve your open positions from Kalshi
Retrieve your open positions from Kalshi (V2 - exact API response)
#### Input
@@ -147,12 +212,13 @@ Retrieve your open positions from Kalshi
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `positions` | array | Array of position objects |
| `paging` | object | Pagination cursor for fetching more results |
| `market_positions` | array | Array of market position objects |
| `event_positions` | array | Array of event position objects |
| `cursor` | string | Pagination cursor for fetching more results |
### `kalshi_get_orders`
Retrieve your orders from Kalshi with optional filtering
Retrieve your orders from Kalshi with optional filtering (V2 with full API response)
#### Input
@@ -170,12 +236,12 @@ Retrieve your orders from Kalshi with optional filtering
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `orders` | array | Array of order objects |
| `paging` | object | Pagination cursor for fetching more results |
| `orders` | array | Array of order objects with full API response fields |
| `cursor` | string | Pagination cursor for fetching more results |
### `kalshi_get_order`
Retrieve details of a specific order by ID from Kalshi
Retrieve details of a specific order by ID from Kalshi (V2 with full API response)
#### Input
@@ -189,11 +255,44 @@ Retrieve details of a specific order by ID from Kalshi
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `order` | object | Order object with details |
| `order` | object | Order object with full API response fields |
| ↳ `order_id` | string | Order ID |
| ↳ `user_id` | string | User ID |
| ↳ `client_order_id` | string | Client order ID |
| ↳ `ticker` | string | Market ticker |
| ↳ `side` | string | Order side \(yes/no\) |
| ↳ `action` | string | Action \(buy/sell\) |
| ↳ `type` | string | Order type \(limit/market\) |
| ↳ `status` | string | Order status \(resting/canceled/executed\) |
| ↳ `yes_price` | number | Yes price in cents |
| ↳ `no_price` | number | No price in cents |
| ↳ `yes_price_dollars` | string | Yes price in dollars |
| ↳ `no_price_dollars` | string | No price in dollars |
| ↳ `fill_count` | number | Filled contract count |
| ↳ `fill_count_fp` | string | Filled count \(fixed-point\) |
| ↳ `remaining_count` | number | Remaining contracts |
| ↳ `remaining_count_fp` | string | Remaining count \(fixed-point\) |
| ↳ `initial_count` | number | Initial contract count |
| ↳ `initial_count_fp` | string | Initial count \(fixed-point\) |
| ↳ `taker_fees` | number | Taker fees in cents |
| ↳ `maker_fees` | number | Maker fees in cents |
| ↳ `taker_fees_dollars` | string | Taker fees in dollars |
| ↳ `maker_fees_dollars` | string | Maker fees in dollars |
| ↳ `taker_fill_cost` | number | Taker fill cost in cents |
| ↳ `maker_fill_cost` | number | Maker fill cost in cents |
| ↳ `taker_fill_cost_dollars` | string | Taker fill cost in dollars |
| ↳ `maker_fill_cost_dollars` | string | Maker fill cost in dollars |
| ↳ `queue_position` | number | Queue position \(deprecated\) |
| ↳ `expiration_time` | string | Order expiration time |
| ↳ `created_time` | string | Order creation time |
| ↳ `last_update_time` | string | Last update time |
| ↳ `self_trade_prevention_type` | string | Self-trade prevention type |
| ↳ `order_group_id` | string | Order group ID |
| ↳ `cancel_order_on_pause` | boolean | Cancel on market pause |
### `kalshi_get_orderbook`
Retrieve the orderbook (yes and no bids) for a specific market
Retrieve the orderbook (yes and no bids) for a specific market (V2 - includes depth and fp fields)
#### Input
@@ -205,11 +304,18 @@ Retrieve the orderbook (yes and no bids) for a specific market
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `orderbook` | object | Orderbook with yes/no bids and asks |
| `orderbook` | object | Orderbook with yes/no bids \(legacy integer counts\) |
| ↳ `yes` | array | Yes side bids as tuples \[price_cents, count\] |
| ↳ `no` | array | No side bids as tuples \[price_cents, count\] |
| ↳ `yes_dollars` | array | Yes side bids as tuples \[dollars_string, count\] |
| ↳ `no_dollars` | array | No side bids as tuples \[dollars_string, count\] |
| `orderbook_fp` | object | Orderbook with fixed-point counts \(preferred\) |
| ↳ `yes_dollars` | array | Yes side bids as tuples \[dollars_string, fp_count_string\] |
| ↳ `no_dollars` | array | No side bids as tuples \[dollars_string, fp_count_string\] |
### `kalshi_get_trades`
Retrieve recent trades across all markets
Retrieve recent trades with additional filtering options (V2 - includes trade_id and count_fp)
#### Input
@@ -222,12 +328,12 @@ Retrieve recent trades across all markets
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `trades` | array | Array of trade objects |
| `paging` | object | Pagination cursor for fetching more results |
| `trades` | array | Array of trade objects with trade_id and count_fp |
| `cursor` | string | Pagination cursor for fetching more results |
### `kalshi_get_candlesticks`
Retrieve OHLC candlestick data for a specific market
Retrieve OHLC candlestick data for a specific market (V2 - full API response)
#### Input
@@ -243,7 +349,8 @@ Retrieve OHLC candlestick data for a specific market
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `candlesticks` | array | Array of OHLC candlestick data |
| `ticker` | string | Market ticker |
| `candlesticks` | array | Array of OHLC candlestick data with nested bid/ask/price objects |
### `kalshi_get_fills`
@@ -266,12 +373,12 @@ Retrieve your portfolio
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `fills` | array | Array of fill/trade objects |
| `paging` | object | Pagination cursor for fetching more results |
| `fills` | array | Array of fill/trade objects with all API fields |
| `cursor` | string | Pagination cursor for fetching more results |
### `kalshi_get_series_by_ticker`
Retrieve details of a specific market series by ticker
Retrieve details of a specific market series by ticker (V2 - exact API response)
#### Input
@@ -283,11 +390,25 @@ Retrieve details of a specific market series by ticker
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `series` | object | Series object with details |
| `series` | object | Series object with full details matching Kalshi API response |
| ↳ `ticker` | string | Series ticker |
| ↳ `title` | string | Series title |
| ↳ `frequency` | string | Event frequency |
| ↳ `category` | string | Series category |
| ↳ `tags` | array | Series tags |
| ↳ `settlement_sources` | array | Settlement sources |
| ↳ `contract_url` | string | Contract URL |
| ↳ `contract_terms_url` | string | Contract terms URL |
| ↳ `fee_type` | string | Fee type |
| ↳ `fee_multiplier` | number | Fee multiplier |
| ↳ `additional_prohibitions` | array | Additional prohibitions |
| ↳ `product_metadata` | object | Product metadata |
| ↳ `volume` | number | Series volume |
| ↳ `volume_fp` | number | Volume \(fixed-point\) |
### `kalshi_get_exchange_status`
Retrieve the current status of the Kalshi exchange (trading and exchange activity)
Retrieve the current status of the Kalshi exchange (V2 - exact API response)
#### Input
@@ -298,11 +419,13 @@ Retrieve the current status of the Kalshi exchange (trading and exchange activit
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `status` | object | Exchange status with trading_active and exchange_active flags |
| `exchange_active` | boolean | Whether the exchange is active |
| `trading_active` | boolean | Whether trading is active |
| `exchange_estimated_resume_time` | string | Estimated time when exchange will resume \(if inactive\) |
### `kalshi_create_order`
Create a new order on a Kalshi prediction market
Create a new order on a Kalshi prediction market (V2 with full API response)
#### Input
@@ -332,11 +455,44 @@ Create a new order on a Kalshi prediction market
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `order` | object | The created order object |
| `order` | object | The created order object with full API response fields |
| ↳ `order_id` | string | Order ID |
| ↳ `user_id` | string | User ID |
| ↳ `client_order_id` | string | Client order ID |
| ↳ `ticker` | string | Market ticker |
| ↳ `side` | string | Order side \(yes/no\) |
| ↳ `action` | string | Action \(buy/sell\) |
| ↳ `type` | string | Order type \(limit/market\) |
| ↳ `status` | string | Order status \(resting/canceled/executed\) |
| ↳ `yes_price` | number | Yes price in cents |
| ↳ `no_price` | number | No price in cents |
| ↳ `yes_price_dollars` | string | Yes price in dollars |
| ↳ `no_price_dollars` | string | No price in dollars |
| ↳ `fill_count` | number | Filled contract count |
| ↳ `fill_count_fp` | string | Filled count \(fixed-point\) |
| ↳ `remaining_count` | number | Remaining contracts |
| ↳ `remaining_count_fp` | string | Remaining count \(fixed-point\) |
| ↳ `initial_count` | number | Initial contract count |
| ↳ `initial_count_fp` | string | Initial count \(fixed-point\) |
| ↳ `taker_fees` | number | Taker fees in cents |
| ↳ `maker_fees` | number | Maker fees in cents |
| ↳ `taker_fees_dollars` | string | Taker fees in dollars |
| ↳ `maker_fees_dollars` | string | Maker fees in dollars |
| ↳ `taker_fill_cost` | number | Taker fill cost in cents |
| ↳ `maker_fill_cost` | number | Maker fill cost in cents |
| ↳ `taker_fill_cost_dollars` | string | Taker fill cost in dollars |
| ↳ `maker_fill_cost_dollars` | string | Maker fill cost in dollars |
| ↳ `queue_position` | number | Queue position \(deprecated\) |
| ↳ `expiration_time` | string | Order expiration time |
| ↳ `created_time` | string | Order creation time |
| ↳ `last_update_time` | string | Last update time |
| ↳ `self_trade_prevention_type` | string | Self-trade prevention type |
| ↳ `order_group_id` | string | Order group ID |
| ↳ `cancel_order_on_pause` | boolean | Cancel on market pause |
### `kalshi_cancel_order`
Cancel an existing order on Kalshi
Cancel an existing order on Kalshi (V2 with full API response)
#### Input
@@ -350,12 +506,46 @@ Cancel an existing order on Kalshi
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `order` | object | The canceled order object |
| `reducedBy` | number | Number of contracts canceled |
| `order` | object | The canceled order object with full API response fields |
| ↳ `order_id` | string | Order ID |
| ↳ `user_id` | string | User ID |
| ↳ `client_order_id` | string | Client order ID |
| ↳ `ticker` | string | Market ticker |
| ↳ `side` | string | Order side \(yes/no\) |
| ↳ `action` | string | Action \(buy/sell\) |
| ↳ `type` | string | Order type \(limit/market\) |
| ↳ `status` | string | Order status \(resting/canceled/executed\) |
| ↳ `yes_price` | number | Yes price in cents |
| ↳ `no_price` | number | No price in cents |
| ↳ `yes_price_dollars` | string | Yes price in dollars |
| ↳ `no_price_dollars` | string | No price in dollars |
| ↳ `fill_count` | number | Filled contract count |
| ↳ `fill_count_fp` | string | Filled count \(fixed-point\) |
| ↳ `remaining_count` | number | Remaining contracts |
| ↳ `remaining_count_fp` | string | Remaining count \(fixed-point\) |
| ↳ `initial_count` | number | Initial contract count |
| ↳ `initial_count_fp` | string | Initial count \(fixed-point\) |
| ↳ `taker_fees` | number | Taker fees in cents |
| ↳ `maker_fees` | number | Maker fees in cents |
| ↳ `taker_fees_dollars` | string | Taker fees in dollars |
| ↳ `maker_fees_dollars` | string | Maker fees in dollars |
| ↳ `taker_fill_cost` | number | Taker fill cost in cents |
| ↳ `maker_fill_cost` | number | Maker fill cost in cents |
| ↳ `taker_fill_cost_dollars` | string | Taker fill cost in dollars |
| ↳ `maker_fill_cost_dollars` | string | Maker fill cost in dollars |
| ↳ `queue_position` | number | Queue position \(deprecated\) |
| ↳ `expiration_time` | string | Order expiration time |
| ↳ `created_time` | string | Order creation time |
| ↳ `last_update_time` | string | Last update time |
| ↳ `self_trade_prevention_type` | string | Self-trade prevention type |
| ↳ `order_group_id` | string | Order group ID |
| ↳ `cancel_order_on_pause` | boolean | Cancel on market pause |
| `reduced_by` | number | Number of contracts canceled |
| `reduced_by_fp` | string | Number of contracts canceled in fixed-point format |
### `kalshi_amend_order`
Modify the price or quantity of an existing order on Kalshi
Modify the price or quantity of an existing order on Kalshi (V2 with full API response)
#### Input
@@ -379,6 +569,63 @@ Modify the price or quantity of an existing order on Kalshi
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `order` | object | The amended order object |
| `old_order` | object | The original order object before amendment |
| ↳ `order_id` | string | Order ID |
| ↳ `user_id` | string | User ID |
| ↳ `ticker` | string | Market ticker |
| ↳ `event_ticker` | string | Event ticker |
| ↳ `status` | string | Order status |
| ↳ `side` | string | Order side \(yes/no\) |
| ↳ `type` | string | Order type \(limit/market\) |
| ↳ `yes_price` | number | Yes price in cents |
| ↳ `no_price` | number | No price in cents |
| ↳ `action` | string | Action \(buy/sell\) |
| ↳ `count` | number | Number of contracts |
| ↳ `remaining_count` | number | Remaining contracts |
| ↳ `created_time` | string | Order creation time |
| ↳ `expiration_time` | string | Order expiration time |
| ↳ `order_group_id` | string | Order group ID |
| ↳ `client_order_id` | string | Client order ID |
| ↳ `place_count` | number | Place count |
| ↳ `decrease_count` | number | Decrease count |
| ↳ `queue_position` | number | Queue position |
| ↳ `maker_fill_count` | number | Maker fill count |
| ↳ `taker_fill_count` | number | Taker fill count |
| ↳ `maker_fees` | number | Maker fees |
| ↳ `taker_fees` | number | Taker fees |
| ↳ `last_update_time` | string | Last update time |
| ↳ `take_profit_order_id` | string | Take profit order ID |
| ↳ `stop_loss_order_id` | string | Stop loss order ID |
| ↳ `amend_count` | number | Amend count |
| ↳ `amend_taker_fill_count` | number | Amend taker fill count |
| `order` | object | The amended order object with full API response fields |
| ↳ `order_id` | string | Order ID |
| ↳ `user_id` | string | User ID |
| ↳ `ticker` | string | Market ticker |
| ↳ `event_ticker` | string | Event ticker |
| ↳ `status` | string | Order status |
| ↳ `side` | string | Order side \(yes/no\) |
| ↳ `type` | string | Order type \(limit/market\) |
| ↳ `yes_price` | number | Yes price in cents |
| ↳ `no_price` | number | No price in cents |
| ↳ `action` | string | Action \(buy/sell\) |
| ↳ `count` | number | Number of contracts |
| ↳ `remaining_count` | number | Remaining contracts |
| ↳ `created_time` | string | Order creation time |
| ↳ `expiration_time` | string | Order expiration time |
| ↳ `order_group_id` | string | Order group ID |
| ↳ `client_order_id` | string | Client order ID |
| ↳ `place_count` | number | Place count |
| ↳ `decrease_count` | number | Decrease count |
| ↳ `queue_position` | number | Queue position |
| ↳ `maker_fill_count` | number | Maker fill count |
| ↳ `taker_fill_count` | number | Taker fill count |
| ↳ `maker_fees` | number | Maker fees |
| ↳ `taker_fees` | number | Taker fees |
| ↳ `last_update_time` | string | Last update time |
| ↳ `take_profit_order_id` | string | Take profit order ID |
| ↳ `stop_loss_order_id` | string | Stop loss order ID |
| ↳ `amend_count` | number | Amend count |
| ↳ `amend_taker_fill_count` | number | Amend taker fill count |

View File

@@ -97,7 +97,6 @@
"shopify",
"slack",
"smtp",
"spotify",
"sqs",
"ssh",
"stagehand",

View File

@@ -29,7 +29,7 @@ By using these documented API endpoints, you can seamlessly integrate Polymarket
## Usage Instructions
Integrate Polymarket prediction markets into the workflow. Can get markets, market, events, event, tags, series, orderbook, price, midpoint, price history, last trade price, spread, tick size, positions, trades, and search.
Integrate Polymarket prediction markets into the workflow. Can get markets, market, events, event, tags, series, orderbook, price, midpoint, price history, last trade price, spread, tick size, positions, trades, activity, leaderboard, holders, and search.
@@ -43,7 +43,7 @@ Retrieve a list of prediction markets from Polymarket with optional filtering
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `closed` | string | No | Filter by closed status \(true/false\). Use false for active markets only. |
| `closed` | string | No | Filter by closed status \(true/false\). Use false for open markets only. |
| `order` | string | No | Sort field \(e.g., volumeNum, liquidityNum, startDate, endDate, createdAt\) |
| `ascending` | string | No | Sort direction \(true for ascending, false for descending\) |
| `tagId` | string | No | Filter by tag ID |
@@ -55,6 +55,21 @@ Retrieve a list of prediction markets from Polymarket with optional filtering
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `markets` | array | Array of market objects |
| ↳ `id` | string | Market ID |
| ↳ `question` | string | Market question |
| ↳ `conditionId` | string | Condition ID |
| ↳ `slug` | string | Market slug |
| ↳ `endDate` | string | End date |
| ↳ `image` | string | Market image URL |
| ↳ `outcomes` | string | Outcomes JSON string |
| ↳ `outcomePrices` | string | Outcome prices JSON string |
| ↳ `volume` | string | Total volume |
| ↳ `liquidity` | string | Total liquidity |
| ↳ `active` | boolean | Whether market is active |
| ↳ `closed` | boolean | Whether market is closed |
| ↳ `volumeNum` | number | Volume as number |
| ↳ `liquidityNum` | number | Liquidity as number |
| ↳ `clobTokenIds` | array | CLOB token IDs |
### `polymarket_get_market`
@@ -72,6 +87,28 @@ Retrieve details of a specific prediction market by ID or slug
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `market` | object | Market object with details |
| ↳ `id` | string | Market ID |
| ↳ `question` | string | Market question |
| ↳ `conditionId` | string | Condition ID |
| ↳ `slug` | string | Market slug |
| ↳ `resolutionSource` | string | Resolution source |
| ↳ `endDate` | string | End date |
| ↳ `startDate` | string | Start date |
| ↳ `image` | string | Market image URL |
| ↳ `icon` | string | Market icon URL |
| ↳ `description` | string | Market description |
| ↳ `outcomes` | string | Outcomes JSON string |
| ↳ `outcomePrices` | string | Outcome prices JSON string |
| ↳ `volume` | string | Total volume |
| ↳ `liquidity` | string | Total liquidity |
| ↳ `active` | boolean | Whether market is active |
| ↳ `closed` | boolean | Whether market is closed |
| ↳ `archived` | boolean | Whether market is archived |
| ↳ `volumeNum` | number | Volume as number |
| ↳ `liquidityNum` | number | Liquidity as number |
| ↳ `clobTokenIds` | array | CLOB token IDs |
| ↳ `acceptingOrders` | boolean | Whether accepting orders |
| ↳ `negRisk` | boolean | Whether negative risk |
### `polymarket_get_events`
@@ -81,7 +118,7 @@ Retrieve a list of events from Polymarket with optional filtering
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `closed` | string | No | Filter by closed status \(true/false\). Use false for active events only. |
| `closed` | string | No | Filter by closed status \(true/false\). Use false for open events only. |
| `order` | string | No | Sort field \(e.g., volume, liquidity, startDate, endDate, createdAt\) |
| `ascending` | string | No | Sort direction \(true for ascending, false for descending\) |
| `tagId` | string | No | Filter by tag ID |
@@ -93,6 +130,21 @@ Retrieve a list of events from Polymarket with optional filtering
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `events` | array | Array of event objects |
| ↳ `id` | string | Event ID |
| ↳ `ticker` | string | Event ticker |
| ↳ `slug` | string | Event slug |
| ↳ `title` | string | Event title |
| ↳ `description` | string | Event description |
| ↳ `startDate` | string | Start date |
| ↳ `endDate` | string | End date |
| ↳ `image` | string | Event image URL |
| ↳ `icon` | string | Event icon URL |
| ↳ `active` | boolean | Whether event is active |
| ↳ `closed` | boolean | Whether event is closed |
| ↳ `archived` | boolean | Whether event is archived |
| ↳ `liquidity` | number | Total liquidity |
| ↳ `volume` | number | Total volume |
| ↳ `markets` | array | Array of markets in this event |
### `polymarket_get_event`
@@ -110,6 +162,24 @@ Retrieve details of a specific event by ID or slug
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `event` | object | Event object with details |
| ↳ `id` | string | Event ID |
| ↳ `ticker` | string | Event ticker |
| ↳ `slug` | string | Event slug |
| ↳ `title` | string | Event title |
| ↳ `description` | string | Event description |
| ↳ `startDate` | string | Start date |
| ↳ `creationDate` | string | Creation date |
| ↳ `endDate` | string | End date |
| ↳ `image` | string | Event image URL |
| ↳ `icon` | string | Event icon URL |
| ↳ `active` | boolean | Whether event is active |
| ↳ `closed` | boolean | Whether event is closed |
| ↳ `archived` | boolean | Whether event is archived |
| ↳ `liquidity` | number | Total liquidity |
| ↳ `volume` | number | Total volume |
| ↳ `openInterest` | number | Open interest |
| ↳ `commentCount` | number | Comment count |
| ↳ `markets` | array | Array of markets in this event |
### `polymarket_get_tags`
@@ -126,7 +196,12 @@ Retrieve available tags for filtering markets from Polymarket
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `tags` | array | Array of tag objects with id, label, and slug |
| `tags` | array | Array of tag objects |
| ↳ `id` | string | Tag ID |
| ↳ `label` | string | Tag label |
| ↳ `slug` | string | Tag slug |
| ↳ `createdAt` | string | Creation timestamp |
| ↳ `updatedAt` | string | Last update timestamp |
### `polymarket_search`
@@ -138,13 +213,28 @@ Search for markets, events, and profiles on Polymarket
| --------- | ---- | -------- | ----------- |
| `query` | string | Yes | Search query term |
| `limit` | string | No | Number of results per page \(max 50\) |
| `offset` | string | No | Pagination offset |
| `page` | string | No | Page number for pagination \(1-indexed\) |
| `cache` | string | No | Enable caching \(true/false\) |
| `eventsStatus` | string | No | Filter events by status |
| `limitPerType` | string | No | Limit results per type \(markets, events, profiles\) |
| `eventsTag` | string | No | Filter by event tags \(comma-separated\) |
| `sort` | string | No | Sort field |
| `ascending` | string | No | Sort direction \(true for ascending, false for descending\) |
| `searchTags` | string | No | Include tags in search results \(true/false\) |
| `searchProfiles` | string | No | Include profiles in search results \(true/false\) |
| `recurrence` | string | No | Filter by recurrence type |
| `excludeTagId` | string | No | Exclude events with these tag IDs \(comma-separated\) |
| `keepClosedMarkets` | string | No | Include closed markets in results \(0 or 1\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `results` | object | Search results containing markets, events, and profiles arrays |
| `results` | object | Search results containing markets, events, tags, and profiles arrays |
| ↳ `markets` | array | Array of matching market objects |
| ↳ `events` | array | Array of matching event objects |
| ↳ `tags` | array | Array of matching tag objects |
| ↳ `profiles` | array | Array of matching profile objects |
### `polymarket_get_series`
@@ -162,6 +252,21 @@ Retrieve series (related market groups) from Polymarket
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `series` | array | Array of series objects |
| ↳ `id` | string | Series ID |
| ↳ `ticker` | string | Series ticker |
| ↳ `slug` | string | Series slug |
| ↳ `title` | string | Series title |
| ↳ `seriesType` | string | Series type |
| ↳ `recurrence` | string | Recurrence pattern |
| ↳ `image` | string | Series image URL |
| ↳ `icon` | string | Series icon URL |
| ↳ `active` | boolean | Whether series is active |
| ↳ `closed` | boolean | Whether series is closed |
| ↳ `archived` | boolean | Whether series is archived |
| ↳ `featured` | boolean | Whether series is featured |
| ↳ `volume` | number | Total volume |
| ↳ `liquidity` | number | Total liquidity |
| ↳ `eventCount` | number | Number of events in series |
### `polymarket_get_series_by_id`
@@ -178,6 +283,23 @@ Retrieve a specific series (related market group) by ID from Polymarket
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `series` | object | Series object with details |
| ↳ `id` | string | Series ID |
| ↳ `ticker` | string | Series ticker |
| ↳ `slug` | string | Series slug |
| ↳ `title` | string | Series title |
| ↳ `seriesType` | string | Series type |
| ↳ `recurrence` | string | Recurrence pattern |
| ↳ `image` | string | Series image URL |
| ↳ `icon` | string | Series icon URL |
| ↳ `active` | boolean | Whether series is active |
| ↳ `closed` | boolean | Whether series is closed |
| ↳ `archived` | boolean | Whether series is archived |
| ↳ `featured` | boolean | Whether series is featured |
| ↳ `volume` | number | Total volume |
| ↳ `liquidity` | number | Total liquidity |
| ↳ `commentCount` | number | Comment count |
| ↳ `eventCount` | number | Number of events in series |
| ↳ `events` | array | Array of events in this series |
### `polymarket_get_orderbook`
@@ -194,6 +316,21 @@ Retrieve the order book summary for a specific token
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `orderbook` | object | Order book with bids and asks arrays |
| ↳ `market` | string | Market identifier |
| ↳ `asset_id` | string | Asset token ID |
| ↳ `hash` | string | Order book hash |
| ↳ `timestamp` | string | Timestamp |
| ↳ `bids` | array | Bid orders |
| ↳ `price` | string | Bid price |
| ↳ `size` | string | Bid size |
| ↳ `price` | string | Ask price |
| ↳ `size` | string | Ask size |
| ↳ `asks` | array | Ask orders |
| ↳ `price` | string | Ask price |
| ↳ `size` | string | Ask size |
| ↳ `min_order_size` | string | Minimum order size |
| ↳ `tick_size` | string | Tick size |
| ↳ `neg_risk` | boolean | Whether negative risk |
### `polymarket_get_price`
@@ -246,7 +383,9 @@ Retrieve historical price data for a specific market token
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `history` | array | Array of price history entries with timestamp \(t\) and price \(p\) |
| `history` | array | Array of price history entries |
| ↳ `t` | number | Unix timestamp |
| ↳ `p` | number | Price at timestamp |
### `polymarket_get_last_trade_price`
@@ -263,6 +402,7 @@ Retrieve the last trade price for a specific token
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `price` | string | Last trade price |
| `side` | string | Side of the last trade \(BUY or SELL\) |
### `polymarket_get_spread`
@@ -278,7 +418,8 @@ Retrieve the bid-ask spread for a specific token
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `spread` | object | Bid-ask spread with bid and ask prices |
| `spread` | object | Spread value between bid and ask |
| ↳ `spread` | string | The spread value |
### `polymarket_get_tick_size`
@@ -305,13 +446,47 @@ Retrieve user positions from Polymarket
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `user` | string | Yes | User wallet address |
| `market` | string | No | Optional market ID to filter positions |
| `market` | string | No | Condition IDs to filter positions \(comma-separated, mutually exclusive with eventId\) |
| `eventId` | string | No | Event ID to filter positions \(mutually exclusive with market\) |
| `sizeThreshold` | string | No | Minimum position size threshold \(default: 1\) |
| `redeemable` | string | No | Filter for redeemable positions only \(true/false\) |
| `mergeable` | string | No | Filter for mergeable positions only \(true/false\) |
| `sortBy` | string | No | Sort field \(TOKENS, CURRENT, INITIAL, CASHPNL, PERCENTPNL, TITLE, RESOLVING, PRICE, AVGPRICE\) |
| `sortDirection` | string | No | Sort direction \(ASC or DESC\) |
| `title` | string | No | Search filter by title |
| `limit` | string | No | Number of results per page |
| `offset` | string | No | Pagination offset |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `positions` | array | Array of position objects |
| ↳ `proxyWallet` | string | Proxy wallet address |
| ↳ `asset` | string | Asset token ID |
| ↳ `conditionId` | string | Condition ID |
| ↳ `size` | number | Position size |
| ↳ `avgPrice` | number | Average price |
| ↳ `initialValue` | number | Initial value |
| ↳ `currentValue` | number | Current value |
| ↳ `cashPnl` | number | Cash profit/loss |
| ↳ `percentPnl` | number | Percent profit/loss |
| ↳ `totalBought` | number | Total bought |
| ↳ `realizedPnl` | number | Realized profit/loss |
| ↳ `percentRealizedPnl` | number | Percent realized profit/loss |
| ↳ `curPrice` | number | Current price |
| ↳ `redeemable` | boolean | Whether position is redeemable |
| ↳ `mergeable` | boolean | Whether position is mergeable |
| ↳ `title` | string | Market title |
| ↳ `slug` | string | Market slug |
| ↳ `icon` | string | Market icon URL |
| ↳ `eventSlug` | string | Event slug |
| ↳ `outcome` | string | Outcome name |
| ↳ `outcomeIndex` | number | Outcome index |
| ↳ `oppositeOutcome` | string | Opposite outcome name |
| ↳ `oppositeAsset` | string | Opposite asset token ID |
| ↳ `endDate` | string | End date |
| ↳ `negativeRisk` | boolean | Whether negative risk |
### `polymarket_get_trades`
@@ -322,8 +497,13 @@ Retrieve trade history from Polymarket
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `user` | string | No | User wallet address to filter trades |
| `market` | string | No | Market ID to filter trades |
| `limit` | string | No | Number of results per page \(max 50\) |
| `market` | string | No | Market/condition ID to filter trades \(mutually exclusive with eventId\) |
| `eventId` | string | No | Event ID to filter trades \(mutually exclusive with market\) |
| `side` | string | No | Trade direction filter \(BUY or SELL\) |
| `takerOnly` | string | No | Filter for taker trades only \(true/false, default: true\) |
| `filterType` | string | No | Filter type \(CASH or TOKENS\) - requires filterAmount |
| `filterAmount` | string | No | Filter amount threshold - requires filterType |
| `limit` | string | No | Number of results per page \(default: 100, max: 10000\) |
| `offset` | string | No | Pagination offset \(skip this many results\) |
#### Output
@@ -331,5 +511,141 @@ Retrieve trade history from Polymarket
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `trades` | array | Array of trade objects |
| ↳ `proxyWallet` | string | Proxy wallet address |
| ↳ `side` | string | Trade side \(BUY or SELL\) |
| ↳ `asset` | string | Asset token ID |
| ↳ `conditionId` | string | Condition ID |
| ↳ `size` | number | Trade size |
| ↳ `price` | number | Trade price |
| ↳ `timestamp` | number | Unix timestamp |
| ↳ `title` | string | Market title |
| ↳ `slug` | string | Market slug |
| ↳ `icon` | string | Market icon URL |
| ↳ `eventSlug` | string | Event slug |
| ↳ `outcome` | string | Outcome name |
| ↳ `outcomeIndex` | number | Outcome index |
| ↳ `name` | string | Trader name |
| ↳ `pseudonym` | string | Trader pseudonym |
| ↳ `bio` | string | Trader bio |
| ↳ `profileImage` | string | Profile image URL |
| ↳ `profileImageOptimized` | string | Optimized profile image URL |
| ↳ `transactionHash` | string | Transaction hash |
### `polymarket_get_activity`
Retrieve on-chain activity for a user including trades, splits, merges, redemptions, rewards, and conversions
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `user` | string | Yes | User wallet address \(0x-prefixed\) |
| `limit` | string | No | Maximum results \(default: 100, max: 500\) |
| `offset` | string | No | Pagination offset \(default: 0, max: 10000\) |
| `market` | string | No | Comma-separated condition IDs \(mutually exclusive with eventId\) |
| `eventId` | string | No | Comma-separated event IDs \(mutually exclusive with market\) |
| `type` | string | No | Activity type filter: TRADE, SPLIT, MERGE, REDEEM, REWARD, CONVERSION, MAKER_REBATE |
| `start` | number | No | Start timestamp \(Unix seconds\) |
| `end` | number | No | End timestamp \(Unix seconds\) |
| `sortBy` | string | No | Sort field: TIMESTAMP, TOKENS, or CASH \(default: TIMESTAMP\) |
| `sortDirection` | string | No | Sort direction: ASC or DESC \(default: DESC\) |
| `side` | string | No | Trade side filter: BUY or SELL \(only applies to trades\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `activity` | array | Array of activity entries |
| ↳ `proxyWallet` | string | User proxy wallet address |
| ↳ `timestamp` | number | Unix timestamp of activity |
| ↳ `conditionId` | string | Market condition ID |
| ↳ `type` | string | Activity type \(TRADE, SPLIT, MERGE, REDEEM, REWARD, CONVERSION\) |
| ↳ `size` | number | Size in tokens |
| ↳ `usdcSize` | number | Size in USDC |
| ↳ `transactionHash` | string | Blockchain transaction hash |
| ↳ `price` | number | Price \(for trades\) |
| ↳ `asset` | string | Asset/token ID |
| ↳ `side` | string | Trade side \(BUY/SELL\) |
| ↳ `outcomeIndex` | number | Outcome index |
| ↳ `title` | string | Market title |
| ↳ `slug` | string | Market slug |
| ↳ `icon` | string | Market icon URL |
| ↳ `eventSlug` | string | Event slug |
| ↳ `outcome` | string | Outcome name |
| ↳ `name` | string | User display name |
| ↳ `pseudonym` | string | User pseudonym |
| ↳ `bio` | string | User bio |
| ↳ `profileImage` | string | User profile image URL |
| ↳ `profileImageOptimized` | string | Optimized profile image URL |
### `polymarket_get_leaderboard`
Retrieve trader leaderboard rankings by profit/loss or volume
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `category` | string | No | Category filter: OVERALL, POLITICS, SPORTS, CRYPTO, CULTURE, MENTIONS, WEATHER, ECONOMICS, TECH, FINANCE \(default: OVERALL\) |
| `timePeriod` | string | No | Time period: DAY, WEEK, MONTH, ALL \(default: DAY\) |
| `orderBy` | string | No | Order by: PNL or VOL \(default: PNL\) |
| `limit` | string | No | Number of results \(1-50, default: 25\) |
| `offset` | string | No | Pagination offset \(0-1000, default: 0\) |
| `user` | string | No | Filter by specific user wallet address |
| `userName` | string | No | Filter by username |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `leaderboard` | array | Array of leaderboard entries |
| ↳ `rank` | string | Leaderboard rank position |
| ↳ `proxyWallet` | string | User proxy wallet address |
| ↳ `userName` | string | User display name |
| ↳ `vol` | number | Trading volume |
| ↳ `pnl` | number | Profit and loss |
| ↳ `profileImage` | string | User profile image URL |
| ↳ `xUsername` | string | Twitter/X username |
| ↳ `verifiedBadge` | boolean | Whether user has verified badge |
### `polymarket_get_holders`
Retrieve top holders of a specific market token
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `market` | string | Yes | Comma-separated list of condition IDs |
| `limit` | string | No | Number of holders to return \(0-20, default: 20\) |
| `minBalance` | string | No | Minimum balance threshold \(default: 1\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `holders` | array | Array of market holder groups by token |
| ↳ `token` | string | Token/asset ID |
| ↳ `holders` | array | Array of holders for this token |
| ↳ `proxyWallet` | string | Holder wallet address |
| ↳ `bio` | string | Holder bio |
| ↳ `asset` | string | Asset ID |
| ↳ `pseudonym` | string | Holder pseudonym |
| ↳ `amount` | number | Amount held |
| ↳ `displayUsernamePublic` | boolean | Whether username is publicly displayed |
| ↳ `outcomeIndex` | number | Outcome index |
| ↳ `name` | string | Holder display name |
| ↳ `profileImage` | string | Profile image URL |
| ↳ `profileImageOptimized` | string | Optimized profile image URL |
| ↳ `proxyWallet` | string | Holder wallet address |
| ↳ `bio` | string | Holder bio |
| ↳ `asset` | string | Asset ID |
| ↳ `pseudonym` | string | Holder pseudonym |
| ↳ `amount` | number | Amount held |
| ↳ `displayUsernamePublic` | boolean | Whether username is publicly displayed |
| ↳ `outcomeIndex` | number | Outcome index |
| ↳ `name` | string | Holder display name |
| ↳ `profileImage` | string | Profile image URL |
| ↳ `profileImageOptimized` | string | Optimized profile image URL |

File diff suppressed because it is too large Load Diff

View File

@@ -299,7 +299,7 @@ Upload a file to a Supabase storage bucket
| `bucket` | string | Yes | The name of the storage bucket |
| `fileName` | string | Yes | The name of the file \(e.g., "document.pdf", "image.jpg"\) |
| `path` | string | No | Optional folder path \(e.g., "folder/subfolder/"\) |
| `fileContent` | string | Yes | The file content \(base64 encoded for binary files, or plain text\) |
| `fileData` | json | Yes | File to upload - UserFile object \(basic mode\) or string content \(advanced mode: base64 or plain text\). Supports data URLs. |
| `contentType` | string | No | MIME type of the file \(e.g., "image/jpeg", "text/plain"\) |
| `upsert` | boolean | No | If true, overwrites existing file \(default: false\) |
| `apiKey` | string | Yes | Your Supabase service role secret key |
@@ -309,7 +309,7 @@ Upload a file to a Supabase storage bucket
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `message` | string | Operation status message |
| `results` | object | Upload result including file path and metadata |
| `results` | object | Upload result including file path, bucket, and public URL |
### `supabase_storage_download`

View File

@@ -1,16 +1,18 @@
import { KalshiIcon } from '@/components/icons'
import type { BlockConfig } from '@/blocks/types'
import { AuthMode } from '@/blocks/types'
import { createVersionedToolSelector } from '@/blocks/utils'
export const KalshiBlock: BlockConfig = {
type: 'kalshi',
name: 'Kalshi',
name: 'Kalshi (Legacy)',
description: 'Access prediction markets and trade on Kalshi',
longDescription:
'Integrate Kalshi prediction markets into the workflow. Can get markets, market, events, event, balance, positions, orders, orderbook, trades, candlesticks, fills, series, exchange status, and place/cancel/amend trades.',
docsLink: 'https://docs.sim.ai/tools/kalshi',
authMode: AuthMode.ApiKey,
category: 'tools',
hideFromToolbar: true,
bgColor: '#09C285',
icon: KalshiIcon,
subBlocks: [
@@ -349,8 +351,14 @@ Return ONLY the numeric timestamp (seconds since Unix epoch) - no explanations,
id: 'count',
title: 'Contracts',
type: 'short-input',
placeholder: 'Number of contracts',
required: true,
placeholder: 'Number of contracts (or use countFp)',
condition: { field: 'operation', value: ['create_order'] },
},
{
id: 'countFp',
title: 'Contracts (Fixed-Point)',
type: 'short-input',
placeholder: 'Fixed-point count (e.g., "10.50")',
condition: { field: 'operation', value: ['create_order'] },
},
{
@@ -674,3 +682,143 @@ Return ONLY the numeric timestamp (seconds since Unix epoch) - no explanations,
paging: { type: 'json', description: 'Pagination cursor for fetching more results' },
},
}
export const KalshiV2Block: BlockConfig = {
...KalshiBlock,
type: 'kalshi_v2',
name: 'Kalshi',
description: 'Access prediction markets and trade on Kalshi',
longDescription:
'Integrate Kalshi prediction markets into the workflow. Can get markets, market, events, event, balance, positions, orders, orderbook, trades, candlesticks, fills, series, exchange status, and place/cancel/amend trades.',
hideFromToolbar: false,
tools: {
...KalshiBlock.tools,
access: [
'kalshi_get_markets_v2',
'kalshi_get_market_v2',
'kalshi_get_events_v2',
'kalshi_get_event_v2',
'kalshi_get_balance_v2',
'kalshi_get_positions_v2',
'kalshi_get_orders_v2',
'kalshi_get_order_v2',
'kalshi_get_orderbook_v2',
'kalshi_get_trades_v2',
'kalshi_get_candlesticks_v2',
'kalshi_get_fills_v2',
'kalshi_get_series_by_ticker_v2',
'kalshi_get_exchange_status_v2',
'kalshi_create_order_v2',
'kalshi_cancel_order_v2',
'kalshi_amend_order_v2',
],
config: {
...KalshiBlock.tools!.config,
tool: createVersionedToolSelector({
baseToolSelector: (params) => {
switch (params.operation) {
case 'get_markets':
return 'kalshi_get_markets'
case 'get_market':
return 'kalshi_get_market'
case 'get_events':
return 'kalshi_get_events'
case 'get_event':
return 'kalshi_get_event'
case 'get_balance':
return 'kalshi_get_balance'
case 'get_positions':
return 'kalshi_get_positions'
case 'get_orders':
return 'kalshi_get_orders'
case 'get_order':
return 'kalshi_get_order'
case 'get_orderbook':
return 'kalshi_get_orderbook'
case 'get_trades':
return 'kalshi_get_trades'
case 'get_candlesticks':
return 'kalshi_get_candlesticks'
case 'get_fills':
return 'kalshi_get_fills'
case 'get_series_by_ticker':
return 'kalshi_get_series_by_ticker'
case 'get_exchange_status':
return 'kalshi_get_exchange_status'
case 'create_order':
return 'kalshi_create_order'
case 'cancel_order':
return 'kalshi_cancel_order'
case 'amend_order':
return 'kalshi_amend_order'
default:
return 'kalshi_get_markets'
}
},
suffix: '_v2',
fallbackToolId: 'kalshi_get_markets_v2',
}),
},
},
outputs: {
// List operations (V2 uses snake_case and flat cursor)
markets: { type: 'json', description: 'Array of market objects (get_markets)' },
events: { type: 'json', description: 'Array of event objects (get_events)' },
orders: { type: 'json', description: 'Array of order objects (get_orders)' },
market_positions: {
type: 'json',
description: 'Array of market position objects (get_positions)',
},
event_positions: {
type: 'json',
description: 'Array of event position objects (get_positions)',
},
fills: { type: 'json', description: 'Array of fill objects (get_fills)' },
trades: { type: 'json', description: 'Array of trade objects (get_trades)' },
candlesticks: {
type: 'json',
description: 'Array of candlestick data with yes_bid/yes_ask/price nested objects',
},
milestones: {
type: 'json',
description: 'Array of milestone objects (get_events with milestones)',
},
// Single item operations
market: { type: 'json', description: 'Single market object (get_market)' },
event: { type: 'json', description: 'Single event object (get_event)' },
order: {
type: 'json',
description: 'Order object with _dollars and _fp fields (get_order, create_order, etc.)',
},
series: { type: 'json', description: 'Series object (get_series_by_ticker)' },
// Account operations
balance: { type: 'number', description: 'Account balance in cents (get_balance)' },
portfolio_value: { type: 'number', description: 'Portfolio value in cents (get_balance)' },
updated_ts: { type: 'number', description: 'Unix timestamp of last update (get_balance)' },
// Orderbook (V2 uses tuple arrays)
orderbook: {
type: 'json',
description: 'Orderbook with yes/no/yes_dollars/no_dollars tuple arrays',
},
orderbook_fp: {
type: 'json',
description: 'Fixed-point orderbook with yes_dollars/no_dollars tuple arrays',
},
// Exchange status
exchange_status: {
type: 'string',
description: 'Exchange status string (get_exchange_status)',
},
trading_active: { type: 'boolean', description: 'Trading active flag (get_exchange_status)' },
// Cancel order specific
reduced_by: { type: 'number', description: 'Number of contracts reduced (cancel_order)' },
reduced_by_fp: {
type: 'string',
description: 'Contracts reduced in fixed-point (cancel_order)',
},
// Candlesticks ticker
ticker: { type: 'string', description: 'Market ticker (get_candlesticks)' },
// Pagination (flat cursor instead of nested paging object)
cursor: { type: 'string', description: 'Pagination cursor for fetching more results' },
},
}

View File

@@ -6,7 +6,7 @@ export const PolymarketBlock: BlockConfig = {
name: 'Polymarket',
description: 'Access prediction markets data from Polymarket',
longDescription:
'Integrate Polymarket prediction markets into the workflow. Can get markets, market, events, event, tags, series, orderbook, price, midpoint, price history, last trade price, spread, tick size, positions, trades, and search.',
'Integrate Polymarket prediction markets into the workflow. Can get markets, market, events, event, tags, series, orderbook, price, midpoint, price history, last trade price, spread, tick size, positions, trades, activity, leaderboard, holders, and search.',
docsLink: 'https://docs.sim.ai/tools/polymarket',
category: 'tools',
bgColor: '#4C82FB',
@@ -34,6 +34,9 @@ export const PolymarketBlock: BlockConfig = {
{ label: 'Get Tick Size', id: 'get_tick_size' },
{ label: 'Get Positions', id: 'get_positions' },
{ label: 'Get Trades', id: 'get_trades' },
{ label: 'Get Activity', id: 'get_activity' },
{ label: 'Get Leaderboard', id: 'get_leaderboard' },
{ label: 'Get Market Holders', id: 'get_holders' },
],
value: () => 'get_markets',
},
@@ -101,14 +104,281 @@ export const PolymarketBlock: BlockConfig = {
placeholder: 'Wallet address (optional filter)',
condition: { field: 'operation', value: ['get_trades'] },
},
// Market filter for positions and trades
// Market/Event filter for positions and trades
{
id: 'market',
title: 'Market ID',
title: 'Condition ID',
type: 'short-input',
placeholder: 'Market ID (optional filter)',
placeholder: 'Condition ID filter (comma-separated)',
condition: { field: 'operation', value: ['get_positions', 'get_trades'] },
},
{
id: 'positionEventId',
title: 'Event ID',
type: 'short-input',
placeholder: 'Event ID filter (alternative to Condition ID)',
condition: { field: 'operation', value: ['get_positions', 'get_trades'] },
},
// Positions-specific filters
{
id: 'sizeThreshold',
title: 'Size Threshold',
type: 'short-input',
placeholder: 'Minimum position size (default: 1)',
condition: { field: 'operation', value: ['get_positions'] },
},
{
id: 'redeemable',
title: 'Redeemable',
type: 'dropdown',
options: [
{ label: 'All', id: '' },
{ label: 'Redeemable Only', id: 'true' },
{ label: 'Non-Redeemable Only', id: 'false' },
],
condition: { field: 'operation', value: ['get_positions'] },
},
{
id: 'mergeable',
title: 'Mergeable',
type: 'dropdown',
options: [
{ label: 'All', id: '' },
{ label: 'Mergeable Only', id: 'true' },
{ label: 'Non-Mergeable Only', id: 'false' },
],
condition: { field: 'operation', value: ['get_positions'] },
},
{
id: 'positionSortBy',
title: 'Sort By',
type: 'dropdown',
options: [
{ label: 'Default', id: '' },
{ label: 'Tokens', id: 'TOKENS' },
{ label: 'Current Value', id: 'CURRENT' },
{ label: 'Initial Value', id: 'INITIAL' },
{ label: 'Cash P&L', id: 'CASHPNL' },
{ label: 'Percent P&L', id: 'PERCENTPNL' },
{ label: 'Title', id: 'TITLE' },
{ label: 'Price', id: 'PRICE' },
{ label: 'Avg Price', id: 'AVGPRICE' },
],
condition: { field: 'operation', value: ['get_positions'] },
},
{
id: 'positionSortDirection',
title: 'Sort Direction',
type: 'dropdown',
options: [
{ label: 'Descending', id: 'DESC' },
{ label: 'Ascending', id: 'ASC' },
],
condition: { field: 'operation', value: ['get_positions'] },
},
{
id: 'positionTitle',
title: 'Title Filter',
type: 'short-input',
placeholder: 'Search by title',
condition: { field: 'operation', value: ['get_positions'] },
},
// Trades-specific filters
{
id: 'tradeSide',
title: 'Trade Side',
type: 'dropdown',
options: [
{ label: 'All', id: '' },
{ label: 'Buy', id: 'BUY' },
{ label: 'Sell', id: 'SELL' },
],
condition: { field: 'operation', value: ['get_trades'] },
},
{
id: 'takerOnly',
title: 'Taker Only',
type: 'dropdown',
options: [
{ label: 'Yes (default)', id: 'true' },
{ label: 'No', id: 'false' },
],
condition: { field: 'operation', value: ['get_trades'] },
},
{
id: 'filterType',
title: 'Filter Type',
type: 'dropdown',
options: [
{ label: 'None', id: '' },
{ label: 'Cash', id: 'CASH' },
{ label: 'Tokens', id: 'TOKENS' },
],
condition: { field: 'operation', value: ['get_trades'] },
},
{
id: 'filterAmount',
title: 'Filter Amount',
type: 'short-input',
placeholder: 'Minimum amount threshold',
condition: { field: 'operation', value: ['get_trades'] },
},
// Activity-specific fields
{
id: 'activityUser',
title: 'User Wallet Address',
type: 'short-input',
placeholder: 'Wallet address (0x-prefixed)',
required: true,
condition: { field: 'operation', value: ['get_activity'] },
},
{
id: 'activityType',
title: 'Activity Type',
type: 'dropdown',
options: [
{ label: 'All', id: '' },
{ label: 'Trade', id: 'TRADE' },
{ label: 'Split', id: 'SPLIT' },
{ label: 'Merge', id: 'MERGE' },
{ label: 'Redeem', id: 'REDEEM' },
{ label: 'Reward', id: 'REWARD' },
{ label: 'Conversion', id: 'CONVERSION' },
{ label: 'Maker Rebate', id: 'MAKER_REBATE' },
],
condition: { field: 'operation', value: ['get_activity'] },
},
{
id: 'activityMarket',
title: 'Condition ID',
type: 'short-input',
placeholder: 'Condition ID filter (comma-separated)',
condition: { field: 'operation', value: ['get_activity'] },
},
{
id: 'activityEventId',
title: 'Event ID',
type: 'short-input',
placeholder: 'Event ID filter (comma-separated)',
condition: { field: 'operation', value: ['get_activity'] },
},
{
id: 'activitySide',
title: 'Trade Side',
type: 'dropdown',
options: [
{ label: 'All', id: '' },
{ label: 'Buy', id: 'BUY' },
{ label: 'Sell', id: 'SELL' },
],
condition: { field: 'operation', value: ['get_activity'] },
},
{
id: 'activitySortBy',
title: 'Sort By',
type: 'dropdown',
options: [
{ label: 'Timestamp', id: 'TIMESTAMP' },
{ label: 'Tokens', id: 'TOKENS' },
{ label: 'Cash', id: 'CASH' },
],
condition: { field: 'operation', value: ['get_activity'] },
},
{
id: 'activitySortDirection',
title: 'Sort Direction',
type: 'dropdown',
options: [
{ label: 'Descending', id: 'DESC' },
{ label: 'Ascending', id: 'ASC' },
],
condition: { field: 'operation', value: ['get_activity'] },
},
{
id: 'activityStart',
title: 'Start Timestamp',
type: 'short-input',
placeholder: 'Unix timestamp (seconds)',
condition: { field: 'operation', value: ['get_activity'] },
},
{
id: 'activityEnd',
title: 'End Timestamp',
type: 'short-input',
placeholder: 'Unix timestamp (seconds)',
condition: { field: 'operation', value: ['get_activity'] },
},
// Leaderboard-specific fields
{
id: 'leaderboardCategory',
title: 'Category',
type: 'dropdown',
options: [
{ label: 'Overall', id: 'OVERALL' },
{ label: 'Politics', id: 'POLITICS' },
{ label: 'Sports', id: 'SPORTS' },
{ label: 'Crypto', id: 'CRYPTO' },
{ label: 'Culture', id: 'CULTURE' },
{ label: 'Mentions', id: 'MENTIONS' },
{ label: 'Weather', id: 'WEATHER' },
{ label: 'Economics', id: 'ECONOMICS' },
{ label: 'Tech', id: 'TECH' },
{ label: 'Finance', id: 'FINANCE' },
],
condition: { field: 'operation', value: ['get_leaderboard'] },
},
{
id: 'leaderboardTimePeriod',
title: 'Time Period',
type: 'dropdown',
options: [
{ label: 'Day', id: 'DAY' },
{ label: 'Week', id: 'WEEK' },
{ label: 'Month', id: 'MONTH' },
{ label: 'All Time', id: 'ALL' },
],
condition: { field: 'operation', value: ['get_leaderboard'] },
},
{
id: 'leaderboardOrderBy',
title: 'Order By',
type: 'dropdown',
options: [
{ label: 'Profit/Loss', id: 'PNL' },
{ label: 'Volume', id: 'VOL' },
],
condition: { field: 'operation', value: ['get_leaderboard'] },
},
{
id: 'leaderboardUser',
title: 'User Address',
type: 'short-input',
placeholder: 'Filter by specific user wallet',
condition: { field: 'operation', value: ['get_leaderboard'] },
},
{
id: 'leaderboardUserName',
title: 'Username',
type: 'short-input',
placeholder: 'Filter by username',
condition: { field: 'operation', value: ['get_leaderboard'] },
},
// Market Holders-specific fields
{
id: 'holdersMarket',
title: 'Condition ID',
type: 'short-input',
placeholder: 'Condition ID (comma-separated)',
required: true,
condition: { field: 'operation', value: ['get_holders'] },
},
{
id: 'holdersMinBalance',
title: 'Min Balance',
type: 'short-input',
placeholder: 'Minimum balance threshold (default: 1)',
condition: { field: 'operation', value: ['get_holders'] },
},
// Token ID for CLOB operations
{
id: 'tokenId',
@@ -205,11 +475,11 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
// Filters for list operations
{
id: 'closed',
title: 'Status',
title: 'Closed Status',
type: 'dropdown',
options: [
{ label: 'All', id: '' },
{ label: 'Active Only', id: 'false' },
{ label: 'Open Only', id: 'false' },
{ label: 'Closed Only', id: 'true' },
],
condition: { field: 'operation', value: ['get_markets', 'get_events'] },
@@ -269,7 +539,18 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
placeholder: 'Number of results (max 50)',
condition: {
field: 'operation',
value: ['get_markets', 'get_events', 'get_tags', 'search', 'get_series', 'get_trades'],
value: [
'get_markets',
'get_events',
'get_tags',
'search',
'get_series',
'get_trades',
'get_positions',
'get_activity',
'get_leaderboard',
'get_holders',
],
},
},
{
@@ -279,9 +560,25 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
placeholder: 'Pagination offset',
condition: {
field: 'operation',
value: ['get_markets', 'get_events', 'get_tags', 'search', 'get_series', 'get_trades'],
value: [
'get_markets',
'get_events',
'get_tags',
'get_series',
'get_trades',
'get_positions',
'get_activity',
'get_leaderboard',
],
},
},
{
id: 'page',
title: 'Page',
type: 'short-input',
placeholder: 'Page number (1-indexed)',
condition: { field: 'operation', value: ['search'] },
},
],
tools: {
access: [
@@ -302,6 +599,9 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
'polymarket_get_tick_size',
'polymarket_get_positions',
'polymarket_get_trades',
'polymarket_get_activity',
'polymarket_get_leaderboard',
'polymarket_get_holders',
],
config: {
tool: (params) => {
@@ -340,12 +640,49 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
return 'polymarket_get_positions'
case 'get_trades':
return 'polymarket_get_trades'
case 'get_activity':
return 'polymarket_get_activity'
case 'get_leaderboard':
return 'polymarket_get_leaderboard'
case 'get_holders':
return 'polymarket_get_holders'
default:
return 'polymarket_get_markets'
}
},
params: (params) => {
const { operation, marketSlug, eventSlug, orderEvents, order, ...rest } = params
const {
operation,
marketSlug,
eventSlug,
orderEvents,
order,
positionEventId,
tradeSide,
positionSortBy,
positionSortDirection,
positionTitle,
// Activity params
activityUser,
activityType,
activityMarket,
activityEventId,
activitySide,
activitySortBy,
activitySortDirection,
activityStart,
activityEnd,
// Leaderboard params
leaderboardCategory,
leaderboardTimePeriod,
leaderboardOrderBy,
leaderboardUser,
leaderboardUserName,
// Holders params
holdersMarket,
holdersMinBalance,
...rest
} = params
const cleanParams: Record<string, any> = {}
// Map marketSlug to slug for get_market
@@ -365,6 +702,51 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
cleanParams.order = orderEvents
}
// Map positionEventId to eventId for positions and trades
if ((operation === 'get_positions' || operation === 'get_trades') && positionEventId) {
cleanParams.eventId = positionEventId
}
// Map tradeSide to side for trades
if (operation === 'get_trades' && tradeSide) {
cleanParams.side = tradeSide
}
// Map position-specific fields
if (operation === 'get_positions') {
if (positionSortBy) cleanParams.sortBy = positionSortBy
if (positionSortDirection) cleanParams.sortDirection = positionSortDirection
if (positionTitle) cleanParams.title = positionTitle
}
// Map activity-specific fields
if (operation === 'get_activity') {
if (activityUser) cleanParams.user = activityUser
if (activityType) cleanParams.type = activityType
if (activityMarket) cleanParams.market = activityMarket
if (activityEventId) cleanParams.eventId = activityEventId
if (activitySide) cleanParams.side = activitySide
if (activitySortBy) cleanParams.sortBy = activitySortBy
if (activitySortDirection) cleanParams.sortDirection = activitySortDirection
if (activityStart) cleanParams.start = Number(activityStart)
if (activityEnd) cleanParams.end = Number(activityEnd)
}
// Map leaderboard-specific fields
if (operation === 'get_leaderboard') {
if (leaderboardCategory) cleanParams.category = leaderboardCategory
if (leaderboardTimePeriod) cleanParams.timePeriod = leaderboardTimePeriod
if (leaderboardOrderBy) cleanParams.orderBy = leaderboardOrderBy
if (leaderboardUser) cleanParams.user = leaderboardUser
if (leaderboardUserName) cleanParams.userName = leaderboardUserName
}
// Map holders-specific fields
if (operation === 'get_holders') {
if (holdersMarket) cleanParams.market = holdersMarket
if (holdersMinBalance) cleanParams.minBalance = holdersMinBalance
}
// Convert numeric fields from string to number for get_price_history
if (operation === 'get_price_history') {
if (rest.fidelity) cleanParams.fidelity = Number(rest.fidelity)
@@ -394,13 +776,55 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
seriesId: { type: 'string', description: 'Series ID' },
query: { type: 'string', description: 'Search query' },
user: { type: 'string', description: 'User wallet address' },
market: { type: 'string', description: 'Market ID filter' },
market: { type: 'string', description: 'Condition ID filter' },
positionEventId: { type: 'string', description: 'Event ID filter for positions/trades' },
tokenId: { type: 'string', description: 'CLOB Token ID' },
side: { type: 'string', description: 'Order side (buy/sell)' },
interval: { type: 'string', description: 'Price history interval' },
fidelity: { type: 'number', description: 'Data resolution in minutes' },
startTs: { type: 'number', description: 'Start timestamp (Unix)' },
endTs: { type: 'number', description: 'End timestamp (Unix)' },
// Positions-specific inputs
sizeThreshold: { type: 'string', description: 'Minimum position size threshold' },
redeemable: { type: 'string', description: 'Filter by redeemable status' },
mergeable: { type: 'string', description: 'Filter by mergeable status' },
positionSortBy: { type: 'string', description: 'Sort positions by field' },
positionSortDirection: { type: 'string', description: 'Sort direction (ASC/DESC)' },
positionTitle: { type: 'string', description: 'Filter positions by title' },
// Trades-specific inputs
tradeSide: { type: 'string', description: 'Filter trades by side (BUY/SELL)' },
takerOnly: { type: 'string', description: 'Filter to taker trades only' },
filterType: { type: 'string', description: 'Trade filter type (CASH/TOKENS)' },
filterAmount: { type: 'string', description: 'Minimum trade amount threshold' },
// List operation filters
closed: { type: 'string', description: 'Filter by closed status' },
order: { type: 'string', description: 'Sort field for markets' },
orderEvents: { type: 'string', description: 'Sort field for events' },
ascending: { type: 'string', description: 'Sort order (true/false)' },
tagId: { type: 'string', description: 'Filter by tag ID' },
// Pagination
limit: { type: 'string', description: 'Number of results per page' },
offset: { type: 'string', description: 'Pagination offset' },
page: { type: 'string', description: 'Page number for search' },
// Activity-specific inputs
activityUser: { type: 'string', description: 'User wallet address for activity' },
activityType: { type: 'string', description: 'Activity type filter' },
activityMarket: { type: 'string', description: 'Condition ID filter for activity' },
activityEventId: { type: 'string', description: 'Event ID filter for activity' },
activitySide: { type: 'string', description: 'Trade side filter for activity' },
activitySortBy: { type: 'string', description: 'Sort field for activity' },
activitySortDirection: { type: 'string', description: 'Sort direction for activity' },
activityStart: { type: 'string', description: 'Start timestamp for activity' },
activityEnd: { type: 'string', description: 'End timestamp for activity' },
// Leaderboard-specific inputs
leaderboardCategory: { type: 'string', description: 'Leaderboard category' },
leaderboardTimePeriod: { type: 'string', description: 'Leaderboard time period' },
leaderboardOrderBy: { type: 'string', description: 'Leaderboard order by field' },
leaderboardUser: { type: 'string', description: 'Filter leaderboard by user' },
leaderboardUserName: { type: 'string', description: 'Filter leaderboard by username' },
// Holders-specific inputs
holdersMarket: { type: 'string', description: 'Condition ID for holders lookup' },
holdersMinBalance: { type: 'string', description: 'Minimum balance threshold' },
},
outputs: {
// List operations
@@ -422,11 +846,19 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
description: 'Search results with markets, events, profiles (search)',
},
// CLOB operations
orderbook: { type: 'json', description: 'Order book with bids and asks (get_orderbook)' },
orderbook: {
type: 'json',
description: 'Order book with bids and asks (get_orderbook)',
},
price: { type: 'string', description: 'Market price (get_price, get_last_trade_price)' },
side: { type: 'string', description: 'Last trade side - BUY or SELL (get_last_trade_price)' },
midpoint: { type: 'string', description: 'Midpoint price (get_midpoint)' },
history: { type: 'json', description: 'Price history entries (get_price_history)' },
spread: { type: 'json', description: 'Bid-ask spread (get_spread)' },
spread: { type: 'json', description: 'Spread value object (get_spread)' },
tickSize: { type: 'string', description: 'Minimum tick size (get_tick_size)' },
// Data API operations
activity: { type: 'json', description: 'Array of user activity entries (get_activity)' },
leaderboard: { type: 'json', description: 'Array of leaderboard entries (get_leaderboard)' },
holders: { type: 'json', description: 'Array of market holder groups (get_holders)' },
},
}

View File

@@ -58,7 +58,7 @@ import { IntercomBlock, IntercomV2Block } from '@/blocks/blocks/intercom'
import { JinaBlock } from '@/blocks/blocks/jina'
import { JiraBlock } from '@/blocks/blocks/jira'
import { JiraServiceManagementBlock } from '@/blocks/blocks/jira_service_management'
import { KalshiBlock } from '@/blocks/blocks/kalshi'
import { KalshiBlock, KalshiV2Block } from '@/blocks/blocks/kalshi'
import { KnowledgeBlock } from '@/blocks/blocks/knowledge'
import { LangsmithBlock } from '@/blocks/blocks/langsmith'
import { LemlistBlock } from '@/blocks/blocks/lemlist'
@@ -222,6 +222,7 @@ export const registry: Record<string, BlockConfig> = {
jira: JiraBlock,
jira_service_management: JiraServiceManagementBlock,
kalshi: KalshiBlock,
kalshi_v2: KalshiV2Block,
knowledge: KnowledgeBlock,
langsmith: LangsmithBlock,
lemlist: LemlistBlock,

View File

@@ -158,3 +158,300 @@ export const kalshiAmendOrderTool: ToolConfig<KalshiAmendOrderParams, KalshiAmen
},
},
}
export interface KalshiAmendOrderV2Params extends KalshiAuthParams {
orderId: string // Order ID to amend (required)
ticker: string // Market ticker (required)
side: string // 'yes' or 'no' (required)
action: string // 'buy' or 'sell' (required)
clientOrderId?: string // Original client order ID (optional in V2)
updatedClientOrderId?: string // New client order ID (optional in V2)
count?: string // Updated quantity
yesPrice?: string // Updated yes price in cents (1-99)
noPrice?: string // Updated no price in cents (1-99)
yesPriceDollars?: string // Updated yes price in dollars
noPriceDollars?: string // Updated no price in dollars
countFp?: string // Count in fixed-point for fractional contracts
}
export interface KalshiAmendOrderV2Order {
order_id: string
user_id: string | null
ticker: string
event_ticker: string
status: string
side: string
type: string
yes_price: number | null
no_price: number | null
action: string
count: number
remaining_count: number
created_time: string
expiration_time: string | null
order_group_id: string | null
client_order_id: string | null
place_count: number | null
decrease_count: number | null
queue_position: number | null
maker_fill_count: number | null
taker_fill_count: number | null
maker_fees: number | null
taker_fees: number | null
last_update_time: string | null
take_profit_order_id: string | null
stop_loss_order_id: string | null
amend_count: number | null
amend_taker_fill_count: number | null
}
export interface KalshiAmendOrderV2Response {
success: boolean
output: {
old_order: KalshiAmendOrderV2Order
order: KalshiAmendOrderV2Order
}
}
export const kalshiAmendOrderV2Tool: ToolConfig<
KalshiAmendOrderV2Params,
KalshiAmendOrderV2Response
> = {
id: 'kalshi_amend_order_v2',
name: 'Amend Order on Kalshi V2',
description:
'Modify the price or quantity of an existing order on Kalshi (V2 with full API response)',
version: '2.0.0',
params: {
keyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your Kalshi API Key ID',
},
privateKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your RSA Private Key (PEM format)',
},
orderId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The order ID to amend',
},
ticker: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Market ticker',
},
side: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: "Side of the order: 'yes' or 'no'",
},
action: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: "Action type: 'buy' or 'sell'",
},
clientOrderId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'The original client-specified order ID',
},
updatedClientOrderId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'The new client-specified order ID after amendment',
},
count: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Updated quantity for the order',
},
yesPrice: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Updated yes price in cents (1-99)',
},
noPrice: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Updated no price in cents (1-99)',
},
yesPriceDollars: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Updated yes price in dollars (e.g., "0.56")',
},
noPriceDollars: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Updated no price in dollars (e.g., "0.56")',
},
countFp: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Count in fixed-point for fractional contracts',
},
},
request: {
url: (params) => buildKalshiUrl(`/portfolio/orders/${params.orderId}/amend`),
method: 'POST',
headers: (params) => {
const path = `/trade-api/v2/portfolio/orders/${params.orderId}/amend`
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'POST', path)
},
body: (params) => {
const body: Record<string, any> = {
ticker: params.ticker,
side: params.side.toLowerCase(),
action: params.action.toLowerCase(),
}
if (params.clientOrderId) body.client_order_id = params.clientOrderId
if (params.updatedClientOrderId) body.updated_client_order_id = params.updatedClientOrderId
if (params.count) body.count = Number.parseInt(params.count, 10)
if (params.yesPrice) body.yes_price = Number.parseInt(params.yesPrice, 10)
if (params.noPrice) body.no_price = Number.parseInt(params.noPrice, 10)
if (params.yesPriceDollars) body.yes_price_dollars = params.yesPriceDollars
if (params.noPriceDollars) body.no_price_dollars = params.noPriceDollars
if (params.countFp) body.count_fp = params.countFp
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'amend_order_v2')
}
const mapOrder = (order: any): KalshiAmendOrderV2Order => ({
order_id: order.order_id ?? null,
user_id: order.user_id ?? null,
ticker: order.ticker ?? null,
event_ticker: order.event_ticker ?? null,
status: order.status ?? null,
side: order.side ?? null,
type: order.type ?? null,
yes_price: order.yes_price ?? null,
no_price: order.no_price ?? null,
action: order.action ?? null,
count: order.count ?? null,
remaining_count: order.remaining_count ?? null,
created_time: order.created_time ?? null,
expiration_time: order.expiration_time ?? null,
order_group_id: order.order_group_id ?? null,
client_order_id: order.client_order_id ?? null,
place_count: order.place_count ?? null,
decrease_count: order.decrease_count ?? null,
queue_position: order.queue_position ?? null,
maker_fill_count: order.maker_fill_count ?? null,
taker_fill_count: order.taker_fill_count ?? null,
maker_fees: order.maker_fees ?? null,
taker_fees: order.taker_fees ?? null,
last_update_time: order.last_update_time ?? null,
take_profit_order_id: order.take_profit_order_id ?? null,
stop_loss_order_id: order.stop_loss_order_id ?? null,
amend_count: order.amend_count ?? null,
amend_taker_fill_count: order.amend_taker_fill_count ?? null,
})
return {
success: true,
output: {
old_order: mapOrder(data.old_order || {}),
order: mapOrder(data.order || {}),
},
}
},
outputs: {
old_order: {
type: 'object',
description: 'The original order object before amendment',
properties: {
order_id: { type: 'string', description: 'Order ID' },
user_id: { type: 'string', description: 'User ID' },
ticker: { type: 'string', description: 'Market ticker' },
event_ticker: { type: 'string', description: 'Event ticker' },
status: { type: 'string', description: 'Order status' },
side: { type: 'string', description: 'Order side (yes/no)' },
type: { type: 'string', description: 'Order type (limit/market)' },
yes_price: { type: 'number', description: 'Yes price in cents' },
no_price: { type: 'number', description: 'No price in cents' },
action: { type: 'string', description: 'Action (buy/sell)' },
count: { type: 'number', description: 'Number of contracts' },
remaining_count: { type: 'number', description: 'Remaining contracts' },
created_time: { type: 'string', description: 'Order creation time' },
expiration_time: { type: 'string', description: 'Order expiration time' },
order_group_id: { type: 'string', description: 'Order group ID' },
client_order_id: { type: 'string', description: 'Client order ID' },
place_count: { type: 'number', description: 'Place count' },
decrease_count: { type: 'number', description: 'Decrease count' },
queue_position: { type: 'number', description: 'Queue position' },
maker_fill_count: { type: 'number', description: 'Maker fill count' },
taker_fill_count: { type: 'number', description: 'Taker fill count' },
maker_fees: { type: 'number', description: 'Maker fees' },
taker_fees: { type: 'number', description: 'Taker fees' },
last_update_time: { type: 'string', description: 'Last update time' },
take_profit_order_id: { type: 'string', description: 'Take profit order ID' },
stop_loss_order_id: { type: 'string', description: 'Stop loss order ID' },
amend_count: { type: 'number', description: 'Amend count' },
amend_taker_fill_count: { type: 'number', description: 'Amend taker fill count' },
},
},
order: {
type: 'object',
description: 'The amended order object with full API response fields',
properties: {
order_id: { type: 'string', description: 'Order ID' },
user_id: { type: 'string', description: 'User ID' },
ticker: { type: 'string', description: 'Market ticker' },
event_ticker: { type: 'string', description: 'Event ticker' },
status: { type: 'string', description: 'Order status' },
side: { type: 'string', description: 'Order side (yes/no)' },
type: { type: 'string', description: 'Order type (limit/market)' },
yes_price: { type: 'number', description: 'Yes price in cents' },
no_price: { type: 'number', description: 'No price in cents' },
action: { type: 'string', description: 'Action (buy/sell)' },
count: { type: 'number', description: 'Number of contracts' },
remaining_count: { type: 'number', description: 'Remaining contracts' },
created_time: { type: 'string', description: 'Order creation time' },
expiration_time: { type: 'string', description: 'Order expiration time' },
order_group_id: { type: 'string', description: 'Order group ID' },
client_order_id: { type: 'string', description: 'Client order ID' },
place_count: { type: 'number', description: 'Place count' },
decrease_count: { type: 'number', description: 'Decrease count' },
queue_position: { type: 'number', description: 'Queue position' },
maker_fill_count: { type: 'number', description: 'Maker fill count' },
taker_fill_count: { type: 'number', description: 'Taker fill count' },
maker_fees: { type: 'number', description: 'Maker fees' },
taker_fees: { type: 'number', description: 'Taker fees' },
last_update_time: { type: 'string', description: 'Last update time' },
take_profit_order_id: { type: 'string', description: 'Take profit order ID' },
stop_loss_order_id: { type: 'string', description: 'Stop loss order ID' },
amend_count: { type: 'number', description: 'Amend count' },
amend_taker_fill_count: { type: 'number', description: 'Amend taker fill count' },
},
},
},
}

View File

@@ -78,3 +78,193 @@ export const kalshiCancelOrderTool: ToolConfig<KalshiCancelOrderParams, KalshiCa
},
},
}
export interface KalshiCancelOrderV2Params extends KalshiAuthParams {
orderId: string // Order ID to cancel (required)
}
export interface KalshiCancelOrderV2Response {
success: boolean
output: {
order: {
order_id: string
user_id: string | null
client_order_id: string | null
ticker: string
side: string
action: string
type: string
status: string
yes_price: number | null
no_price: number | null
yes_price_dollars: string | null
no_price_dollars: string | null
fill_count: number | null
fill_count_fp: string | null
remaining_count: number | null
remaining_count_fp: string | null
initial_count: number | null
initial_count_fp: string | null
taker_fees: number | null
maker_fees: number | null
taker_fees_dollars: string | null
maker_fees_dollars: string | null
taker_fill_cost: number | null
maker_fill_cost: number | null
taker_fill_cost_dollars: string | null
maker_fill_cost_dollars: string | null
queue_position: number | null
expiration_time: string | null
created_time: string | null
last_update_time: string | null
self_trade_prevention_type: string | null
order_group_id: string | null
cancel_order_on_pause: boolean | null
}
reduced_by: number
reduced_by_fp: string | null
}
}
export const kalshiCancelOrderV2Tool: ToolConfig<
KalshiCancelOrderV2Params,
KalshiCancelOrderV2Response
> = {
id: 'kalshi_cancel_order_v2',
name: 'Cancel Order on Kalshi V2',
description: 'Cancel an existing order on Kalshi (V2 with full API response)',
version: '2.0.0',
params: {
keyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your Kalshi API Key ID',
},
privateKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your RSA Private Key (PEM format)',
},
orderId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The order ID to cancel',
},
},
request: {
url: (params) => buildKalshiUrl(`/portfolio/orders/${params.orderId}`),
method: 'DELETE',
headers: (params) => {
const path = `/trade-api/v2/portfolio/orders/${params.orderId}`
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'DELETE', path)
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'cancel_order_v2')
}
const order = data.order || {}
return {
success: true,
output: {
order: {
order_id: order.order_id ?? null,
user_id: order.user_id ?? null,
client_order_id: order.client_order_id ?? null,
ticker: order.ticker ?? null,
side: order.side ?? null,
action: order.action ?? null,
type: order.type ?? null,
status: order.status ?? null,
yes_price: order.yes_price ?? null,
no_price: order.no_price ?? null,
yes_price_dollars: order.yes_price_dollars ?? null,
no_price_dollars: order.no_price_dollars ?? null,
fill_count: order.fill_count ?? null,
fill_count_fp: order.fill_count_fp ?? null,
remaining_count: order.remaining_count ?? null,
remaining_count_fp: order.remaining_count_fp ?? null,
initial_count: order.initial_count ?? null,
initial_count_fp: order.initial_count_fp ?? null,
taker_fees: order.taker_fees ?? null,
maker_fees: order.maker_fees ?? null,
taker_fees_dollars: order.taker_fees_dollars ?? null,
maker_fees_dollars: order.maker_fees_dollars ?? null,
taker_fill_cost: order.taker_fill_cost ?? null,
maker_fill_cost: order.maker_fill_cost ?? null,
taker_fill_cost_dollars: order.taker_fill_cost_dollars ?? null,
maker_fill_cost_dollars: order.maker_fill_cost_dollars ?? null,
queue_position: order.queue_position ?? null,
expiration_time: order.expiration_time ?? null,
created_time: order.created_time ?? null,
last_update_time: order.last_update_time ?? null,
self_trade_prevention_type: order.self_trade_prevention_type ?? null,
order_group_id: order.order_group_id ?? null,
cancel_order_on_pause: order.cancel_order_on_pause ?? null,
},
reduced_by: data.reduced_by ?? 0,
reduced_by_fp: data.reduced_by_fp ?? null,
},
}
},
outputs: {
order: {
type: 'object',
description: 'The canceled order object with full API response fields',
properties: {
order_id: { type: 'string', description: 'Order ID' },
user_id: { type: 'string', description: 'User ID' },
client_order_id: { type: 'string', description: 'Client order ID' },
ticker: { type: 'string', description: 'Market ticker' },
side: { type: 'string', description: 'Order side (yes/no)' },
action: { type: 'string', description: 'Action (buy/sell)' },
type: { type: 'string', description: 'Order type (limit/market)' },
status: { type: 'string', description: 'Order status (resting/canceled/executed)' },
yes_price: { type: 'number', description: 'Yes price in cents' },
no_price: { type: 'number', description: 'No price in cents' },
yes_price_dollars: { type: 'string', description: 'Yes price in dollars' },
no_price_dollars: { type: 'string', description: 'No price in dollars' },
fill_count: { type: 'number', description: 'Filled contract count' },
fill_count_fp: { type: 'string', description: 'Filled count (fixed-point)' },
remaining_count: { type: 'number', description: 'Remaining contracts' },
remaining_count_fp: { type: 'string', description: 'Remaining count (fixed-point)' },
initial_count: { type: 'number', description: 'Initial contract count' },
initial_count_fp: { type: 'string', description: 'Initial count (fixed-point)' },
taker_fees: { type: 'number', description: 'Taker fees in cents' },
maker_fees: { type: 'number', description: 'Maker fees in cents' },
taker_fees_dollars: { type: 'string', description: 'Taker fees in dollars' },
maker_fees_dollars: { type: 'string', description: 'Maker fees in dollars' },
taker_fill_cost: { type: 'number', description: 'Taker fill cost in cents' },
maker_fill_cost: { type: 'number', description: 'Maker fill cost in cents' },
taker_fill_cost_dollars: { type: 'string', description: 'Taker fill cost in dollars' },
maker_fill_cost_dollars: { type: 'string', description: 'Maker fill cost in dollars' },
queue_position: { type: 'number', description: 'Queue position (deprecated)' },
expiration_time: { type: 'string', description: 'Order expiration time' },
created_time: { type: 'string', description: 'Order creation time' },
last_update_time: { type: 'string', description: 'Last update time' },
self_trade_prevention_type: { type: 'string', description: 'Self-trade prevention type' },
order_group_id: { type: 'string', description: 'Order group ID' },
cancel_order_on_pause: { type: 'boolean', description: 'Cancel on market pause' },
},
},
reduced_by: {
type: 'number',
description: 'Number of contracts canceled',
},
reduced_by_fp: {
type: 'string',
description: 'Number of contracts canceled in fixed-point format',
},
},
}

View File

@@ -209,3 +209,344 @@ export const kalshiCreateOrderTool: ToolConfig<KalshiCreateOrderParams, KalshiCr
},
},
}
export interface KalshiCreateOrderV2Params extends KalshiAuthParams {
ticker: string // Market ticker (required)
side: string // 'yes' or 'no' (required)
action: string // 'buy' or 'sell' (required)
count?: string // Number of contracts (optional - provide count or countFp)
type?: string // 'limit' or 'market' (default: limit)
yesPrice?: string // Yes price in cents (1-99)
noPrice?: string // No price in cents (1-99)
yesPriceDollars?: string // Yes price in dollars (e.g., "0.56")
noPriceDollars?: string // No price in dollars (e.g., "0.56")
clientOrderId?: string // Custom order identifier
expirationTs?: string // Unix timestamp expiration
timeInForce?: string // 'fill_or_kill', 'good_till_canceled', 'immediate_or_cancel'
buyMaxCost?: string // Maximum cost in cents
postOnly?: string // 'true' or 'false' - maker-only orders
reduceOnly?: string // 'true' or 'false' - position reduction only
selfTradePreventionType?: string // 'taker_at_cross' or 'maker'
orderGroupId?: string // Associated order group
countFp?: string // Count in fixed-point (for fractional contracts)
cancelOrderOnPause?: string // 'true' or 'false' - cancel on market pause
subaccount?: string // Subaccount to use for the order
}
export interface KalshiCreateOrderV2Response {
success: boolean
output: {
order: {
order_id: string
user_id: string | null
client_order_id: string | null
ticker: string
side: string
action: string
type: string
status: string
yes_price: number | null
no_price: number | null
yes_price_dollars: string | null
no_price_dollars: string | null
fill_count: number | null
fill_count_fp: string | null
remaining_count: number | null
remaining_count_fp: string | null
initial_count: number | null
initial_count_fp: string | null
taker_fees: number | null
maker_fees: number | null
taker_fees_dollars: string | null
maker_fees_dollars: string | null
taker_fill_cost: number | null
maker_fill_cost: number | null
taker_fill_cost_dollars: string | null
maker_fill_cost_dollars: string | null
queue_position: number | null
expiration_time: string | null
created_time: string | null
last_update_time: string | null
self_trade_prevention_type: string | null
order_group_id: string | null
cancel_order_on_pause: boolean | null
}
}
}
export const kalshiCreateOrderV2Tool: ToolConfig<
KalshiCreateOrderV2Params,
KalshiCreateOrderV2Response
> = {
id: 'kalshi_create_order_v2',
name: 'Create Order on Kalshi V2',
description: 'Create a new order on a Kalshi prediction market (V2 with full API response)',
version: '2.0.0',
params: {
keyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your Kalshi API Key ID',
},
privateKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your RSA Private Key (PEM format)',
},
ticker: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Market ticker (e.g., KXBTC-24DEC31)',
},
side: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: "Side of the order: 'yes' or 'no'",
},
action: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: "Action type: 'buy' or 'sell'",
},
count: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Number of contracts (provide count or countFp)',
},
type: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: "Order type: 'limit' or 'market' (default: limit)",
},
yesPrice: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Yes price in cents (1-99)',
},
noPrice: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'No price in cents (1-99)',
},
yesPriceDollars: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Yes price in dollars (e.g., "0.56")',
},
noPriceDollars: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'No price in dollars (e.g., "0.56")',
},
clientOrderId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Custom order identifier',
},
expirationTs: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Unix timestamp for order expiration',
},
timeInForce: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: "Time in force: 'fill_or_kill', 'good_till_canceled', 'immediate_or_cancel'",
},
buyMaxCost: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Maximum cost in cents (auto-enables fill_or_kill)',
},
postOnly: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: "Set to 'true' for maker-only orders",
},
reduceOnly: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: "Set to 'true' for position reduction only",
},
selfTradePreventionType: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: "Self-trade prevention: 'taker_at_cross' or 'maker'",
},
orderGroupId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Associated order group ID',
},
countFp: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Count in fixed-point for fractional contracts',
},
cancelOrderOnPause: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: "Set to 'true' to cancel order on market pause",
},
subaccount: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Subaccount to use for the order',
},
},
request: {
url: () => buildKalshiUrl('/portfolio/orders'),
method: 'POST',
headers: (params) => {
const path = '/trade-api/v2/portfolio/orders'
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'POST', path)
},
body: (params) => {
const body: Record<string, any> = {
ticker: params.ticker,
side: params.side.toLowerCase(),
action: params.action.toLowerCase(),
}
// count or count_fp must be provided (but not both required)
if (params.count) body.count = Number.parseInt(params.count, 10)
if (params.countFp) body.count_fp = params.countFp
if (params.type) body.type = params.type.toLowerCase()
if (params.yesPrice) body.yes_price = Number.parseInt(params.yesPrice, 10)
if (params.noPrice) body.no_price = Number.parseInt(params.noPrice, 10)
if (params.yesPriceDollars) body.yes_price_dollars = params.yesPriceDollars
if (params.noPriceDollars) body.no_price_dollars = params.noPriceDollars
if (params.clientOrderId) body.client_order_id = params.clientOrderId
if (params.expirationTs) body.expiration_ts = Number.parseInt(params.expirationTs, 10)
if (params.timeInForce) body.time_in_force = params.timeInForce
if (params.buyMaxCost) body.buy_max_cost = Number.parseInt(params.buyMaxCost, 10)
if (params.postOnly) body.post_only = params.postOnly === 'true'
if (params.reduceOnly) body.reduce_only = params.reduceOnly === 'true'
if (params.selfTradePreventionType)
body.self_trade_prevention_type = params.selfTradePreventionType
if (params.orderGroupId) body.order_group_id = params.orderGroupId
if (params.cancelOrderOnPause)
body.cancel_order_on_pause = params.cancelOrderOnPause === 'true'
if (params.subaccount) body.subaccount = params.subaccount
return body
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'create_order_v2')
}
const order = data.order || {}
return {
success: true,
output: {
order: {
order_id: order.order_id ?? null,
user_id: order.user_id ?? null,
client_order_id: order.client_order_id ?? null,
ticker: order.ticker ?? null,
side: order.side ?? null,
action: order.action ?? null,
type: order.type ?? null,
status: order.status ?? null,
yes_price: order.yes_price ?? null,
no_price: order.no_price ?? null,
yes_price_dollars: order.yes_price_dollars ?? null,
no_price_dollars: order.no_price_dollars ?? null,
fill_count: order.fill_count ?? null,
fill_count_fp: order.fill_count_fp ?? null,
remaining_count: order.remaining_count ?? null,
remaining_count_fp: order.remaining_count_fp ?? null,
initial_count: order.initial_count ?? null,
initial_count_fp: order.initial_count_fp ?? null,
taker_fees: order.taker_fees ?? null,
maker_fees: order.maker_fees ?? null,
taker_fees_dollars: order.taker_fees_dollars ?? null,
maker_fees_dollars: order.maker_fees_dollars ?? null,
taker_fill_cost: order.taker_fill_cost ?? null,
maker_fill_cost: order.maker_fill_cost ?? null,
taker_fill_cost_dollars: order.taker_fill_cost_dollars ?? null,
maker_fill_cost_dollars: order.maker_fill_cost_dollars ?? null,
queue_position: order.queue_position ?? null,
expiration_time: order.expiration_time ?? null,
created_time: order.created_time ?? null,
last_update_time: order.last_update_time ?? null,
self_trade_prevention_type: order.self_trade_prevention_type ?? null,
order_group_id: order.order_group_id ?? null,
cancel_order_on_pause: order.cancel_order_on_pause ?? null,
},
},
}
},
outputs: {
order: {
type: 'object',
description: 'The created order object with full API response fields',
properties: {
order_id: { type: 'string', description: 'Order ID' },
user_id: { type: 'string', description: 'User ID' },
client_order_id: { type: 'string', description: 'Client order ID' },
ticker: { type: 'string', description: 'Market ticker' },
side: { type: 'string', description: 'Order side (yes/no)' },
action: { type: 'string', description: 'Action (buy/sell)' },
type: { type: 'string', description: 'Order type (limit/market)' },
status: { type: 'string', description: 'Order status (resting/canceled/executed)' },
yes_price: { type: 'number', description: 'Yes price in cents' },
no_price: { type: 'number', description: 'No price in cents' },
yes_price_dollars: { type: 'string', description: 'Yes price in dollars' },
no_price_dollars: { type: 'string', description: 'No price in dollars' },
fill_count: { type: 'number', description: 'Filled contract count' },
fill_count_fp: { type: 'string', description: 'Filled count (fixed-point)' },
remaining_count: { type: 'number', description: 'Remaining contracts' },
remaining_count_fp: { type: 'string', description: 'Remaining count (fixed-point)' },
initial_count: { type: 'number', description: 'Initial contract count' },
initial_count_fp: { type: 'string', description: 'Initial count (fixed-point)' },
taker_fees: { type: 'number', description: 'Taker fees in cents' },
maker_fees: { type: 'number', description: 'Maker fees in cents' },
taker_fees_dollars: { type: 'string', description: 'Taker fees in dollars' },
maker_fees_dollars: { type: 'string', description: 'Maker fees in dollars' },
taker_fill_cost: { type: 'number', description: 'Taker fill cost in cents' },
maker_fill_cost: { type: 'number', description: 'Maker fill cost in cents' },
taker_fill_cost_dollars: { type: 'string', description: 'Taker fill cost in dollars' },
maker_fill_cost_dollars: { type: 'string', description: 'Maker fill cost in dollars' },
queue_position: { type: 'number', description: 'Queue position (deprecated)' },
expiration_time: { type: 'string', description: 'Order expiration time' },
created_time: { type: 'string', description: 'Order creation time' },
last_update_time: { type: 'string', description: 'Last update time' },
self_trade_prevention_type: { type: 'string', description: 'Self-trade prevention type' },
order_group_id: { type: 'string', description: 'Order group ID' },
cancel_order_on_pause: { type: 'boolean', description: 'Cancel on market pause' },
},
},
},
}

View File

@@ -66,3 +66,78 @@ export const kalshiGetBalanceTool: ToolConfig<KalshiGetBalanceParams, KalshiGetB
portfolioValue: { type: 'number', description: 'Portfolio value in cents' },
},
}
/**
* V2 Params for Get Balance
*/
export interface KalshiGetBalanceV2Params extends KalshiAuthParams {}
/**
* V2 Response matching Kalshi API exactly
*/
export interface KalshiGetBalanceV2Response {
success: boolean
output: {
balance: number
portfolio_value: number
updated_ts: number | null
}
}
export const kalshiGetBalanceV2Tool: ToolConfig<
KalshiGetBalanceV2Params,
KalshiGetBalanceV2Response
> = {
id: 'kalshi_get_balance_v2',
name: 'Get Balance from Kalshi V2',
description:
'Retrieve your account balance and portfolio value from Kalshi (V2 - exact API response)',
version: '2.0.0',
params: {
keyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your Kalshi API Key ID',
},
privateKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your RSA Private Key (PEM format)',
},
},
request: {
url: () => buildKalshiUrl('/portfolio/balance'),
method: 'GET',
headers: (params) => {
const path = '/trade-api/v2/portfolio/balance'
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'GET', path)
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'get_balance_v2')
}
return {
success: true,
output: {
balance: data.balance ?? 0,
portfolio_value: data.portfolio_value ?? 0,
updated_ts: data.updated_ts ?? null,
},
}
},
outputs: {
balance: { type: 'number', description: 'Account balance in cents' },
portfolio_value: { type: 'number', description: 'Portfolio value in cents' },
updated_ts: { type: 'number', description: 'Unix timestamp of last update (milliseconds)' },
},
}

View File

@@ -102,3 +102,246 @@ export const kalshiGetCandlesticksTool: ToolConfig<
},
},
}
/**
* BidAskDistribution - OHLC data for yes_bid and yes_ask
*/
export interface BidAskDistribution {
open: number | null
open_dollars: string | null
low: number | null
low_dollars: string | null
high: number | null
high_dollars: string | null
close: number | null
close_dollars: string | null
}
/**
* PriceDistribution - Extended OHLC data for price field
*/
export interface PriceDistribution {
open: number | null
open_dollars: string | null
low: number | null
low_dollars: string | null
high: number | null
high_dollars: string | null
close: number | null
close_dollars: string | null
mean: number | null
mean_dollars: string | null
previous: number | null
previous_dollars: string | null
min: number | null
min_dollars: string | null
max: number | null
max_dollars: string | null
}
/**
* V2 Get Candlesticks Tool - Returns exact Kalshi API response structure
*/
export interface KalshiGetCandlesticksV2Response {
success: boolean
output: {
ticker: string
candlesticks: Array<{
end_period_ts: number | null
yes_bid: BidAskDistribution
yes_ask: BidAskDistribution
price: PriceDistribution
volume: number | null
volume_fp: string | null
open_interest: number | null
open_interest_fp: string | null
}>
}
}
export const kalshiGetCandlesticksV2Tool: ToolConfig<
KalshiGetCandlesticksParams,
KalshiGetCandlesticksV2Response
> = {
id: 'kalshi_get_candlesticks_v2',
name: 'Get Market Candlesticks from Kalshi V2',
description: 'Retrieve OHLC candlestick data for a specific market (V2 - full API response)',
version: '2.0.0',
params: {
seriesTicker: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Series ticker',
},
ticker: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Market ticker (e.g., KXBTC-24DEC31)',
},
startTs: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Start timestamp (Unix seconds)',
},
endTs: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'End timestamp (Unix seconds)',
},
periodInterval: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Period interval: 1 (1min), 60 (1hour), or 1440 (1day)',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
queryParams.append('start_ts', params.startTs.toString())
queryParams.append('end_ts', params.endTs.toString())
queryParams.append('period_interval', params.periodInterval.toString())
const query = queryParams.toString()
const url = buildKalshiUrl(
`/series/${params.seriesTicker}/markets/${params.ticker}/candlesticks`
)
return `${url}?${query}`
},
method: 'GET',
headers: () => ({
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'get_candlesticks_v2')
}
const mapBidAsk = (obj: Record<string, unknown> | null): BidAskDistribution => ({
open: (obj?.open as number) ?? null,
open_dollars: (obj?.open_dollars as string) ?? null,
low: (obj?.low as number) ?? null,
low_dollars: (obj?.low_dollars as string) ?? null,
high: (obj?.high as number) ?? null,
high_dollars: (obj?.high_dollars as string) ?? null,
close: (obj?.close as number) ?? null,
close_dollars: (obj?.close_dollars as string) ?? null,
})
const mapPrice = (obj: Record<string, unknown> | null): PriceDistribution => ({
open: (obj?.open as number) ?? null,
open_dollars: (obj?.open_dollars as string) ?? null,
low: (obj?.low as number) ?? null,
low_dollars: (obj?.low_dollars as string) ?? null,
high: (obj?.high as number) ?? null,
high_dollars: (obj?.high_dollars as string) ?? null,
close: (obj?.close as number) ?? null,
close_dollars: (obj?.close_dollars as string) ?? null,
mean: (obj?.mean as number) ?? null,
mean_dollars: (obj?.mean_dollars as string) ?? null,
previous: (obj?.previous as number) ?? null,
previous_dollars: (obj?.previous_dollars as string) ?? null,
min: (obj?.min as number) ?? null,
min_dollars: (obj?.min_dollars as string) ?? null,
max: (obj?.max as number) ?? null,
max_dollars: (obj?.max_dollars as string) ?? null,
})
const candlesticks = (data.candlesticks || []).map((c: Record<string, unknown>) => ({
end_period_ts: (c.end_period_ts as number) ?? null,
yes_bid: mapBidAsk(c.yes_bid as Record<string, unknown> | null),
yes_ask: mapBidAsk(c.yes_ask as Record<string, unknown> | null),
price: mapPrice(c.price as Record<string, unknown> | null),
volume: (c.volume as number) ?? null,
volume_fp: (c.volume_fp as string) ?? null,
open_interest: (c.open_interest as number) ?? null,
open_interest_fp: (c.open_interest_fp as string) ?? null,
}))
return {
success: true,
output: {
ticker: data.ticker ?? null,
candlesticks,
},
}
},
outputs: {
ticker: {
type: 'string',
description: 'Market ticker',
},
candlesticks: {
type: 'array',
description: 'Array of OHLC candlestick data with nested bid/ask/price objects',
properties: {
end_period_ts: { type: 'number', description: 'End period timestamp (Unix)' },
yes_bid: {
type: 'object',
description: 'Yes bid OHLC data',
properties: {
open: { type: 'number', description: 'Open price (cents)' },
open_dollars: { type: 'string', description: 'Open price (dollars)' },
low: { type: 'number', description: 'Low price (cents)' },
low_dollars: { type: 'string', description: 'Low price (dollars)' },
high: { type: 'number', description: 'High price (cents)' },
high_dollars: { type: 'string', description: 'High price (dollars)' },
close: { type: 'number', description: 'Close price (cents)' },
close_dollars: { type: 'string', description: 'Close price (dollars)' },
},
},
yes_ask: {
type: 'object',
description: 'Yes ask OHLC data',
properties: {
open: { type: 'number', description: 'Open price (cents)' },
open_dollars: { type: 'string', description: 'Open price (dollars)' },
low: { type: 'number', description: 'Low price (cents)' },
low_dollars: { type: 'string', description: 'Low price (dollars)' },
high: { type: 'number', description: 'High price (cents)' },
high_dollars: { type: 'string', description: 'High price (dollars)' },
close: { type: 'number', description: 'Close price (cents)' },
close_dollars: { type: 'string', description: 'Close price (dollars)' },
},
},
price: {
type: 'object',
description: 'Trade price OHLC data with additional statistics',
properties: {
open: { type: 'number', description: 'Open price (cents)' },
open_dollars: { type: 'string', description: 'Open price (dollars)' },
low: { type: 'number', description: 'Low price (cents)' },
low_dollars: { type: 'string', description: 'Low price (dollars)' },
high: { type: 'number', description: 'High price (cents)' },
high_dollars: { type: 'string', description: 'High price (dollars)' },
close: { type: 'number', description: 'Close price (cents)' },
close_dollars: { type: 'string', description: 'Close price (dollars)' },
mean: { type: 'number', description: 'Mean price (cents)' },
mean_dollars: { type: 'string', description: 'Mean price (dollars)' },
previous: { type: 'number', description: 'Previous price (cents)' },
previous_dollars: { type: 'string', description: 'Previous price (dollars)' },
min: { type: 'number', description: 'Min price (cents)' },
min_dollars: { type: 'string', description: 'Min price (dollars)' },
max: { type: 'number', description: 'Max price (cents)' },
max_dollars: { type: 'string', description: 'Max price (dollars)' },
},
},
volume: { type: 'number', description: 'Volume (contracts)' },
volume_fp: { type: 'string', description: 'Volume (fixed-point string)' },
open_interest: { type: 'number', description: 'Open interest (contracts)' },
open_interest_fp: { type: 'string', description: 'Open interest (fixed-point string)' },
},
},
},
}

View File

@@ -73,3 +73,179 @@ export const kalshiGetEventTool: ToolConfig<KalshiGetEventParams, KalshiGetEvent
},
},
}
/**
* V2 Params for Get Event
*/
export interface KalshiGetEventV2Params {
eventTicker: string
withNestedMarkets?: string
}
/**
* V2 Response matching Kalshi API exactly
*/
export interface KalshiGetEventV2Response {
success: boolean
output: {
event: {
event_ticker: string
series_ticker: string
title: string
sub_title: string | null
mutually_exclusive: boolean
category: string
collateral_return_type: string | null
strike_date: string | null
strike_period: string | null
available_on_brokers: boolean | null
product_metadata: Record<string, unknown> | null
markets: Array<{
ticker: string
event_ticker: string
market_type: string
title: string
subtitle: string | null
yes_sub_title: string | null
no_sub_title: string | null
open_time: string
close_time: string
expiration_time: string
status: string
yes_bid: number
yes_ask: number
no_bid: number
no_ask: number
last_price: number
previous_yes_bid: number | null
previous_yes_ask: number | null
previous_price: number | null
volume: number
volume_24h: number
liquidity: number | null
open_interest: number | null
result: string | null
cap_strike: number | null
floor_strike: number | null
}> | null
}
}
}
export const kalshiGetEventV2Tool: ToolConfig<KalshiGetEventV2Params, KalshiGetEventV2Response> = {
id: 'kalshi_get_event_v2',
name: 'Get Event from Kalshi V2',
description: 'Retrieve details of a specific event by ticker (V2 - exact API response)',
version: '2.0.0',
params: {
eventTicker: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The event ticker',
},
withNestedMarkets: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Include nested markets in response (true/false)',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
if (params.withNestedMarkets)
queryParams.append('with_nested_markets', params.withNestedMarkets)
const query = queryParams.toString()
const url = buildKalshiUrl(`/events/${params.eventTicker}`)
return query ? `${url}?${query}` : url
},
method: 'GET',
headers: () => ({
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'get_event_v2')
}
const event = data.event || {}
const markets =
event.markets?.map((m: Record<string, unknown>) => ({
ticker: m.ticker ?? null,
event_ticker: m.event_ticker ?? null,
market_type: m.market_type ?? null,
title: m.title ?? null,
subtitle: m.subtitle ?? null,
yes_sub_title: m.yes_sub_title ?? null,
no_sub_title: m.no_sub_title ?? null,
open_time: m.open_time ?? null,
close_time: m.close_time ?? null,
expiration_time: m.expiration_time ?? null,
status: m.status ?? null,
yes_bid: m.yes_bid ?? 0,
yes_ask: m.yes_ask ?? 0,
no_bid: m.no_bid ?? 0,
no_ask: m.no_ask ?? 0,
last_price: m.last_price ?? 0,
previous_yes_bid: m.previous_yes_bid ?? null,
previous_yes_ask: m.previous_yes_ask ?? null,
previous_price: m.previous_price ?? null,
volume: m.volume ?? 0,
volume_24h: m.volume_24h ?? 0,
liquidity: m.liquidity ?? null,
open_interest: m.open_interest ?? null,
result: m.result ?? null,
cap_strike: m.cap_strike ?? null,
floor_strike: m.floor_strike ?? null,
})) ?? null
return {
success: true,
output: {
event: {
event_ticker: event.event_ticker ?? null,
series_ticker: event.series_ticker ?? null,
title: event.title ?? null,
sub_title: event.sub_title ?? null,
mutually_exclusive: event.mutually_exclusive ?? false,
category: event.category ?? null,
collateral_return_type: event.collateral_return_type ?? null,
strike_date: event.strike_date ?? null,
strike_period: event.strike_period ?? null,
available_on_brokers: event.available_on_brokers ?? null,
product_metadata: event.product_metadata ?? null,
markets,
},
},
}
},
outputs: {
event: {
type: 'object',
description: 'Event object with full details matching Kalshi API response',
properties: {
event_ticker: { type: 'string', description: 'Event ticker' },
series_ticker: { type: 'string', description: 'Series ticker' },
title: { type: 'string', description: 'Event title' },
sub_title: { type: 'string', description: 'Event subtitle' },
mutually_exclusive: { type: 'boolean', description: 'Mutually exclusive markets' },
category: { type: 'string', description: 'Event category' },
collateral_return_type: { type: 'string', description: 'Collateral return type' },
strike_date: { type: 'string', description: 'Strike date' },
strike_period: { type: 'string', description: 'Strike period' },
available_on_brokers: { type: 'boolean', description: 'Available on brokers' },
product_metadata: { type: 'object', description: 'Product metadata' },
markets: { type: 'array', description: 'Nested markets (if requested)' },
},
},
},
}

View File

@@ -106,3 +106,197 @@ export const kalshiGetEventsTool: ToolConfig<KalshiGetEventsParams, KalshiGetEve
},
},
}
/**
* V2 Params for Get Events
*/
export interface KalshiGetEventsV2Params extends KalshiPaginationParams {
status?: string
seriesTicker?: string
withNestedMarkets?: string
withMilestones?: string
minCloseTs?: number
}
/**
* V2 Response matching Kalshi API exactly
*/
export interface KalshiGetEventsV2Response {
success: boolean
output: {
events: Array<{
event_ticker: string
series_ticker: string
title: string
sub_title: string | null
mutually_exclusive: boolean
category: string
collateral_return_type: string | null
strike_date: string | null
strike_period: string | null
available_on_brokers: boolean | null
product_metadata: Record<string, unknown> | null
markets: Array<Record<string, unknown>> | null
}>
milestones: Array<{
event_ticker: string
milestone_type: string
milestone_date: string
milestone_title: string | null
}> | null
cursor: string | null
}
}
export const kalshiGetEventsV2Tool: ToolConfig<KalshiGetEventsV2Params, KalshiGetEventsV2Response> =
{
id: 'kalshi_get_events_v2',
name: 'Get Events from Kalshi V2',
description:
'Retrieve a list of events from Kalshi with optional filtering (V2 - exact API response)',
version: '2.0.0',
params: {
status: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by status (open, closed, settled)',
},
seriesTicker: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by series ticker',
},
withNestedMarkets: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Include nested markets in response (true/false)',
},
withMilestones: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Include milestones in response (true/false)',
},
minCloseTs: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Minimum close timestamp (Unix seconds)',
},
limit: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Number of results (1-200, default: 200)',
},
cursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination cursor for next page',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
if (params.status) queryParams.append('status', params.status)
if (params.seriesTicker) queryParams.append('series_ticker', params.seriesTicker)
if (params.withNestedMarkets)
queryParams.append('with_nested_markets', params.withNestedMarkets)
if (params.withMilestones) queryParams.append('with_milestones', params.withMilestones)
if (params.minCloseTs !== undefined)
queryParams.append('min_close_ts', params.minCloseTs.toString())
if (params.limit) queryParams.append('limit', params.limit)
if (params.cursor) queryParams.append('cursor', params.cursor)
const query = queryParams.toString()
const url = buildKalshiUrl('/events')
return query ? `${url}?${query}` : url
},
method: 'GET',
headers: () => ({
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'get_events_v2')
}
const events = (data.events || []).map((e: Record<string, unknown>) => ({
event_ticker: e.event_ticker ?? null,
series_ticker: e.series_ticker ?? null,
title: e.title ?? null,
sub_title: e.sub_title ?? null,
mutually_exclusive: e.mutually_exclusive ?? false,
category: e.category ?? null,
collateral_return_type: e.collateral_return_type ?? null,
strike_date: e.strike_date ?? null,
strike_period: e.strike_period ?? null,
available_on_brokers: e.available_on_brokers ?? null,
product_metadata: e.product_metadata ?? null,
markets: e.markets ?? null,
}))
const milestones = data.milestones
? (data.milestones as Array<Record<string, unknown>>).map((m) => ({
event_ticker: (m.event_ticker as string) ?? '',
milestone_type: (m.milestone_type as string) ?? '',
milestone_date: (m.milestone_date as string) ?? '',
milestone_title: (m.milestone_title as string | null) ?? null,
}))
: null
return {
success: true,
output: {
events,
milestones,
cursor: data.cursor ?? null,
},
}
},
outputs: {
events: {
type: 'array',
description: 'Array of event objects',
properties: {
event_ticker: { type: 'string', description: 'Event ticker' },
series_ticker: { type: 'string', description: 'Series ticker' },
title: { type: 'string', description: 'Event title' },
sub_title: { type: 'string', description: 'Event subtitle' },
mutually_exclusive: { type: 'boolean', description: 'Mutually exclusive markets' },
category: { type: 'string', description: 'Event category' },
collateral_return_type: { type: 'string', description: 'Collateral return type' },
strike_date: { type: 'string', description: 'Strike date' },
strike_period: { type: 'string', description: 'Strike period' },
available_on_brokers: { type: 'boolean', description: 'Available on brokers' },
product_metadata: { type: 'object', description: 'Product metadata' },
markets: { type: 'array', description: 'Nested markets (if requested)' },
},
},
milestones: {
type: 'array',
description: 'Array of milestone objects (if requested)',
properties: {
event_ticker: { type: 'string', description: 'Event ticker' },
milestone_type: { type: 'string', description: 'Milestone type' },
milestone_date: { type: 'string', description: 'Milestone date' },
milestone_title: { type: 'string', description: 'Milestone title' },
},
},
cursor: {
type: 'string',
description: 'Pagination cursor for fetching more results',
},
},
}

View File

@@ -59,3 +59,74 @@ export const kalshiGetExchangeStatusTool: ToolConfig<
},
},
}
/**
* V2 Params for Get Exchange Status
*/
export type KalshiGetExchangeStatusV2Params = Record<string, never>
/**
* V2 Response matching Kalshi API exactly
*/
export interface KalshiGetExchangeStatusV2Response {
success: boolean
output: {
exchange_active: boolean
trading_active: boolean
exchange_estimated_resume_time: string | null
}
}
export const kalshiGetExchangeStatusV2Tool: ToolConfig<
KalshiGetExchangeStatusV2Params,
KalshiGetExchangeStatusV2Response
> = {
id: 'kalshi_get_exchange_status_v2',
name: 'Get Exchange Status from Kalshi V2',
description: 'Retrieve the current status of the Kalshi exchange (V2 - exact API response)',
version: '2.0.0',
params: {},
request: {
url: () => {
return buildKalshiUrl('/exchange/status')
},
method: 'GET',
headers: () => ({
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'get_exchange_status_v2')
}
return {
success: true,
output: {
exchange_active: data.exchange_active ?? false,
trading_active: data.trading_active ?? false,
exchange_estimated_resume_time: data.exchange_estimated_resume_time ?? null,
},
}
},
outputs: {
exchange_active: {
type: 'boolean',
description: 'Whether the exchange is active',
},
trading_active: {
type: 'boolean',
description: 'Whether trading is active',
},
exchange_estimated_resume_time: {
type: 'string',
description: 'Estimated time when exchange will resume (if inactive)',
},
},
}

View File

@@ -131,3 +131,198 @@ export const kalshiGetFillsTool: ToolConfig<KalshiGetFillsParams, KalshiGetFills
},
},
}
/**
* V2 Params for Get Fills - fixes limit max to 200, adds subaccount
*/
export interface KalshiGetFillsV2Params extends KalshiAuthParams, KalshiPaginationParams {
ticker?: string
orderId?: string
minTs?: number
maxTs?: number
subaccount?: string
}
/**
* V2 Response matching Kalshi API exactly
*/
export interface KalshiGetFillsV2Response {
success: boolean
output: {
fills: Array<{
fill_id: string
trade_id: string
order_id: string
client_order_id: string | null
ticker: string
market_ticker: string
side: string
action: string
count: number
count_fp: string | null
price: number | null
yes_price: number
no_price: number
yes_price_fixed: string | null
no_price_fixed: string | null
is_taker: boolean
created_time: string | null
ts: number | null
}>
cursor: string | null
}
}
export const kalshiGetFillsV2Tool: ToolConfig<KalshiGetFillsV2Params, KalshiGetFillsV2Response> = {
id: 'kalshi_get_fills_v2',
name: 'Get Fills from Kalshi V2',
description: "Retrieve your portfolio's fills/trades from Kalshi (V2 - exact API response)",
version: '2.0.0',
params: {
keyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your Kalshi API Key ID',
},
privateKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your RSA Private Key (PEM format)',
},
ticker: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by market ticker',
},
orderId: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by order ID',
},
minTs: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Minimum timestamp (Unix milliseconds)',
},
maxTs: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum timestamp (Unix milliseconds)',
},
subaccount: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Subaccount to get fills for',
},
limit: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Number of results (1-200, default: 100)',
},
cursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination cursor for next page',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
if (params.ticker) queryParams.append('ticker', params.ticker)
if (params.orderId) queryParams.append('order_id', params.orderId)
if (params.minTs !== undefined) queryParams.append('min_ts', params.minTs.toString())
if (params.maxTs !== undefined) queryParams.append('max_ts', params.maxTs.toString())
if (params.subaccount) queryParams.append('subaccount', params.subaccount)
if (params.limit) queryParams.append('limit', params.limit)
if (params.cursor) queryParams.append('cursor', params.cursor)
const query = queryParams.toString()
const url = buildKalshiUrl('/portfolio/fills')
return query ? `${url}?${query}` : url
},
method: 'GET',
headers: (params) => {
const path = '/trade-api/v2/portfolio/fills'
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'GET', path)
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'get_fills_v2')
}
const fills = (data.fills || []).map((f: Record<string, unknown>) => ({
fill_id: f.fill_id ?? null,
trade_id: f.trade_id ?? null,
order_id: f.order_id ?? null,
client_order_id: f.client_order_id ?? null,
ticker: f.ticker ?? null,
market_ticker: f.market_ticker ?? null,
side: f.side ?? null,
action: f.action ?? null,
count: f.count ?? 0,
count_fp: f.count_fp ?? null,
price: f.price ?? null,
yes_price: f.yes_price ?? 0,
no_price: f.no_price ?? 0,
yes_price_fixed: f.yes_price_fixed ?? null,
no_price_fixed: f.no_price_fixed ?? null,
is_taker: f.is_taker ?? false,
created_time: f.created_time ?? null,
ts: f.ts ?? null,
}))
return {
success: true,
output: {
fills,
cursor: data.cursor ?? null,
},
}
},
outputs: {
fills: {
type: 'array',
description: 'Array of fill/trade objects with all API fields',
properties: {
fill_id: { type: 'string', description: 'Fill ID' },
trade_id: { type: 'string', description: 'Trade ID (same as fill_id)' },
order_id: { type: 'string', description: 'Order ID' },
client_order_id: { type: 'string', description: 'Client order ID' },
ticker: { type: 'string', description: 'Market ticker' },
market_ticker: { type: 'string', description: 'Market ticker (legacy)' },
side: { type: 'string', description: 'Side (yes/no)' },
action: { type: 'string', description: 'Action (buy/sell)' },
count: { type: 'number', description: 'Number of contracts' },
count_fp: { type: 'string', description: 'Count (fixed-point)' },
price: { type: 'number', description: 'Price (deprecated)' },
yes_price: { type: 'number', description: 'Yes price in cents' },
no_price: { type: 'number', description: 'No price in cents' },
yes_price_fixed: { type: 'string', description: 'Yes price in dollars' },
no_price_fixed: { type: 'string', description: 'No price in dollars' },
is_taker: { type: 'boolean', description: 'Whether fill was taker' },
created_time: { type: 'string', description: 'Fill creation time' },
ts: { type: 'number', description: 'Unix timestamp (milliseconds)' },
},
},
cursor: {
type: 'string',
description: 'Pagination cursor for fetching more results',
},
},
}

View File

@@ -58,3 +58,219 @@ export const kalshiGetMarketTool: ToolConfig<KalshiGetMarketParams, KalshiGetMar
},
},
}
/**
* V2 Get Market Tool - Returns exact Kalshi API response structure
*/
export interface KalshiGetMarketV2Response {
success: boolean
output: {
market: {
ticker: string
event_ticker: string
market_type: string
title: string
subtitle: string | null
yes_sub_title: string | null
no_sub_title: string | null
open_time: string | null
close_time: string | null
expected_expiration_time: string | null
expiration_time: string | null
latest_expiration_time: string | null
settlement_timer_seconds: number | null
status: string
response_price_units: string | null
notional_value: number | null
tick_size: number | null
yes_bid: number | null
yes_ask: number | null
no_bid: number | null
no_ask: number | null
last_price: number | null
previous_yes_bid: number | null
previous_yes_ask: number | null
previous_price: number | null
volume: number | null
volume_24h: number | null
liquidity: number | null
open_interest: number | null
result: string | null
cap_strike: number | null
floor_strike: number | null
can_close_early: boolean | null
expiration_value: string | null
category: string | null
risk_limit_cents: number | null
strike_type: string | null
rules_primary: string | null
rules_secondary: string | null
settlement_source_url: string | null
custom_strike: object | null
underlying: string | null
settlement_value: number | null
cfd_contract_size: number | null
yes_fee_fp: number | null
no_fee_fp: number | null
last_price_fp: number | null
yes_bid_fp: number | null
yes_ask_fp: number | null
no_bid_fp: number | null
no_ask_fp: number | null
}
}
}
export const kalshiGetMarketV2Tool: ToolConfig<KalshiGetMarketParams, KalshiGetMarketV2Response> = {
id: 'kalshi_get_market_v2',
name: 'Get Market from Kalshi V2',
description:
'Retrieve details of a specific prediction market by ticker (V2 - full API response)',
version: '2.0.0',
params: {
ticker: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The market ticker (e.g., "KXBTC-24DEC31")',
},
},
request: {
url: (params) => buildKalshiUrl(`/markets/${params.ticker}`),
method: 'GET',
headers: () => ({
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'get_market_v2')
}
const m = data.market || {}
return {
success: true,
output: {
market: {
ticker: m.ticker ?? null,
event_ticker: m.event_ticker ?? null,
market_type: m.market_type ?? null,
title: m.title ?? null,
subtitle: m.subtitle ?? null,
yes_sub_title: m.yes_sub_title ?? null,
no_sub_title: m.no_sub_title ?? null,
open_time: m.open_time ?? null,
close_time: m.close_time ?? null,
expected_expiration_time: m.expected_expiration_time ?? null,
expiration_time: m.expiration_time ?? null,
latest_expiration_time: m.latest_expiration_time ?? null,
settlement_timer_seconds: m.settlement_timer_seconds ?? null,
status: m.status ?? null,
response_price_units: m.response_price_units ?? null,
notional_value: m.notional_value ?? null,
tick_size: m.tick_size ?? null,
yes_bid: m.yes_bid ?? null,
yes_ask: m.yes_ask ?? null,
no_bid: m.no_bid ?? null,
no_ask: m.no_ask ?? null,
last_price: m.last_price ?? null,
previous_yes_bid: m.previous_yes_bid ?? null,
previous_yes_ask: m.previous_yes_ask ?? null,
previous_price: m.previous_price ?? null,
volume: m.volume ?? null,
volume_24h: m.volume_24h ?? null,
liquidity: m.liquidity ?? null,
open_interest: m.open_interest ?? null,
result: m.result ?? null,
cap_strike: m.cap_strike ?? null,
floor_strike: m.floor_strike ?? null,
can_close_early: m.can_close_early ?? null,
expiration_value: m.expiration_value ?? null,
category: m.category ?? null,
risk_limit_cents: m.risk_limit_cents ?? null,
strike_type: m.strike_type ?? null,
rules_primary: m.rules_primary ?? null,
rules_secondary: m.rules_secondary ?? null,
settlement_source_url: m.settlement_source_url ?? null,
custom_strike: m.custom_strike ?? null,
underlying: m.underlying ?? null,
settlement_value: m.settlement_value ?? null,
cfd_contract_size: m.cfd_contract_size ?? null,
yes_fee_fp: m.yes_fee_fp ?? null,
no_fee_fp: m.no_fee_fp ?? null,
last_price_fp: m.last_price_fp ?? null,
yes_bid_fp: m.yes_bid_fp ?? null,
yes_ask_fp: m.yes_ask_fp ?? null,
no_bid_fp: m.no_bid_fp ?? null,
no_ask_fp: m.no_ask_fp ?? null,
},
},
}
},
outputs: {
market: {
type: 'object',
description: 'Market object with all API fields',
properties: {
ticker: { type: 'string', description: 'Market ticker' },
event_ticker: { type: 'string', description: 'Event ticker' },
market_type: { type: 'string', description: 'Market type' },
title: { type: 'string', description: 'Market title' },
subtitle: { type: 'string', description: 'Market subtitle' },
yes_sub_title: { type: 'string', description: 'Yes outcome subtitle' },
no_sub_title: { type: 'string', description: 'No outcome subtitle' },
open_time: { type: 'string', description: 'Market open time' },
close_time: { type: 'string', description: 'Market close time' },
expected_expiration_time: { type: 'string', description: 'Expected expiration time' },
expiration_time: { type: 'string', description: 'Expiration time' },
latest_expiration_time: { type: 'string', description: 'Latest expiration time' },
settlement_timer_seconds: { type: 'number', description: 'Settlement timer in seconds' },
status: { type: 'string', description: 'Market status' },
response_price_units: { type: 'string', description: 'Response price units' },
notional_value: { type: 'number', description: 'Notional value' },
tick_size: { type: 'number', description: 'Tick size' },
yes_bid: { type: 'number', description: 'Current yes bid price' },
yes_ask: { type: 'number', description: 'Current yes ask price' },
no_bid: { type: 'number', description: 'Current no bid price' },
no_ask: { type: 'number', description: 'Current no ask price' },
last_price: { type: 'number', description: 'Last trade price' },
previous_yes_bid: { type: 'number', description: 'Previous yes bid' },
previous_yes_ask: { type: 'number', description: 'Previous yes ask' },
previous_price: { type: 'number', description: 'Previous price' },
volume: { type: 'number', description: 'Total volume' },
volume_24h: { type: 'number', description: '24-hour volume' },
liquidity: { type: 'number', description: 'Market liquidity' },
open_interest: { type: 'number', description: 'Open interest' },
result: { type: 'string', description: 'Market result' },
cap_strike: { type: 'number', description: 'Cap strike' },
floor_strike: { type: 'number', description: 'Floor strike' },
can_close_early: { type: 'boolean', description: 'Can close early' },
expiration_value: { type: 'string', description: 'Expiration value' },
category: { type: 'string', description: 'Market category' },
risk_limit_cents: { type: 'number', description: 'Risk limit in cents' },
strike_type: { type: 'string', description: 'Strike type' },
rules_primary: { type: 'string', description: 'Primary rules' },
rules_secondary: { type: 'string', description: 'Secondary rules' },
settlement_source_url: { type: 'string', description: 'Settlement source URL' },
custom_strike: { type: 'object', description: 'Custom strike object' },
underlying: { type: 'string', description: 'Underlying asset' },
settlement_value: { type: 'number', description: 'Settlement value' },
cfd_contract_size: { type: 'number', description: 'CFD contract size' },
yes_fee_fp: { type: 'number', description: 'Yes fee (fixed-point)' },
no_fee_fp: { type: 'number', description: 'No fee (fixed-point)' },
last_price_fp: { type: 'number', description: 'Last price (fixed-point)' },
yes_bid_fp: { type: 'number', description: 'Yes bid (fixed-point)' },
yes_ask_fp: { type: 'number', description: 'Yes ask (fixed-point)' },
no_bid_fp: { type: 'number', description: 'No bid (fixed-point)' },
no_ask_fp: { type: 'number', description: 'No ask (fixed-point)' },
},
},
},
}

View File

@@ -105,3 +105,341 @@ export const kalshiGetMarketsTool: ToolConfig<KalshiGetMarketsParams, KalshiGetM
},
},
}
/**
* V2 Get Markets Tool - Returns exact Kalshi API response structure with all params
*/
export interface KalshiGetMarketsV2Params extends KalshiPaginationParams {
status?: string // unopened, open, closed, settled
seriesTicker?: string
eventTicker?: string
minCreatedTs?: number
maxCreatedTs?: number
minUpdatedTs?: number
minCloseTs?: number
maxCloseTs?: number
minSettledTs?: number
maxSettledTs?: number
tickers?: string // comma-separated list
mveFilter?: string // display or all
}
export interface KalshiGetMarketsV2Response {
success: boolean
output: {
markets: Array<{
ticker: string
event_ticker: string
market_type: string
title: string
subtitle: string | null
yes_sub_title: string | null
no_sub_title: string | null
open_time: string | null
close_time: string | null
expected_expiration_time: string | null
expiration_time: string | null
latest_expiration_time: string | null
settlement_timer_seconds: number | null
status: string
response_price_units: string | null
notional_value: number | null
tick_size: number | null
yes_bid: number | null
yes_ask: number | null
no_bid: number | null
no_ask: number | null
last_price: number | null
previous_yes_bid: number | null
previous_yes_ask: number | null
previous_price: number | null
volume: number | null
volume_24h: number | null
liquidity: number | null
open_interest: number | null
result: string | null
cap_strike: number | null
floor_strike: number | null
can_close_early: boolean | null
expiration_value: string | null
category: string | null
risk_limit_cents: number | null
strike_type: string | null
rules_primary: string | null
rules_secondary: string | null
settlement_source_url: string | null
custom_strike: object | null
underlying: string | null
settlement_value: number | null
cfd_contract_size: number | null
yes_fee_fp: number | null
no_fee_fp: number | null
last_price_fp: number | null
yes_bid_fp: number | null
yes_ask_fp: number | null
no_bid_fp: number | null
no_ask_fp: number | null
}>
cursor: string | null
}
}
export const kalshiGetMarketsV2Tool: ToolConfig<
KalshiGetMarketsV2Params,
KalshiGetMarketsV2Response
> = {
id: 'kalshi_get_markets_v2',
name: 'Get Markets from Kalshi V2',
description:
'Retrieve a list of prediction markets from Kalshi with all filtering options (V2 - full API response)',
version: '2.0.0',
params: {
status: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by status (unopened, open, closed, settled)',
},
seriesTicker: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by series ticker',
},
eventTicker: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by event ticker',
},
minCreatedTs: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Minimum created timestamp (Unix seconds)',
},
maxCreatedTs: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum created timestamp (Unix seconds)',
},
minUpdatedTs: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Minimum updated timestamp (Unix seconds)',
},
minCloseTs: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Minimum close timestamp (Unix seconds)',
},
maxCloseTs: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum close timestamp (Unix seconds)',
},
minSettledTs: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Minimum settled timestamp (Unix seconds)',
},
maxSettledTs: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum settled timestamp (Unix seconds)',
},
tickers: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated list of tickers to filter',
},
mveFilter: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'MVE filter (display or all)',
},
limit: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Number of results (1-1000, default: 100)',
},
cursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination cursor for next page',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
if (params.status) queryParams.append('status', params.status)
if (params.seriesTicker) queryParams.append('series_ticker', params.seriesTicker)
if (params.eventTicker) queryParams.append('event_ticker', params.eventTicker)
if (params.minCreatedTs) queryParams.append('min_created_ts', params.minCreatedTs.toString())
if (params.maxCreatedTs) queryParams.append('max_created_ts', params.maxCreatedTs.toString())
if (params.minUpdatedTs) queryParams.append('min_updated_ts', params.minUpdatedTs.toString())
if (params.minCloseTs) queryParams.append('min_close_ts', params.minCloseTs.toString())
if (params.maxCloseTs) queryParams.append('max_close_ts', params.maxCloseTs.toString())
if (params.minSettledTs) queryParams.append('min_settled_ts', params.minSettledTs.toString())
if (params.maxSettledTs) queryParams.append('max_settled_ts', params.maxSettledTs.toString())
if (params.tickers) queryParams.append('tickers', params.tickers)
if (params.mveFilter) queryParams.append('mve_filter', params.mveFilter)
if (params.limit) queryParams.append('limit', params.limit)
if (params.cursor) queryParams.append('cursor', params.cursor)
const query = queryParams.toString()
const url = buildKalshiUrl('/markets')
return query ? `${url}?${query}` : url
},
method: 'GET',
headers: () => ({
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'get_markets_v2')
}
const markets = (data.markets || []).map((m: Record<string, unknown>) => ({
ticker: m.ticker ?? null,
event_ticker: m.event_ticker ?? null,
market_type: m.market_type ?? null,
title: m.title ?? null,
subtitle: m.subtitle ?? null,
yes_sub_title: m.yes_sub_title ?? null,
no_sub_title: m.no_sub_title ?? null,
open_time: m.open_time ?? null,
close_time: m.close_time ?? null,
expected_expiration_time: m.expected_expiration_time ?? null,
expiration_time: m.expiration_time ?? null,
latest_expiration_time: m.latest_expiration_time ?? null,
settlement_timer_seconds: m.settlement_timer_seconds ?? null,
status: m.status ?? null,
response_price_units: m.response_price_units ?? null,
notional_value: m.notional_value ?? null,
tick_size: m.tick_size ?? null,
yes_bid: m.yes_bid ?? null,
yes_ask: m.yes_ask ?? null,
no_bid: m.no_bid ?? null,
no_ask: m.no_ask ?? null,
last_price: m.last_price ?? null,
previous_yes_bid: m.previous_yes_bid ?? null,
previous_yes_ask: m.previous_yes_ask ?? null,
previous_price: m.previous_price ?? null,
volume: m.volume ?? null,
volume_24h: m.volume_24h ?? null,
liquidity: m.liquidity ?? null,
open_interest: m.open_interest ?? null,
result: m.result ?? null,
cap_strike: m.cap_strike ?? null,
floor_strike: m.floor_strike ?? null,
can_close_early: m.can_close_early ?? null,
expiration_value: m.expiration_value ?? null,
category: m.category ?? null,
risk_limit_cents: m.risk_limit_cents ?? null,
strike_type: m.strike_type ?? null,
rules_primary: m.rules_primary ?? null,
rules_secondary: m.rules_secondary ?? null,
settlement_source_url: m.settlement_source_url ?? null,
custom_strike: m.custom_strike ?? null,
underlying: m.underlying ?? null,
settlement_value: m.settlement_value ?? null,
cfd_contract_size: m.cfd_contract_size ?? null,
yes_fee_fp: m.yes_fee_fp ?? null,
no_fee_fp: m.no_fee_fp ?? null,
last_price_fp: m.last_price_fp ?? null,
yes_bid_fp: m.yes_bid_fp ?? null,
yes_ask_fp: m.yes_ask_fp ?? null,
no_bid_fp: m.no_bid_fp ?? null,
no_ask_fp: m.no_ask_fp ?? null,
}))
return {
success: true,
output: {
markets,
cursor: data.cursor ?? null,
},
}
},
outputs: {
markets: {
type: 'array',
description: 'Array of market objects with all API fields',
properties: {
ticker: { type: 'string', description: 'Market ticker' },
event_ticker: { type: 'string', description: 'Event ticker' },
market_type: { type: 'string', description: 'Market type' },
title: { type: 'string', description: 'Market title' },
subtitle: { type: 'string', description: 'Market subtitle' },
yes_sub_title: { type: 'string', description: 'Yes outcome subtitle' },
no_sub_title: { type: 'string', description: 'No outcome subtitle' },
open_time: { type: 'string', description: 'Market open time' },
close_time: { type: 'string', description: 'Market close time' },
expected_expiration_time: { type: 'string', description: 'Expected expiration time' },
expiration_time: { type: 'string', description: 'Expiration time' },
latest_expiration_time: { type: 'string', description: 'Latest expiration time' },
settlement_timer_seconds: { type: 'number', description: 'Settlement timer in seconds' },
status: { type: 'string', description: 'Market status' },
response_price_units: { type: 'string', description: 'Response price units' },
notional_value: { type: 'number', description: 'Notional value' },
tick_size: { type: 'number', description: 'Tick size' },
yes_bid: { type: 'number', description: 'Current yes bid price' },
yes_ask: { type: 'number', description: 'Current yes ask price' },
no_bid: { type: 'number', description: 'Current no bid price' },
no_ask: { type: 'number', description: 'Current no ask price' },
last_price: { type: 'number', description: 'Last trade price' },
previous_yes_bid: { type: 'number', description: 'Previous yes bid' },
previous_yes_ask: { type: 'number', description: 'Previous yes ask' },
previous_price: { type: 'number', description: 'Previous price' },
volume: { type: 'number', description: 'Total volume' },
volume_24h: { type: 'number', description: '24-hour volume' },
liquidity: { type: 'number', description: 'Market liquidity' },
open_interest: { type: 'number', description: 'Open interest' },
result: { type: 'string', description: 'Market result' },
cap_strike: { type: 'number', description: 'Cap strike' },
floor_strike: { type: 'number', description: 'Floor strike' },
can_close_early: { type: 'boolean', description: 'Can close early' },
expiration_value: { type: 'string', description: 'Expiration value' },
category: { type: 'string', description: 'Market category' },
risk_limit_cents: { type: 'number', description: 'Risk limit in cents' },
strike_type: { type: 'string', description: 'Strike type' },
rules_primary: { type: 'string', description: 'Primary rules' },
rules_secondary: { type: 'string', description: 'Secondary rules' },
settlement_source_url: { type: 'string', description: 'Settlement source URL' },
custom_strike: { type: 'object', description: 'Custom strike object' },
underlying: { type: 'string', description: 'Underlying asset' },
settlement_value: { type: 'number', description: 'Settlement value' },
cfd_contract_size: { type: 'number', description: 'CFD contract size' },
yes_fee_fp: { type: 'number', description: 'Yes fee (fixed-point)' },
no_fee_fp: { type: 'number', description: 'No fee (fixed-point)' },
last_price_fp: { type: 'number', description: 'Last price (fixed-point)' },
yes_bid_fp: { type: 'number', description: 'Yes bid (fixed-point)' },
yes_ask_fp: { type: 'number', description: 'Yes ask (fixed-point)' },
no_bid_fp: { type: 'number', description: 'No bid (fixed-point)' },
no_ask_fp: { type: 'number', description: 'No ask (fixed-point)' },
},
},
cursor: {
type: 'string',
description: 'Pagination cursor for fetching more results',
},
},
}

View File

@@ -71,3 +71,178 @@ export const kalshiGetOrderTool: ToolConfig<KalshiGetOrderParams, KalshiGetOrder
},
},
}
export interface KalshiGetOrderV2Params extends KalshiAuthParams {
orderId: string // Order ID to retrieve (required)
}
export interface KalshiGetOrderV2Response {
success: boolean
output: {
order: {
order_id: string
user_id: string | null
client_order_id: string | null
ticker: string
side: string
action: string
type: string
status: string
yes_price: number | null
no_price: number | null
yes_price_dollars: string | null
no_price_dollars: string | null
fill_count: number | null
fill_count_fp: string | null
remaining_count: number | null
remaining_count_fp: string | null
initial_count: number | null
initial_count_fp: string | null
taker_fees: number | null
maker_fees: number | null
taker_fees_dollars: string | null
maker_fees_dollars: string | null
taker_fill_cost: number | null
maker_fill_cost: number | null
taker_fill_cost_dollars: string | null
maker_fill_cost_dollars: string | null
queue_position: number | null
expiration_time: string | null
created_time: string | null
last_update_time: string | null
self_trade_prevention_type: string | null
order_group_id: string | null
cancel_order_on_pause: boolean | null
}
}
}
export const kalshiGetOrderV2Tool: ToolConfig<KalshiGetOrderV2Params, KalshiGetOrderV2Response> = {
id: 'kalshi_get_order_v2',
name: 'Get Order from Kalshi V2',
description: 'Retrieve details of a specific order by ID from Kalshi (V2 with full API response)',
version: '2.0.0',
params: {
keyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your Kalshi API Key ID',
},
privateKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your RSA Private Key (PEM format)',
},
orderId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The order ID to retrieve',
},
},
request: {
url: (params) => buildKalshiUrl(`/portfolio/orders/${params.orderId}`),
method: 'GET',
headers: (params) => {
const path = `/trade-api/v2/portfolio/orders/${params.orderId}`
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'GET', path)
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'get_order_v2')
}
const order = data.order || {}
return {
success: true,
output: {
order: {
order_id: order.order_id ?? null,
user_id: order.user_id ?? null,
client_order_id: order.client_order_id ?? null,
ticker: order.ticker ?? null,
side: order.side ?? null,
action: order.action ?? null,
type: order.type ?? null,
status: order.status ?? null,
yes_price: order.yes_price ?? null,
no_price: order.no_price ?? null,
yes_price_dollars: order.yes_price_dollars ?? null,
no_price_dollars: order.no_price_dollars ?? null,
fill_count: order.fill_count ?? null,
fill_count_fp: order.fill_count_fp ?? null,
remaining_count: order.remaining_count ?? null,
remaining_count_fp: order.remaining_count_fp ?? null,
initial_count: order.initial_count ?? null,
initial_count_fp: order.initial_count_fp ?? null,
taker_fees: order.taker_fees ?? null,
maker_fees: order.maker_fees ?? null,
taker_fees_dollars: order.taker_fees_dollars ?? null,
maker_fees_dollars: order.maker_fees_dollars ?? null,
taker_fill_cost: order.taker_fill_cost ?? null,
maker_fill_cost: order.maker_fill_cost ?? null,
taker_fill_cost_dollars: order.taker_fill_cost_dollars ?? null,
maker_fill_cost_dollars: order.maker_fill_cost_dollars ?? null,
queue_position: order.queue_position ?? null,
expiration_time: order.expiration_time ?? null,
created_time: order.created_time ?? null,
last_update_time: order.last_update_time ?? null,
self_trade_prevention_type: order.self_trade_prevention_type ?? null,
order_group_id: order.order_group_id ?? null,
cancel_order_on_pause: order.cancel_order_on_pause ?? null,
},
},
}
},
outputs: {
order: {
type: 'object',
description: 'Order object with full API response fields',
properties: {
order_id: { type: 'string', description: 'Order ID' },
user_id: { type: 'string', description: 'User ID' },
client_order_id: { type: 'string', description: 'Client order ID' },
ticker: { type: 'string', description: 'Market ticker' },
side: { type: 'string', description: 'Order side (yes/no)' },
action: { type: 'string', description: 'Action (buy/sell)' },
type: { type: 'string', description: 'Order type (limit/market)' },
status: { type: 'string', description: 'Order status (resting/canceled/executed)' },
yes_price: { type: 'number', description: 'Yes price in cents' },
no_price: { type: 'number', description: 'No price in cents' },
yes_price_dollars: { type: 'string', description: 'Yes price in dollars' },
no_price_dollars: { type: 'string', description: 'No price in dollars' },
fill_count: { type: 'number', description: 'Filled contract count' },
fill_count_fp: { type: 'string', description: 'Filled count (fixed-point)' },
remaining_count: { type: 'number', description: 'Remaining contracts' },
remaining_count_fp: { type: 'string', description: 'Remaining count (fixed-point)' },
initial_count: { type: 'number', description: 'Initial contract count' },
initial_count_fp: { type: 'string', description: 'Initial count (fixed-point)' },
taker_fees: { type: 'number', description: 'Taker fees in cents' },
maker_fees: { type: 'number', description: 'Maker fees in cents' },
taker_fees_dollars: { type: 'string', description: 'Taker fees in dollars' },
maker_fees_dollars: { type: 'string', description: 'Maker fees in dollars' },
taker_fill_cost: { type: 'number', description: 'Taker fill cost in cents' },
maker_fill_cost: { type: 'number', description: 'Maker fill cost in cents' },
taker_fill_cost_dollars: { type: 'string', description: 'Taker fill cost in dollars' },
maker_fill_cost_dollars: { type: 'string', description: 'Maker fill cost in dollars' },
queue_position: { type: 'number', description: 'Queue position (deprecated)' },
expiration_time: { type: 'string', description: 'Order expiration time' },
created_time: { type: 'string', description: 'Order creation time' },
last_update_time: { type: 'string', description: 'Last update time' },
self_trade_prevention_type: { type: 'string', description: 'Self-trade prevention type' },
order_group_id: { type: 'string', description: 'Order group ID' },
cancel_order_on_pause: { type: 'boolean', description: 'Cancel on market pause' },
},
},
},
}

View File

@@ -63,3 +63,135 @@ export const kalshiGetOrderbookTool: ToolConfig<
},
},
}
/**
* V2 Get Orderbook Tool - Returns exact Kalshi API response structure with depth param
* API returns tuple arrays: [price, count] for orderbook, [dollars_string, count] for _dollars variants
*/
export interface KalshiGetOrderbookV2Params {
ticker: string
depth?: number // Number of price levels to return
}
export interface KalshiGetOrderbookV2Response {
success: boolean
output: {
orderbook: {
yes: Array<[number, number]> // [price_in_cents, count]
no: Array<[number, number]> // [price_in_cents, count]
yes_dollars: Array<[string, number]> // [dollars_string, count]
no_dollars: Array<[string, number]> // [dollars_string, count]
}
orderbook_fp: {
yes_dollars: Array<[string, string]> // [dollars_string, fp_count_string]
no_dollars: Array<[string, string]> // [dollars_string, fp_count_string]
}
}
}
export const kalshiGetOrderbookV2Tool: ToolConfig<
KalshiGetOrderbookV2Params,
KalshiGetOrderbookV2Response
> = {
id: 'kalshi_get_orderbook_v2',
name: 'Get Market Orderbook from Kalshi V2',
description:
'Retrieve the orderbook (yes and no bids) for a specific market (V2 - includes depth and fp fields)',
version: '2.0.0',
params: {
ticker: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Market ticker (e.g., KXBTC-24DEC31)',
},
depth: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Number of price levels to return (default: all)',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
if (params.depth) queryParams.append('depth', params.depth.toString())
const query = queryParams.toString()
const url = buildKalshiUrl(`/markets/${params.ticker}/orderbook`)
return query ? `${url}?${query}` : url
},
method: 'GET',
headers: () => ({
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'get_orderbook_v2')
}
const orderbook = data.orderbook || {}
const orderbookFp = data.orderbook_fp || {}
return {
success: true,
output: {
orderbook: {
yes: orderbook.yes ?? [],
no: orderbook.no ?? [],
yes_dollars: orderbook.yes_dollars ?? [],
no_dollars: orderbook.no_dollars ?? [],
},
orderbook_fp: {
yes_dollars: orderbookFp.yes_dollars ?? [],
no_dollars: orderbookFp.no_dollars ?? [],
},
},
}
},
outputs: {
orderbook: {
type: 'object',
description: 'Orderbook with yes/no bids (legacy integer counts)',
properties: {
yes: {
type: 'array',
description: 'Yes side bids as tuples [price_cents, count]',
},
no: {
type: 'array',
description: 'No side bids as tuples [price_cents, count]',
},
yes_dollars: {
type: 'array',
description: 'Yes side bids as tuples [dollars_string, count]',
},
no_dollars: {
type: 'array',
description: 'No side bids as tuples [dollars_string, count]',
},
},
},
orderbook_fp: {
type: 'object',
description: 'Orderbook with fixed-point counts (preferred)',
properties: {
yes_dollars: {
type: 'array',
description: 'Yes side bids as tuples [dollars_string, fp_count_string]',
},
no_dollars: {
type: 'array',
description: 'No side bids as tuples [dollars_string, fp_count_string]',
},
},
},
},
}

View File

@@ -123,3 +123,250 @@ export const kalshiGetOrdersTool: ToolConfig<KalshiGetOrdersParams, KalshiGetOrd
},
},
}
export interface KalshiGetOrdersV2Params extends KalshiAuthParams, KalshiPaginationParams {
ticker?: string
eventTicker?: string
status?: string // resting, canceled, executed
minTs?: string // Minimum timestamp filter (Unix timestamp)
maxTs?: string // Maximum timestamp filter (Unix timestamp)
subaccount?: string // Subaccount to filter orders
}
export interface KalshiOrderV2 {
order_id: string
user_id: string | null
client_order_id: string | null
ticker: string
side: string
action: string
type: string
status: string
yes_price: number | null
no_price: number | null
yes_price_dollars: string | null
no_price_dollars: string | null
fill_count: number | null
fill_count_fp: string | null
remaining_count: number | null
remaining_count_fp: string | null
initial_count: number | null
initial_count_fp: string | null
taker_fees: number | null
maker_fees: number | null
taker_fees_dollars: string | null
maker_fees_dollars: string | null
taker_fill_cost: number | null
maker_fill_cost: number | null
taker_fill_cost_dollars: string | null
maker_fill_cost_dollars: string | null
queue_position: number | null
expiration_time: string | null
created_time: string | null
last_update_time: string | null
self_trade_prevention_type: string | null
order_group_id: string | null
cancel_order_on_pause: boolean | null
}
export interface KalshiGetOrdersV2Response {
success: boolean
output: {
orders: KalshiOrderV2[]
cursor: string | null
}
}
export const kalshiGetOrdersV2Tool: ToolConfig<KalshiGetOrdersV2Params, KalshiGetOrdersV2Response> =
{
id: 'kalshi_get_orders_v2',
name: 'Get Orders from Kalshi V2',
description:
'Retrieve your orders from Kalshi with optional filtering (V2 with full API response)',
version: '2.0.0',
params: {
keyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your Kalshi API Key ID',
},
privateKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your RSA Private Key (PEM format)',
},
ticker: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by market ticker',
},
eventTicker: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by event ticker (max 10 comma-separated)',
},
status: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by status (resting, canceled, executed)',
},
minTs: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Minimum timestamp filter (Unix timestamp)',
},
maxTs: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Maximum timestamp filter (Unix timestamp)',
},
subaccount: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Subaccount to filter orders',
},
limit: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Number of results (1-200, default: 100)',
},
cursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination cursor for next page',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
if (params.ticker) queryParams.append('ticker', params.ticker)
if (params.eventTicker) queryParams.append('event_ticker', params.eventTicker)
if (params.status) queryParams.append('status', params.status)
if (params.minTs) queryParams.append('min_ts', params.minTs)
if (params.maxTs) queryParams.append('max_ts', params.maxTs)
if (params.subaccount) queryParams.append('subaccount', params.subaccount)
if (params.limit) queryParams.append('limit', params.limit)
if (params.cursor) queryParams.append('cursor', params.cursor)
const query = queryParams.toString()
const url = buildKalshiUrl('/portfolio/orders')
return query ? `${url}?${query}` : url
},
method: 'GET',
headers: (params) => {
const path = '/trade-api/v2/portfolio/orders'
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'GET', path)
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'get_orders_v2')
}
const rawOrders = data.orders || []
const orders: KalshiOrderV2[] = rawOrders.map((order: any) => ({
order_id: order.order_id ?? null,
user_id: order.user_id ?? null,
client_order_id: order.client_order_id ?? null,
ticker: order.ticker ?? null,
side: order.side ?? null,
action: order.action ?? null,
type: order.type ?? null,
status: order.status ?? null,
yes_price: order.yes_price ?? null,
no_price: order.no_price ?? null,
yes_price_dollars: order.yes_price_dollars ?? null,
no_price_dollars: order.no_price_dollars ?? null,
fill_count: order.fill_count ?? null,
fill_count_fp: order.fill_count_fp ?? null,
remaining_count: order.remaining_count ?? null,
remaining_count_fp: order.remaining_count_fp ?? null,
initial_count: order.initial_count ?? null,
initial_count_fp: order.initial_count_fp ?? null,
taker_fees: order.taker_fees ?? null,
maker_fees: order.maker_fees ?? null,
taker_fees_dollars: order.taker_fees_dollars ?? null,
maker_fees_dollars: order.maker_fees_dollars ?? null,
taker_fill_cost: order.taker_fill_cost ?? null,
maker_fill_cost: order.maker_fill_cost ?? null,
taker_fill_cost_dollars: order.taker_fill_cost_dollars ?? null,
maker_fill_cost_dollars: order.maker_fill_cost_dollars ?? null,
queue_position: order.queue_position ?? null,
expiration_time: order.expiration_time ?? null,
created_time: order.created_time ?? null,
last_update_time: order.last_update_time ?? null,
self_trade_prevention_type: order.self_trade_prevention_type ?? null,
order_group_id: order.order_group_id ?? null,
cancel_order_on_pause: order.cancel_order_on_pause ?? null,
}))
return {
success: true,
output: {
orders,
cursor: data.cursor ?? null,
},
}
},
outputs: {
orders: {
type: 'array',
description: 'Array of order objects with full API response fields',
properties: {
order_id: { type: 'string', description: 'Order ID' },
user_id: { type: 'string', description: 'User ID' },
client_order_id: { type: 'string', description: 'Client order ID' },
ticker: { type: 'string', description: 'Market ticker' },
side: { type: 'string', description: 'Order side (yes/no)' },
action: { type: 'string', description: 'Action (buy/sell)' },
type: { type: 'string', description: 'Order type (limit/market)' },
status: { type: 'string', description: 'Order status (resting/canceled/executed)' },
yes_price: { type: 'number', description: 'Yes price in cents' },
no_price: { type: 'number', description: 'No price in cents' },
yes_price_dollars: { type: 'string', description: 'Yes price in dollars' },
no_price_dollars: { type: 'string', description: 'No price in dollars' },
fill_count: { type: 'number', description: 'Filled contract count' },
fill_count_fp: { type: 'string', description: 'Filled count (fixed-point)' },
remaining_count: { type: 'number', description: 'Remaining contracts' },
remaining_count_fp: { type: 'string', description: 'Remaining count (fixed-point)' },
initial_count: { type: 'number', description: 'Initial contract count' },
initial_count_fp: { type: 'string', description: 'Initial count (fixed-point)' },
taker_fees: { type: 'number', description: 'Taker fees in cents' },
maker_fees: { type: 'number', description: 'Maker fees in cents' },
taker_fees_dollars: { type: 'string', description: 'Taker fees in dollars' },
maker_fees_dollars: { type: 'string', description: 'Maker fees in dollars' },
taker_fill_cost: { type: 'number', description: 'Taker fill cost in cents' },
maker_fill_cost: { type: 'number', description: 'Maker fill cost in cents' },
taker_fill_cost_dollars: { type: 'string', description: 'Taker fill cost in dollars' },
maker_fill_cost_dollars: { type: 'string', description: 'Maker fill cost in dollars' },
queue_position: { type: 'number', description: 'Queue position (deprecated)' },
expiration_time: { type: 'string', description: 'Order expiration time' },
created_time: { type: 'string', description: 'Order creation time' },
last_update_time: { type: 'string', description: 'Last update time' },
self_trade_prevention_type: { type: 'string', description: 'Self-trade prevention type' },
order_group_id: { type: 'string', description: 'Order group ID' },
cancel_order_on_pause: { type: 'boolean', description: 'Cancel on market pause' },
},
},
cursor: {
type: 'string',
description: 'Pagination cursor for fetching more results',
},
},
}

View File

@@ -126,3 +126,195 @@ export const kalshiGetPositionsTool: ToolConfig<
},
},
}
/**
* V2 Params for Get Positions - removes invalid settlementStatus, adds countFilter and subaccount
*/
export interface KalshiGetPositionsV2Params extends KalshiAuthParams, KalshiPaginationParams {
ticker?: string
eventTicker?: string
countFilter?: string
subaccount?: string
}
/**
* V2 Response matching Kalshi API exactly
*/
export interface KalshiGetPositionsV2Response {
success: boolean
output: {
market_positions: Array<{
ticker: string
event_ticker: string
event_title: string | null
market_title: string | null
position: number
market_exposure: number | null
realized_pnl: number | null
total_traded: number | null
resting_orders_count: number | null
fees_paid: number | null
}>
event_positions: Array<{
event_ticker: string
event_exposure: number
realized_pnl: number | null
total_cost: number | null
}> | null
cursor: string | null
}
}
export const kalshiGetPositionsV2Tool: ToolConfig<
KalshiGetPositionsV2Params,
KalshiGetPositionsV2Response
> = {
id: 'kalshi_get_positions_v2',
name: 'Get Positions from Kalshi V2',
description: 'Retrieve your open positions from Kalshi (V2 - exact API response)',
version: '2.0.0',
params: {
keyId: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your Kalshi API Key ID',
},
privateKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Your RSA Private Key (PEM format)',
},
ticker: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by market ticker',
},
eventTicker: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by event ticker (max 10 comma-separated)',
},
countFilter: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by count (all, positive, negative). Default: all',
},
subaccount: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Subaccount to get positions for',
},
limit: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Number of results (1-1000, default: 100)',
},
cursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination cursor for next page',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
if (params.ticker) queryParams.append('ticker', params.ticker)
if (params.eventTicker) queryParams.append('event_ticker', params.eventTicker)
if (params.countFilter) queryParams.append('count_filter', params.countFilter)
if (params.subaccount) queryParams.append('subaccount', params.subaccount)
if (params.limit) queryParams.append('limit', params.limit)
if (params.cursor) queryParams.append('cursor', params.cursor)
const query = queryParams.toString()
const url = buildKalshiUrl('/portfolio/positions')
return query ? `${url}?${query}` : url
},
method: 'GET',
headers: (params) => {
const path = '/trade-api/v2/portfolio/positions'
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'GET', path)
},
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'get_positions_v2')
}
const marketPositions = (data.market_positions || []).map((p: Record<string, unknown>) => ({
ticker: p.ticker ?? null,
event_ticker: p.event_ticker ?? null,
event_title: p.event_title ?? null,
market_title: p.market_title ?? null,
position: p.position ?? 0,
market_exposure: p.market_exposure ?? null,
realized_pnl: p.realized_pnl ?? null,
total_traded: p.total_traded ?? null,
resting_orders_count: p.resting_orders_count ?? null,
fees_paid: p.fees_paid ?? null,
}))
const eventPositions = data.event_positions
? (data.event_positions as Array<Record<string, unknown>>).map((p) => ({
event_ticker: (p.event_ticker as string) ?? '',
event_exposure: (p.event_exposure as number) ?? 0,
realized_pnl: (p.realized_pnl as number | null) ?? null,
total_cost: (p.total_cost as number | null) ?? null,
}))
: null
return {
success: true,
output: {
market_positions: marketPositions,
event_positions: eventPositions,
cursor: data.cursor ?? null,
},
}
},
outputs: {
market_positions: {
type: 'array',
description: 'Array of market position objects',
properties: {
ticker: { type: 'string', description: 'Market ticker' },
event_ticker: { type: 'string', description: 'Event ticker' },
event_title: { type: 'string', description: 'Event title' },
market_title: { type: 'string', description: 'Market title' },
position: { type: 'number', description: 'Position size' },
market_exposure: { type: 'number', description: 'Market exposure' },
realized_pnl: { type: 'number', description: 'Realized P&L' },
total_traded: { type: 'number', description: 'Total traded' },
resting_orders_count: { type: 'number', description: 'Resting orders count' },
fees_paid: { type: 'number', description: 'Fees paid' },
},
},
event_positions: {
type: 'array',
description: 'Array of event position objects',
properties: {
event_ticker: { type: 'string', description: 'Event ticker' },
event_exposure: { type: 'number', description: 'Event exposure' },
realized_pnl: { type: 'number', description: 'Realized P&L' },
total_cost: { type: 'number', description: 'Total cost' },
},
},
cursor: {
type: 'string',
description: 'Pagination cursor for fetching more results',
},
},
}

View File

@@ -65,3 +65,141 @@ export const kalshiGetSeriesByTickerTool: ToolConfig<
},
},
}
/**
* V2 Params for Get Series by Ticker
*/
export interface KalshiGetSeriesByTickerV2Params {
seriesTicker: string
includeVolume?: string
}
/**
* V2 Response matching Kalshi API exactly
*/
export interface KalshiGetSeriesByTickerV2Response {
success: boolean
output: {
series: {
ticker: string
title: string
frequency: string
category: string
tags: string[] | null
settlement_sources: Array<{
name: string
url: string
}> | null
contract_url: string | null
contract_terms_url: string | null
fee_type: string | null
fee_multiplier: number | null
additional_prohibitions: string[] | null
product_metadata: Record<string, unknown> | null
volume: number | null
volume_fp: number | null
}
}
}
export const kalshiGetSeriesByTickerV2Tool: ToolConfig<
KalshiGetSeriesByTickerV2Params,
KalshiGetSeriesByTickerV2Response
> = {
id: 'kalshi_get_series_by_ticker_v2',
name: 'Get Series by Ticker from Kalshi V2',
description: 'Retrieve details of a specific market series by ticker (V2 - exact API response)',
version: '2.0.0',
params: {
seriesTicker: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Series ticker',
},
includeVolume: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Include volume data in response (true/false)',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
if (params.includeVolume) queryParams.append('include_volume', params.includeVolume)
const query = queryParams.toString()
const url = buildKalshiUrl(`/series/${params.seriesTicker}`)
return query ? `${url}?${query}` : url
},
method: 'GET',
headers: () => ({
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'get_series_by_ticker_v2')
}
const series = data.series || data
const settlementSources = series.settlement_sources
? (series.settlement_sources as Array<Record<string, unknown>>).map((s) => ({
name: (s.name as string) ?? null,
url: (s.url as string) ?? null,
}))
: null
return {
success: true,
output: {
series: {
ticker: series.ticker ?? null,
title: series.title ?? null,
frequency: series.frequency ?? null,
category: series.category ?? null,
tags: series.tags ?? null,
settlement_sources: settlementSources,
contract_url: series.contract_url ?? null,
contract_terms_url: series.contract_terms_url ?? null,
fee_type: series.fee_type ?? null,
fee_multiplier: series.fee_multiplier ?? null,
additional_prohibitions: series.additional_prohibitions ?? null,
product_metadata: series.product_metadata ?? null,
volume: series.volume ?? null,
volume_fp: series.volume_fp ?? null,
},
},
}
},
outputs: {
series: {
type: 'object',
description: 'Series object with full details matching Kalshi API response',
properties: {
ticker: { type: 'string', description: 'Series ticker' },
title: { type: 'string', description: 'Series title' },
frequency: { type: 'string', description: 'Event frequency' },
category: { type: 'string', description: 'Series category' },
tags: { type: 'array', description: 'Series tags' },
settlement_sources: { type: 'array', description: 'Settlement sources' },
contract_url: { type: 'string', description: 'Contract URL' },
contract_terms_url: { type: 'string', description: 'Contract terms URL' },
fee_type: { type: 'string', description: 'Fee type' },
fee_multiplier: { type: 'number', description: 'Fee multiplier' },
additional_prohibitions: { type: 'array', description: 'Additional prohibitions' },
product_metadata: { type: 'object', description: 'Product metadata' },
volume: { type: 'number', description: 'Series volume' },
volume_fp: { type: 'number', description: 'Volume (fixed-point)' },
},
},
},
}

View File

@@ -80,3 +80,138 @@ export const kalshiGetTradesTool: ToolConfig<KalshiGetTradesParams, KalshiGetTra
},
},
}
/**
* V2 Get Trades Tool - Returns exact Kalshi API response structure with additional params
*/
export interface KalshiGetTradesV2Params extends KalshiPaginationParams {
ticker?: string // Filter by market ticker
minTs?: number // Minimum timestamp (Unix seconds)
maxTs?: number // Maximum timestamp (Unix seconds)
}
export interface KalshiGetTradesV2Response {
success: boolean
output: {
trades: Array<{
trade_id: string | null
ticker: string
yes_price: number | null
no_price: number | null
count: number | null
count_fp: number | null
created_time: string | null
taker_side: string | null
}>
cursor: string | null
}
}
export const kalshiGetTradesV2Tool: ToolConfig<KalshiGetTradesV2Params, KalshiGetTradesV2Response> =
{
id: 'kalshi_get_trades_v2',
name: 'Get Trades from Kalshi V2',
description:
'Retrieve recent trades with additional filtering options (V2 - includes trade_id and count_fp)',
version: '2.0.0',
params: {
ticker: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by market ticker',
},
minTs: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Minimum timestamp (Unix seconds)',
},
maxTs: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum timestamp (Unix seconds)',
},
limit: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Number of results (1-1000, default: 100)',
},
cursor: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination cursor for next page',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
if (params.ticker) queryParams.append('ticker', params.ticker)
if (params.minTs) queryParams.append('min_ts', params.minTs.toString())
if (params.maxTs) queryParams.append('max_ts', params.maxTs.toString())
if (params.limit) queryParams.append('limit', params.limit)
if (params.cursor) queryParams.append('cursor', params.cursor)
const query = queryParams.toString()
const url = buildKalshiUrl('/markets/trades')
return query ? `${url}?${query}` : url
},
method: 'GET',
headers: () => ({
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handleKalshiError(data, response.status, 'get_trades_v2')
}
const trades = (data.trades || []).map((t: Record<string, unknown>) => ({
trade_id: t.trade_id ?? null,
ticker: t.ticker ?? null,
yes_price: t.yes_price ?? null,
no_price: t.no_price ?? null,
count: t.count ?? null,
count_fp: t.count_fp ?? null,
created_time: t.created_time ?? null,
taker_side: t.taker_side ?? null,
}))
return {
success: true,
output: {
trades,
cursor: data.cursor ?? null,
},
}
},
outputs: {
trades: {
type: 'array',
description: 'Array of trade objects with trade_id and count_fp',
properties: {
trade_id: { type: 'string', description: 'Trade ID' },
ticker: { type: 'string', description: 'Market ticker' },
yes_price: { type: 'number', description: 'Yes price' },
no_price: { type: 'number', description: 'No price' },
count: { type: 'number', description: 'Number of contracts' },
count_fp: { type: 'number', description: 'Count (fixed-point)' },
created_time: { type: 'string', description: 'Trade creation time' },
taker_side: { type: 'string', description: 'Taker side (yes/no)' },
},
},
cursor: {
type: 'string',
description: 'Pagination cursor for fetching more results',
},
},
}

View File

@@ -1,17 +1,17 @@
export { kalshiAmendOrderTool } from './amend_order'
export { kalshiCancelOrderTool } from './cancel_order'
export { kalshiCreateOrderTool } from './create_order'
export { kalshiGetBalanceTool } from './get_balance'
export { kalshiGetCandlesticksTool } from './get_candlesticks'
export { kalshiGetEventTool } from './get_event'
export { kalshiGetEventsTool } from './get_events'
export { kalshiGetExchangeStatusTool } from './get_exchange_status'
export { kalshiGetFillsTool } from './get_fills'
export { kalshiGetMarketTool } from './get_market'
export { kalshiGetMarketsTool } from './get_markets'
export { kalshiGetOrderTool } from './get_order'
export { kalshiGetOrderbookTool } from './get_orderbook'
export { kalshiGetOrdersTool } from './get_orders'
export { kalshiGetPositionsTool } from './get_positions'
export { kalshiGetSeriesByTickerTool } from './get_series_by_ticker'
export { kalshiGetTradesTool } from './get_trades'
export { kalshiAmendOrderTool, kalshiAmendOrderV2Tool } from './amend_order'
export { kalshiCancelOrderTool, kalshiCancelOrderV2Tool } from './cancel_order'
export { kalshiCreateOrderTool, kalshiCreateOrderV2Tool } from './create_order'
export { kalshiGetBalanceTool, kalshiGetBalanceV2Tool } from './get_balance'
export { kalshiGetCandlesticksTool, kalshiGetCandlesticksV2Tool } from './get_candlesticks'
export { kalshiGetEventTool, kalshiGetEventV2Tool } from './get_event'
export { kalshiGetEventsTool, kalshiGetEventsV2Tool } from './get_events'
export { kalshiGetExchangeStatusTool, kalshiGetExchangeStatusV2Tool } from './get_exchange_status'
export { kalshiGetFillsTool, kalshiGetFillsV2Tool } from './get_fills'
export { kalshiGetMarketTool, kalshiGetMarketV2Tool } from './get_market'
export { kalshiGetMarketsTool, kalshiGetMarketsV2Tool } from './get_markets'
export { kalshiGetOrderTool, kalshiGetOrderV2Tool } from './get_order'
export { kalshiGetOrderbookTool, kalshiGetOrderbookV2Tool } from './get_orderbook'
export { kalshiGetOrdersTool, kalshiGetOrdersV2Tool } from './get_orders'
export { kalshiGetPositionsTool, kalshiGetPositionsV2Tool } from './get_positions'
export { kalshiGetSeriesByTickerTool, kalshiGetSeriesByTickerV2Tool } from './get_series_by_ticker'
export { kalshiGetTradesTool, kalshiGetTradesV2Tool } from './get_trades'

View File

@@ -0,0 +1,206 @@
import type { ToolConfig } from '@/tools/types'
import type { PolymarketActivity } from './types'
import { buildDataUrl, handlePolymarketError } from './types'
export interface PolymarketGetActivityParams {
user: string
limit?: string
offset?: string
market?: string
eventId?: string
type?: string
start?: number
end?: number
sortBy?: string
sortDirection?: string
side?: string
}
export interface PolymarketGetActivityResponse {
success: boolean
output: {
activity: PolymarketActivity[]
}
}
export const polymarketGetActivityTool: ToolConfig<
PolymarketGetActivityParams,
PolymarketGetActivityResponse
> = {
id: 'polymarket_get_activity',
name: 'Get Activity from Polymarket',
description:
'Retrieve on-chain activity for a user including trades, splits, merges, redemptions, rewards, and conversions',
version: '1.0.0',
params: {
user: {
type: 'string',
required: true,
description: 'User wallet address (0x-prefixed)',
visibility: 'user-or-llm',
},
limit: {
type: 'string',
required: false,
description: 'Maximum results (default: 100, max: 500)',
visibility: 'user-or-llm',
},
offset: {
type: 'string',
required: false,
description: 'Pagination offset (default: 0, max: 10000)',
visibility: 'user-or-llm',
},
market: {
type: 'string',
required: false,
description: 'Comma-separated condition IDs (mutually exclusive with eventId)',
visibility: 'user-or-llm',
},
eventId: {
type: 'string',
required: false,
description: 'Comma-separated event IDs (mutually exclusive with market)',
visibility: 'user-or-llm',
},
type: {
type: 'string',
required: false,
description:
'Activity type filter: TRADE, SPLIT, MERGE, REDEEM, REWARD, CONVERSION, MAKER_REBATE',
visibility: 'user-or-llm',
},
start: {
type: 'number',
required: false,
description: 'Start timestamp (Unix seconds)',
visibility: 'user-or-llm',
},
end: {
type: 'number',
required: false,
description: 'End timestamp (Unix seconds)',
visibility: 'user-or-llm',
},
sortBy: {
type: 'string',
required: false,
description: 'Sort field: TIMESTAMP, TOKENS, or CASH (default: TIMESTAMP)',
visibility: 'user-or-llm',
},
sortDirection: {
type: 'string',
required: false,
description: 'Sort direction: ASC or DESC (default: DESC)',
visibility: 'user-or-llm',
},
side: {
type: 'string',
required: false,
description: 'Trade side filter: BUY or SELL (only applies to trades)',
visibility: 'user-or-llm',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
queryParams.append('user', params.user)
if (params.limit) queryParams.append('limit', params.limit)
if (params.offset) queryParams.append('offset', params.offset)
if (params.market) queryParams.append('market', params.market)
if (params.eventId) queryParams.append('eventId', params.eventId)
if (params.type) queryParams.append('type', params.type)
if (params.start != null && !Number.isNaN(params.start))
queryParams.append('start', String(params.start))
if (params.end != null && !Number.isNaN(params.end))
queryParams.append('end', String(params.end))
if (params.sortBy) queryParams.append('sortBy', params.sortBy)
if (params.sortDirection) queryParams.append('sortDirection', params.sortDirection)
if (params.side) queryParams.append('side', params.side)
return `${buildDataUrl('/activity')}?${queryParams.toString()}`
},
method: 'GET',
headers: () => ({
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handlePolymarketError(data, response.status, 'get_activity')
}
const activityList = Array.isArray(data) ? data : []
const activity: PolymarketActivity[] = activityList.map((a: any) => ({
proxyWallet: a.proxyWallet ?? null,
timestamp: a.timestamp ?? 0,
conditionId: a.conditionId ?? '',
type: a.type ?? '',
size: a.size ?? 0,
usdcSize: a.usdcSize ?? 0,
transactionHash: a.transactionHash ?? null,
price: a.price ?? null,
asset: a.asset ?? null,
side: a.side ?? null,
outcomeIndex: a.outcomeIndex ?? null,
title: a.title ?? null,
slug: a.slug ?? null,
icon: a.icon ?? null,
eventSlug: a.eventSlug ?? null,
outcome: a.outcome ?? null,
name: a.name ?? null,
pseudonym: a.pseudonym ?? null,
bio: a.bio ?? null,
profileImage: a.profileImage ?? null,
profileImageOptimized: a.profileImageOptimized ?? null,
}))
return {
success: true,
output: {
activity,
},
}
},
outputs: {
activity: {
type: 'array',
description: 'Array of activity entries',
items: {
type: 'object',
properties: {
proxyWallet: { type: 'string', description: 'User proxy wallet address' },
timestamp: { type: 'number', description: 'Unix timestamp of activity' },
conditionId: { type: 'string', description: 'Market condition ID' },
type: {
type: 'string',
description: 'Activity type (TRADE, SPLIT, MERGE, REDEEM, REWARD, CONVERSION)',
},
size: { type: 'number', description: 'Size in tokens' },
usdcSize: { type: 'number', description: 'Size in USDC' },
transactionHash: { type: 'string', description: 'Blockchain transaction hash' },
price: { type: 'number', description: 'Price (for trades)' },
asset: { type: 'string', description: 'Asset/token ID' },
side: { type: 'string', description: 'Trade side (BUY/SELL)' },
outcomeIndex: { type: 'number', description: 'Outcome index' },
title: { type: 'string', description: 'Market title' },
slug: { type: 'string', description: 'Market slug' },
icon: { type: 'string', description: 'Market icon URL' },
eventSlug: { type: 'string', description: 'Event slug' },
outcome: { type: 'string', description: 'Outcome name' },
name: { type: 'string', description: 'User display name' },
pseudonym: { type: 'string', description: 'User pseudonym' },
bio: { type: 'string', description: 'User bio' },
profileImage: { type: 'string', description: 'User profile image URL' },
profileImageOptimized: { type: 'string', description: 'Optimized profile image URL' },
},
},
},
},
}

View File

@@ -71,6 +71,26 @@ export const polymarketGetEventTool: ToolConfig<
event: {
type: 'object',
description: 'Event object with details',
properties: {
id: { type: 'string', description: 'Event ID' },
ticker: { type: 'string', description: 'Event ticker' },
slug: { type: 'string', description: 'Event slug' },
title: { type: 'string', description: 'Event title' },
description: { type: 'string', description: 'Event description' },
startDate: { type: 'string', description: 'Start date' },
creationDate: { type: 'string', description: 'Creation date' },
endDate: { type: 'string', description: 'End date' },
image: { type: 'string', description: 'Event image URL' },
icon: { type: 'string', description: 'Event icon URL' },
active: { type: 'boolean', description: 'Whether event is active' },
closed: { type: 'boolean', description: 'Whether event is closed' },
archived: { type: 'boolean', description: 'Whether event is archived' },
liquidity: { type: 'number', description: 'Total liquidity' },
volume: { type: 'number', description: 'Total volume' },
openInterest: { type: 'number', description: 'Open interest' },
commentCount: { type: 'number', description: 'Comment count' },
markets: { type: 'array', description: 'Array of markets in this event' },
},
},
},
}

View File

@@ -3,10 +3,10 @@ import type { PolymarketEvent, PolymarketPaginationParams } from './types'
import { buildGammaUrl, handlePolymarketError } from './types'
export interface PolymarketGetEventsParams extends PolymarketPaginationParams {
closed?: string // 'true' or 'false' - filter for closed/active events
order?: string // sort field (e.g., 'volume', 'liquidity', 'startDate', 'endDate')
ascending?: string // 'true' or 'false' - sort direction
tagId?: string // filter by tag ID
closed?: string
order?: string
ascending?: string
tagId?: string
}
export interface PolymarketGetEventsResponse {
@@ -29,7 +29,7 @@ export const polymarketGetEventsTool: ToolConfig<
closed: {
type: 'string',
required: false,
description: 'Filter by closed status (true/false). Use false for active events only.',
description: 'Filter by closed status (true/false). Use false for open events only.',
visibility: 'user-or-llm',
},
order: {
@@ -71,13 +71,11 @@ export const polymarketGetEventsTool: ToolConfig<
if (params.order) queryParams.append('order', params.order)
if (params.ascending) queryParams.append('ascending', params.ascending)
if (params.tagId) queryParams.append('tag_id', params.tagId)
// Default limit to 50 to prevent browser crashes from large data sets
queryParams.append('limit', params.limit || '50')
if (params.offset) queryParams.append('offset', params.offset)
const query = queryParams.toString()
const url = buildGammaUrl('/events')
return `${url}?${query}`
return `${url}?${queryParams.toString()}`
},
method: 'GET',
headers: () => ({
@@ -92,7 +90,6 @@ export const polymarketGetEventsTool: ToolConfig<
handlePolymarketError(data, response.status, 'get_events')
}
// Response is an array of events
const events = Array.isArray(data) ? data : []
return {
@@ -107,6 +104,26 @@ export const polymarketGetEventsTool: ToolConfig<
events: {
type: 'array',
description: 'Array of event objects',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Event ID' },
ticker: { type: 'string', description: 'Event ticker' },
slug: { type: 'string', description: 'Event slug' },
title: { type: 'string', description: 'Event title' },
description: { type: 'string', description: 'Event description' },
startDate: { type: 'string', description: 'Start date' },
endDate: { type: 'string', description: 'End date' },
image: { type: 'string', description: 'Event image URL' },
icon: { type: 'string', description: 'Event icon URL' },
active: { type: 'boolean', description: 'Whether event is active' },
closed: { type: 'boolean', description: 'Whether event is closed' },
archived: { type: 'boolean', description: 'Whether event is archived' },
liquidity: { type: 'number', description: 'Total liquidity' },
volume: { type: 'number', description: 'Total volume' },
markets: { type: 'array', description: 'Array of markets in this event' },
},
},
},
},
}

View File

@@ -0,0 +1,132 @@
import type { ToolConfig } from '@/tools/types'
import type { PolymarketMarketHolders } from './types'
import { buildDataUrl, handlePolymarketError } from './types'
export interface PolymarketGetHoldersParams {
market: string
limit?: string
minBalance?: string
}
export interface PolymarketGetHoldersResponse {
success: boolean
output: {
holders: PolymarketMarketHolders[]
}
}
export const polymarketGetHoldersTool: ToolConfig<
PolymarketGetHoldersParams,
PolymarketGetHoldersResponse
> = {
id: 'polymarket_get_holders',
name: 'Get Market Holders from Polymarket',
description: 'Retrieve top holders of a specific market token',
version: '1.0.0',
params: {
market: {
type: 'string',
required: true,
description: 'Comma-separated list of condition IDs',
visibility: 'user-or-llm',
},
limit: {
type: 'string',
required: false,
description: 'Number of holders to return (0-20, default: 20)',
visibility: 'user-or-llm',
},
minBalance: {
type: 'string',
required: false,
description: 'Minimum balance threshold (default: 1)',
visibility: 'user-or-llm',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
queryParams.append('market', params.market)
if (params.limit) queryParams.append('limit', params.limit)
if (params.minBalance) queryParams.append('minBalance', params.minBalance)
return `${buildDataUrl('/holders')}?${queryParams.toString()}`
},
method: 'GET',
headers: () => ({
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handlePolymarketError(data, response.status, 'get_holders')
}
const marketHolders = Array.isArray(data) ? data : []
const holders: PolymarketMarketHolders[] = marketHolders.map((mh: any) => ({
token: mh.token ?? '',
holders: (mh.holders ?? []).map((h: any) => ({
proxyWallet: h.proxyWallet ?? '',
bio: h.bio ?? null,
asset: h.asset ?? '',
pseudonym: h.pseudonym ?? null,
amount: h.amount ?? 0,
displayUsernamePublic: h.displayUsernamePublic ?? false,
outcomeIndex: h.outcomeIndex ?? 0,
name: h.name ?? null,
profileImage: h.profileImage ?? null,
profileImageOptimized: h.profileImageOptimized ?? null,
})),
}))
return {
success: true,
output: {
holders,
},
}
},
outputs: {
holders: {
type: 'array',
description: 'Array of market holder groups by token',
items: {
type: 'object',
properties: {
token: { type: 'string', description: 'Token/asset ID' },
holders: {
type: 'array',
description: 'Array of holders for this token',
items: {
type: 'object',
properties: {
proxyWallet: { type: 'string', description: 'Holder wallet address' },
bio: { type: 'string', description: 'Holder bio' },
asset: { type: 'string', description: 'Asset ID' },
pseudonym: { type: 'string', description: 'Holder pseudonym' },
amount: { type: 'number', description: 'Amount held' },
displayUsernamePublic: {
type: 'boolean',
description: 'Whether username is publicly displayed',
},
outcomeIndex: { type: 'number', description: 'Outcome index' },
name: { type: 'string', description: 'Holder display name' },
profileImage: { type: 'string', description: 'Profile image URL' },
profileImageOptimized: {
type: 'string',
description: 'Optimized profile image URL',
},
},
},
},
},
},
},
},
}

View File

@@ -9,6 +9,7 @@ export interface PolymarketGetLastTradePriceResponse {
success: boolean
output: {
price: string
side: string
}
}
@@ -52,7 +53,8 @@ export const polymarketGetLastTradePriceTool: ToolConfig<
return {
success: true,
output: {
price: typeof data === 'string' ? data : data.price || '',
price: data.price ?? '',
side: data.side ?? '',
},
}
},
@@ -62,5 +64,9 @@ export const polymarketGetLastTradePriceTool: ToolConfig<
type: 'string',
description: 'Last trade price',
},
side: {
type: 'string',
description: 'Side of the last trade (BUY or SELL)',
},
},
}

View File

@@ -0,0 +1,143 @@
import type { ToolConfig } from '@/tools/types'
import type { PolymarketLeaderboardEntry } from './types'
import { buildDataUrl, handlePolymarketError } from './types'
export interface PolymarketGetLeaderboardParams {
category?: string
timePeriod?: string
orderBy?: string
limit?: string
offset?: string
user?: string
userName?: string
}
export interface PolymarketGetLeaderboardResponse {
success: boolean
output: {
leaderboard: PolymarketLeaderboardEntry[]
}
}
export const polymarketGetLeaderboardTool: ToolConfig<
PolymarketGetLeaderboardParams,
PolymarketGetLeaderboardResponse
> = {
id: 'polymarket_get_leaderboard',
name: 'Get Leaderboard from Polymarket',
description: 'Retrieve trader leaderboard rankings by profit/loss or volume',
version: '1.0.0',
params: {
category: {
type: 'string',
required: false,
description:
'Category filter: OVERALL, POLITICS, SPORTS, CRYPTO, CULTURE, MENTIONS, WEATHER, ECONOMICS, TECH, FINANCE (default: OVERALL)',
visibility: 'user-or-llm',
},
timePeriod: {
type: 'string',
required: false,
description: 'Time period: DAY, WEEK, MONTH, ALL (default: DAY)',
visibility: 'user-or-llm',
},
orderBy: {
type: 'string',
required: false,
description: 'Order by: PNL or VOL (default: PNL)',
visibility: 'user-or-llm',
},
limit: {
type: 'string',
required: false,
description: 'Number of results (1-50, default: 25)',
visibility: 'user-or-llm',
},
offset: {
type: 'string',
required: false,
description: 'Pagination offset (0-1000, default: 0)',
visibility: 'user-or-llm',
},
user: {
type: 'string',
required: false,
description: 'Filter by specific user wallet address',
visibility: 'user-or-llm',
},
userName: {
type: 'string',
required: false,
description: 'Filter by username',
visibility: 'user-or-llm',
},
},
request: {
url: (params) => {
const queryParams = new URLSearchParams()
if (params.category) queryParams.append('category', params.category)
if (params.timePeriod) queryParams.append('timePeriod', params.timePeriod)
if (params.orderBy) queryParams.append('orderBy', params.orderBy)
if (params.limit) queryParams.append('limit', params.limit)
if (params.offset) queryParams.append('offset', params.offset)
if (params.user) queryParams.append('user', params.user)
if (params.userName) queryParams.append('userName', params.userName)
const query = queryParams.toString()
return query ? `${buildDataUrl('/v1/leaderboard')}?${query}` : buildDataUrl('/v1/leaderboard')
},
method: 'GET',
headers: () => ({
'Content-Type': 'application/json',
}),
},
transformResponse: async (response: Response) => {
const data = await response.json()
if (!response.ok) {
handlePolymarketError(data, response.status, 'get_leaderboard')
}
const entries = Array.isArray(data) ? data : []
const leaderboard: PolymarketLeaderboardEntry[] = entries.map((entry: any) => ({
rank: entry.rank ?? '',
proxyWallet: entry.proxyWallet ?? '',
userName: entry.userName ?? null,
vol: entry.vol ?? 0,
pnl: entry.pnl ?? 0,
profileImage: entry.profileImage ?? null,
xUsername: entry.xUsername ?? null,
verifiedBadge: entry.verifiedBadge ?? false,
}))
return {
success: true,
output: {
leaderboard,
},
}
},
outputs: {
leaderboard: {
type: 'array',
description: 'Array of leaderboard entries',
items: {
type: 'object',
properties: {
rank: { type: 'string', description: 'Leaderboard rank position' },
proxyWallet: { type: 'string', description: 'User proxy wallet address' },
userName: { type: 'string', description: 'User display name' },
vol: { type: 'number', description: 'Trading volume' },
pnl: { type: 'number', description: 'Profit and loss' },
profileImage: { type: 'string', description: 'User profile image URL' },
xUsername: { type: 'string', description: 'Twitter/X username' },
verifiedBadge: { type: 'boolean', description: 'Whether user has verified badge' },
},
},
},
},
}

View File

@@ -71,6 +71,30 @@ export const polymarketGetMarketTool: ToolConfig<
market: {
type: 'object',
description: 'Market object with details',
properties: {
id: { type: 'string', description: 'Market ID' },
question: { type: 'string', description: 'Market question' },
conditionId: { type: 'string', description: 'Condition ID' },
slug: { type: 'string', description: 'Market slug' },
resolutionSource: { type: 'string', description: 'Resolution source' },
endDate: { type: 'string', description: 'End date' },
startDate: { type: 'string', description: 'Start date' },
image: { type: 'string', description: 'Market image URL' },
icon: { type: 'string', description: 'Market icon URL' },
description: { type: 'string', description: 'Market description' },
outcomes: { type: 'string', description: 'Outcomes JSON string' },
outcomePrices: { type: 'string', description: 'Outcome prices JSON string' },
volume: { type: 'string', description: 'Total volume' },
liquidity: { type: 'string', description: 'Total liquidity' },
active: { type: 'boolean', description: 'Whether market is active' },
closed: { type: 'boolean', description: 'Whether market is closed' },
archived: { type: 'boolean', description: 'Whether market is archived' },
volumeNum: { type: 'number', description: 'Volume as number' },
liquidityNum: { type: 'number', description: 'Liquidity as number' },
clobTokenIds: { type: 'array', description: 'CLOB token IDs' },
acceptingOrders: { type: 'boolean', description: 'Whether accepting orders' },
negRisk: { type: 'boolean', description: 'Whether negative risk' },
},
},
},
}

View File

@@ -3,10 +3,10 @@ import type { PolymarketMarket, PolymarketPaginationParams } from './types'
import { buildGammaUrl, handlePolymarketError } from './types'
export interface PolymarketGetMarketsParams extends PolymarketPaginationParams {
closed?: string // 'true' or 'false' - filter for closed/active markets
order?: string // sort field - use camelCase (e.g., 'volumeNum', 'liquidityNum', 'startDate', 'endDate')
ascending?: string // 'true' or 'false' - sort direction
tagId?: string // filter by tag ID
closed?: string
order?: string
ascending?: string
tagId?: string
}
export interface PolymarketGetMarketsResponse {
@@ -29,7 +29,7 @@ export const polymarketGetMarketsTool: ToolConfig<
closed: {
type: 'string',
required: false,
description: 'Filter by closed status (true/false). Use false for active markets only.',
description: 'Filter by closed status (true/false). Use false for open markets only.',
visibility: 'user-or-llm',
},
order: {
@@ -71,13 +71,11 @@ export const polymarketGetMarketsTool: ToolConfig<
if (params.order) queryParams.append('order', params.order)
if (params.ascending) queryParams.append('ascending', params.ascending)
if (params.tagId) queryParams.append('tag_id', params.tagId)
// Default limit to 50 to prevent browser crashes from large data sets
queryParams.append('limit', params.limit || '50')
if (params.offset) queryParams.append('offset', params.offset)
const query = queryParams.toString()
const url = buildGammaUrl('/markets')
return `${url}?${query}`
return `${url}?${queryParams.toString()}`
},
method: 'GET',
headers: () => ({
@@ -107,6 +105,26 @@ export const polymarketGetMarketsTool: ToolConfig<
markets: {
type: 'array',
description: 'Array of market objects',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Market ID' },
question: { type: 'string', description: 'Market question' },
conditionId: { type: 'string', description: 'Condition ID' },
slug: { type: 'string', description: 'Market slug' },
endDate: { type: 'string', description: 'End date' },
image: { type: 'string', description: 'Market image URL' },
outcomes: { type: 'string', description: 'Outcomes JSON string' },
outcomePrices: { type: 'string', description: 'Outcome prices JSON string' },
volume: { type: 'string', description: 'Total volume' },
liquidity: { type: 'string', description: 'Total liquidity' },
active: { type: 'boolean', description: 'Whether market is active' },
closed: { type: 'boolean', description: 'Whether market is closed' },
volumeNum: { type: 'number', description: 'Volume as number' },
liquidityNum: { type: 'number', description: 'Liquidity as number' },
clobTokenIds: { type: 'array', description: 'CLOB token IDs' },
},
},
},
},
}

View File

@@ -50,10 +50,22 @@ export const polymarketGetOrderbookTool: ToolConfig<
handlePolymarketError(data, response.status, 'get_orderbook')
}
const orderbook: PolymarketOrderBook = {
market: data.market ?? '',
asset_id: data.asset_id ?? '',
hash: data.hash ?? '',
timestamp: data.timestamp ?? '',
bids: data.bids ?? [],
asks: data.asks ?? [],
min_order_size: data.min_order_size ?? '0',
tick_size: data.tick_size ?? '0',
neg_risk: data.neg_risk ?? false,
}
return {
success: true,
output: {
orderbook: data,
orderbook,
},
}
},
@@ -62,6 +74,37 @@ export const polymarketGetOrderbookTool: ToolConfig<
orderbook: {
type: 'object',
description: 'Order book with bids and asks arrays',
properties: {
market: { type: 'string', description: 'Market identifier' },
asset_id: { type: 'string', description: 'Asset token ID' },
hash: { type: 'string', description: 'Order book hash' },
timestamp: { type: 'string', description: 'Timestamp' },
bids: {
type: 'array',
description: 'Bid orders',
items: {
type: 'object',
properties: {
price: { type: 'string', description: 'Bid price' },
size: { type: 'string', description: 'Bid size' },
},
},
},
asks: {
type: 'array',
description: 'Ask orders',
items: {
type: 'object',
properties: {
price: { type: 'string', description: 'Ask price' },
size: { type: 'string', description: 'Ask size' },
},
},
},
min_order_size: { type: 'string', description: 'Minimum order size' },
tick_size: { type: 'string', description: 'Tick size' },
neg_risk: { type: 'boolean', description: 'Whether negative risk' },
},
},
},
}

View File

@@ -3,8 +3,17 @@ import type { PolymarketPosition } from './types'
import { buildDataUrl, handlePolymarketError } from './types'
export interface PolymarketGetPositionsParams {
user: string // Wallet address (required)
market?: string // Optional market filter
user: string
market?: string
eventId?: string
sizeThreshold?: string
redeemable?: string
mergeable?: string
sortBy?: string
sortDirection?: string
title?: string
limit?: string
offset?: string
}
export interface PolymarketGetPositionsResponse {
@@ -33,7 +42,63 @@ export const polymarketGetPositionsTool: ToolConfig<
market: {
type: 'string',
required: false,
description: 'Optional market ID to filter positions',
description:
'Condition IDs to filter positions (comma-separated, mutually exclusive with eventId)',
visibility: 'user-or-llm',
},
eventId: {
type: 'string',
required: false,
description: 'Event ID to filter positions (mutually exclusive with market)',
visibility: 'user-or-llm',
},
sizeThreshold: {
type: 'string',
required: false,
description: 'Minimum position size threshold (default: 1)',
visibility: 'user-or-llm',
},
redeemable: {
type: 'string',
required: false,
description: 'Filter for redeemable positions only (true/false)',
visibility: 'user-or-llm',
},
mergeable: {
type: 'string',
required: false,
description: 'Filter for mergeable positions only (true/false)',
visibility: 'user-or-llm',
},
sortBy: {
type: 'string',
required: false,
description:
'Sort field (TOKENS, CURRENT, INITIAL, CASHPNL, PERCENTPNL, TITLE, RESOLVING, PRICE, AVGPRICE)',
visibility: 'user-or-llm',
},
sortDirection: {
type: 'string',
required: false,
description: 'Sort direction (ASC or DESC)',
visibility: 'user-or-llm',
},
title: {
type: 'string',
required: false,
description: 'Search filter by title',
visibility: 'user-or-llm',
},
limit: {
type: 'string',
required: false,
description: 'Number of results per page',
visibility: 'user-or-llm',
},
offset: {
type: 'string',
required: false,
description: 'Pagination offset',
visibility: 'user-or-llm',
},
},
@@ -43,6 +108,15 @@ export const polymarketGetPositionsTool: ToolConfig<
const queryParams = new URLSearchParams()
queryParams.append('user', params.user)
if (params.market) queryParams.append('market', params.market)
if (params.eventId) queryParams.append('eventId', params.eventId)
if (params.sizeThreshold) queryParams.append('sizeThreshold', params.sizeThreshold)
if (params.redeemable) queryParams.append('redeemable', params.redeemable)
if (params.mergeable) queryParams.append('mergeable', params.mergeable)
if (params.sortBy) queryParams.append('sortBy', params.sortBy)
if (params.sortDirection) queryParams.append('sortDirection', params.sortDirection)
if (params.title) queryParams.append('title', params.title)
if (params.limit) queryParams.append('limit', params.limit)
if (params.offset) queryParams.append('offset', params.offset)
return `${buildDataUrl('/positions')}?${queryParams.toString()}`
},
@@ -59,8 +133,34 @@ export const polymarketGetPositionsTool: ToolConfig<
handlePolymarketError(data, response.status, 'get_positions')
}
// Response is an array of positions
const positions = Array.isArray(data) ? data : []
const rawPositions = Array.isArray(data) ? data : []
const positions: PolymarketPosition[] = rawPositions.map((p: Record<string, unknown>) => ({
proxyWallet: (p.proxyWallet as string) ?? null,
asset: (p.asset as string) ?? '',
conditionId: (p.conditionId as string) ?? '',
size: (p.size as number) ?? 0,
avgPrice: (p.avgPrice as number) ?? 0,
initialValue: (p.initialValue as number) ?? 0,
currentValue: (p.currentValue as number) ?? 0,
cashPnl: (p.cashPnl as number) ?? 0,
percentPnl: (p.percentPnl as number) ?? 0,
totalBought: (p.totalBought as number) ?? 0,
realizedPnl: (p.realizedPnl as number) ?? 0,
percentRealizedPnl: (p.percentRealizedPnl as number) ?? 0,
curPrice: (p.curPrice as number) ?? 0,
redeemable: (p.redeemable as boolean) ?? false,
mergeable: (p.mergeable as boolean) ?? false,
title: (p.title as string) ?? null,
slug: (p.slug as string) ?? null,
icon: (p.icon as string) ?? null,
eventSlug: (p.eventSlug as string) ?? null,
outcome: (p.outcome as string) ?? null,
outcomeIndex: (p.outcomeIndex as number) ?? null,
oppositeOutcome: (p.oppositeOutcome as string) ?? null,
oppositeAsset: (p.oppositeAsset as string) ?? null,
endDate: (p.endDate as string) ?? null,
negativeRisk: (p.negativeRisk as boolean) ?? false,
}))
return {
success: true,
@@ -74,6 +174,36 @@ export const polymarketGetPositionsTool: ToolConfig<
positions: {
type: 'array',
description: 'Array of position objects',
items: {
type: 'object',
properties: {
proxyWallet: { type: 'string', description: 'Proxy wallet address' },
asset: { type: 'string', description: 'Asset token ID' },
conditionId: { type: 'string', description: 'Condition ID' },
size: { type: 'number', description: 'Position size' },
avgPrice: { type: 'number', description: 'Average price' },
initialValue: { type: 'number', description: 'Initial value' },
currentValue: { type: 'number', description: 'Current value' },
cashPnl: { type: 'number', description: 'Cash profit/loss' },
percentPnl: { type: 'number', description: 'Percent profit/loss' },
totalBought: { type: 'number', description: 'Total bought' },
realizedPnl: { type: 'number', description: 'Realized profit/loss' },
percentRealizedPnl: { type: 'number', description: 'Percent realized profit/loss' },
curPrice: { type: 'number', description: 'Current price' },
redeemable: { type: 'boolean', description: 'Whether position is redeemable' },
mergeable: { type: 'boolean', description: 'Whether position is mergeable' },
title: { type: 'string', description: 'Market title' },
slug: { type: 'string', description: 'Market slug' },
icon: { type: 'string', description: 'Market icon URL' },
eventSlug: { type: 'string', description: 'Event slug' },
outcome: { type: 'string', description: 'Outcome name' },
outcomeIndex: { type: 'number', description: 'Outcome index' },
oppositeOutcome: { type: 'string', description: 'Opposite outcome name' },
oppositeAsset: { type: 'string', description: 'Opposite asset token ID' },
endDate: { type: 'string', description: 'End date' },
negativeRisk: { type: 'boolean', description: 'Whether negative risk' },
},
},
},
},
}

View File

@@ -99,7 +99,14 @@ export const polymarketGetPriceHistoryTool: ToolConfig<
outputs: {
history: {
type: 'array',
description: 'Array of price history entries with timestamp (t) and price (p)',
description: 'Array of price history entries',
items: {
type: 'object',
properties: {
t: { type: 'number', description: 'Unix timestamp' },
p: { type: 'number', description: 'Price at timestamp' },
},
},
},
},
}

View File

@@ -97,6 +97,26 @@ export const polymarketGetSeriesTool: ToolConfig<
series: {
type: 'array',
description: 'Array of series objects',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Series ID' },
ticker: { type: 'string', description: 'Series ticker' },
slug: { type: 'string', description: 'Series slug' },
title: { type: 'string', description: 'Series title' },
seriesType: { type: 'string', description: 'Series type' },
recurrence: { type: 'string', description: 'Recurrence pattern' },
image: { type: 'string', description: 'Series image URL' },
icon: { type: 'string', description: 'Series icon URL' },
active: { type: 'boolean', description: 'Whether series is active' },
closed: { type: 'boolean', description: 'Whether series is closed' },
archived: { type: 'boolean', description: 'Whether series is archived' },
featured: { type: 'boolean', description: 'Whether series is featured' },
volume: { type: 'number', description: 'Total volume' },
liquidity: { type: 'number', description: 'Total liquidity' },
eventCount: { type: 'number', description: 'Number of events in series' },
},
},
},
},
}

View File

@@ -58,6 +58,25 @@ export const polymarketGetSeriesByIdTool: ToolConfig<
series: {
type: 'object',
description: 'Series object with details',
properties: {
id: { type: 'string', description: 'Series ID' },
ticker: { type: 'string', description: 'Series ticker' },
slug: { type: 'string', description: 'Series slug' },
title: { type: 'string', description: 'Series title' },
seriesType: { type: 'string', description: 'Series type' },
recurrence: { type: 'string', description: 'Recurrence pattern' },
image: { type: 'string', description: 'Series image URL' },
icon: { type: 'string', description: 'Series icon URL' },
active: { type: 'boolean', description: 'Whether series is active' },
closed: { type: 'boolean', description: 'Whether series is closed' },
archived: { type: 'boolean', description: 'Whether series is archived' },
featured: { type: 'boolean', description: 'Whether series is featured' },
volume: { type: 'number', description: 'Total volume' },
liquidity: { type: 'number', description: 'Total liquidity' },
commentCount: { type: 'number', description: 'Comment count' },
eventCount: { type: 'number', description: 'Number of events in series' },
events: { type: 'array', description: 'Array of events in this series' },
},
},
},
}

View File

@@ -53,7 +53,9 @@ export const polymarketGetSpreadTool: ToolConfig<
return {
success: true,
output: {
spread: data,
spread: {
spread: data.spread ?? '',
},
},
}
},
@@ -61,7 +63,10 @@ export const polymarketGetSpreadTool: ToolConfig<
outputs: {
spread: {
type: 'object',
description: 'Bid-ask spread with bid and ask prices',
description: 'Spread value between bid and ask',
properties: {
spread: { type: 'string', description: 'The spread value' },
},
},
},
}

View File

@@ -71,7 +71,17 @@ export const polymarketGetTagsTool: ToolConfig<PolymarketGetTagsParams, Polymark
outputs: {
tags: {
type: 'array',
description: 'Array of tag objects with id, label, and slug',
description: 'Array of tag objects',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Tag ID' },
label: { type: 'string', description: 'Tag label' },
slug: { type: 'string', description: 'Tag slug' },
createdAt: { type: 'string', description: 'Creation timestamp' },
updatedAt: { type: 'string', description: 'Last update timestamp' },
},
},
},
},
}

View File

@@ -1,10 +1,17 @@
import type { ToolConfig } from '@/tools/types'
import type { PolymarketPaginationParams, PolymarketTrade } from './types'
import type { PolymarketTrade } from './types'
import { buildDataUrl, handlePolymarketError } from './types'
export interface PolymarketGetTradesParams extends PolymarketPaginationParams {
user?: string // Optional user wallet address
market?: string // Optional market filter
export interface PolymarketGetTradesParams {
user?: string
market?: string
eventId?: string
side?: string
takerOnly?: string
filterType?: string
filterAmount?: string
limit?: string
offset?: string
}
export interface PolymarketGetTradesResponse {
@@ -33,13 +40,43 @@ export const polymarketGetTradesTool: ToolConfig<
market: {
type: 'string',
required: false,
description: 'Market ID to filter trades',
description: 'Market/condition ID to filter trades (mutually exclusive with eventId)',
visibility: 'user-or-llm',
},
eventId: {
type: 'string',
required: false,
description: 'Event ID to filter trades (mutually exclusive with market)',
visibility: 'user-or-llm',
},
side: {
type: 'string',
required: false,
description: 'Trade direction filter (BUY or SELL)',
visibility: 'user-or-llm',
},
takerOnly: {
type: 'string',
required: false,
description: 'Filter for taker trades only (true/false, default: true)',
visibility: 'user-or-llm',
},
filterType: {
type: 'string',
required: false,
description: 'Filter type (CASH or TOKENS) - requires filterAmount',
visibility: 'user-or-llm',
},
filterAmount: {
type: 'string',
required: false,
description: 'Filter amount threshold - requires filterType',
visibility: 'user-or-llm',
},
limit: {
type: 'string',
required: false,
description: 'Number of results per page (max 50)',
description: 'Number of results per page (default: 100, max: 10000)',
visibility: 'user-or-llm',
},
offset: {
@@ -55,13 +92,16 @@ export const polymarketGetTradesTool: ToolConfig<
const queryParams = new URLSearchParams()
if (params.user) queryParams.append('user', params.user)
if (params.market) queryParams.append('market', params.market)
// Default limit to 50 to prevent browser crashes from large data sets
queryParams.append('limit', params.limit || '50')
if (params.eventId) queryParams.append('eventId', params.eventId)
if (params.side) queryParams.append('side', params.side.toUpperCase())
if (params.takerOnly) queryParams.append('takerOnly', params.takerOnly)
if (params.filterType) queryParams.append('filterType', params.filterType.toUpperCase())
if (params.filterAmount) queryParams.append('filterAmount', params.filterAmount)
if (params.limit) queryParams.append('limit', params.limit)
if (params.offset) queryParams.append('offset', params.offset)
const query = queryParams.toString()
const url = buildDataUrl('/trades')
return `${url}?${query}`
return `${url}?${queryParams.toString()}`
},
method: 'GET',
headers: () => ({
@@ -76,8 +116,28 @@ export const polymarketGetTradesTool: ToolConfig<
handlePolymarketError(data, response.status, 'get_trades')
}
// Response is an array of trades
const trades = Array.isArray(data) ? data : []
const rawTrades = Array.isArray(data) ? data : []
const trades: PolymarketTrade[] = rawTrades.map((t: Record<string, unknown>) => ({
proxyWallet: (t.proxyWallet as string) ?? null,
side: (t.side as string) ?? '',
asset: (t.asset as string) ?? '',
conditionId: (t.conditionId as string) ?? '',
size: (t.size as number) ?? 0,
price: (t.price as number) ?? 0,
timestamp: (t.timestamp as number) ?? 0,
title: (t.title as string) ?? null,
slug: (t.slug as string) ?? null,
icon: (t.icon as string) ?? null,
eventSlug: (t.eventSlug as string) ?? null,
outcome: (t.outcome as string) ?? null,
outcomeIndex: (t.outcomeIndex as number) ?? null,
name: (t.name as string) ?? null,
pseudonym: (t.pseudonym as string) ?? null,
bio: (t.bio as string) ?? null,
profileImage: (t.profileImage as string) ?? null,
profileImageOptimized: (t.profileImageOptimized as string) ?? null,
transactionHash: (t.transactionHash as string) ?? null,
}))
return {
success: true,
@@ -91,6 +151,30 @@ export const polymarketGetTradesTool: ToolConfig<
trades: {
type: 'array',
description: 'Array of trade objects',
items: {
type: 'object',
properties: {
proxyWallet: { type: 'string', description: 'Proxy wallet address' },
side: { type: 'string', description: 'Trade side (BUY or SELL)' },
asset: { type: 'string', description: 'Asset token ID' },
conditionId: { type: 'string', description: 'Condition ID' },
size: { type: 'number', description: 'Trade size' },
price: { type: 'number', description: 'Trade price' },
timestamp: { type: 'number', description: 'Unix timestamp' },
title: { type: 'string', description: 'Market title' },
slug: { type: 'string', description: 'Market slug' },
icon: { type: 'string', description: 'Market icon URL' },
eventSlug: { type: 'string', description: 'Event slug' },
outcome: { type: 'string', description: 'Outcome name' },
outcomeIndex: { type: 'number', description: 'Outcome index' },
name: { type: 'string', description: 'Trader name' },
pseudonym: { type: 'string', description: 'Trader pseudonym' },
bio: { type: 'string', description: 'Trader bio' },
profileImage: { type: 'string', description: 'Profile image URL' },
profileImageOptimized: { type: 'string', description: 'Optimized profile image URL' },
transactionHash: { type: 'string', description: 'Transaction hash' },
},
},
},
},
}

View File

@@ -1,6 +1,9 @@
export * from './get_activity'
export * from './get_event'
export * from './get_events'
export * from './get_holders'
export * from './get_last_trade_price'
export * from './get_leaderboard'
export * from './get_market'
export * from './get_markets'
export * from './get_midpoint'

View File

@@ -1,9 +1,22 @@
import type { ToolConfig } from '@/tools/types'
import type { PolymarketPaginationParams, PolymarketSearchResult } from './types'
import type { PolymarketSearchResult } from './types'
import { buildGammaUrl, handlePolymarketError } from './types'
export interface PolymarketSearchParams extends PolymarketPaginationParams {
query: string // Search term (required)
export interface PolymarketSearchParams {
query: string
limit?: string
page?: string
cache?: string
eventsStatus?: string
limitPerType?: string
eventsTag?: string
sort?: string
ascending?: string
searchTags?: string
searchProfiles?: string
recurrence?: string
excludeTagId?: string
keepClosedMarkets?: string
}
export interface PolymarketSearchResponse {
@@ -32,10 +45,76 @@ export const polymarketSearchTool: ToolConfig<PolymarketSearchParams, Polymarket
description: 'Number of results per page (max 50)',
visibility: 'user-or-llm',
},
offset: {
page: {
type: 'string',
required: false,
description: 'Pagination offset',
description: 'Page number for pagination (1-indexed)',
visibility: 'user-or-llm',
},
cache: {
type: 'string',
required: false,
description: 'Enable caching (true/false)',
visibility: 'user-or-llm',
},
eventsStatus: {
type: 'string',
required: false,
description: 'Filter events by status',
visibility: 'user-or-llm',
},
limitPerType: {
type: 'string',
required: false,
description: 'Limit results per type (markets, events, profiles)',
visibility: 'user-or-llm',
},
eventsTag: {
type: 'string',
required: false,
description: 'Filter by event tags (comma-separated)',
visibility: 'user-or-llm',
},
sort: {
type: 'string',
required: false,
description: 'Sort field',
visibility: 'user-or-llm',
},
ascending: {
type: 'string',
required: false,
description: 'Sort direction (true for ascending, false for descending)',
visibility: 'user-or-llm',
},
searchTags: {
type: 'string',
required: false,
description: 'Include tags in search results (true/false)',
visibility: 'user-or-llm',
},
searchProfiles: {
type: 'string',
required: false,
description: 'Include profiles in search results (true/false)',
visibility: 'user-or-llm',
},
recurrence: {
type: 'string',
required: false,
description: 'Filter by recurrence type',
visibility: 'user-or-llm',
},
excludeTagId: {
type: 'string',
required: false,
description: 'Exclude events with these tag IDs (comma-separated)',
visibility: 'user-or-llm',
},
keepClosedMarkets: {
type: 'string',
required: false,
description: 'Include closed markets in results (0 or 1)',
visibility: 'user-or-llm',
},
},
@@ -44,9 +123,20 @@ export const polymarketSearchTool: ToolConfig<PolymarketSearchParams, Polymarket
url: (params) => {
const queryParams = new URLSearchParams()
queryParams.append('q', params.query)
// Default limit to 50 to prevent browser crashes from large data sets
queryParams.append('limit', params.limit || '50')
if (params.offset) queryParams.append('offset', params.offset)
if (params.page) queryParams.append('page', params.page)
if (params.cache) queryParams.append('cache', params.cache)
if (params.eventsStatus) queryParams.append('events_status', params.eventsStatus)
if (params.limitPerType) queryParams.append('limit_per_type', params.limitPerType)
if (params.eventsTag) queryParams.append('events_tag', params.eventsTag)
if (params.sort) queryParams.append('sort', params.sort)
if (params.ascending) queryParams.append('ascending', params.ascending)
if (params.searchTags) queryParams.append('search_tags', params.searchTags)
if (params.searchProfiles) queryParams.append('search_profiles', params.searchProfiles)
if (params.recurrence) queryParams.append('recurrence', params.recurrence)
if (params.excludeTagId) queryParams.append('exclude_tag_id', params.excludeTagId)
if (params.keepClosedMarkets)
queryParams.append('keep_closed_markets', params.keepClosedMarkets)
return `${buildGammaUrl('/public-search')}?${queryParams.toString()}`
},
@@ -63,11 +153,11 @@ export const polymarketSearchTool: ToolConfig<PolymarketSearchParams, Polymarket
handlePolymarketError(data, response.status, 'search')
}
// Response contains markets, events, and profiles arrays
const results: PolymarketSearchResult = {
markets: data.markets || [],
events: data.events || [],
profiles: data.profiles || [],
markets: data.markets ?? [],
events: data.events ?? [],
tags: data.tags ?? [],
profiles: data.profiles ?? [],
}
return {
@@ -81,7 +171,13 @@ export const polymarketSearchTool: ToolConfig<PolymarketSearchParams, Polymarket
outputs: {
results: {
type: 'object',
description: 'Search results containing markets, events, and profiles arrays',
description: 'Search results containing markets, events, tags, and profiles arrays',
properties: {
markets: { type: 'array', description: 'Array of matching market objects' },
events: { type: 'array', description: 'Array of matching event objects' },
tags: { type: 'array', description: 'Array of matching tag objects' },
profiles: { type: 'array', description: 'Array of matching profile objects' },
},
},
},
}

View File

@@ -92,6 +92,11 @@ export interface PolymarketTag {
id: string
label: string
slug: string
createdAt?: string
updatedAt?: string
forceShow?: boolean
forceHide?: boolean
isCarousel?: boolean
}
export interface PolymarketOrderBookEntry {
@@ -106,11 +111,13 @@ export interface PolymarketOrderBook {
timestamp: string
bids: PolymarketOrderBookEntry[]
asks: PolymarketOrderBookEntry[]
min_order_size: string
tick_size: string
neg_risk: boolean
}
export interface PolymarketPrice {
price: string
side: string
}
export interface PolymarketPriceHistoryEntry {
@@ -143,31 +150,125 @@ export interface PolymarketSeries {
export interface PolymarketSearchResult {
markets: PolymarketMarket[]
events: PolymarketEvent[]
profiles: any[]
tags: PolymarketTag[]
profiles: PolymarketProfile[]
}
export interface PolymarketProfile {
id: string
name: string | null
pseudonym: string | null
bio: string | null
profileImage: string | null
profileImageOptimized: string | null
walletAddress: string
}
export interface PolymarketSpread {
bid: string
ask: string
spread: string
}
export interface PolymarketPosition {
market: string
asset_id: string
size: string
value: string
proxyWallet: string | null
asset: string
conditionId: string
size: number
avgPrice: number
initialValue: number
currentValue: number
cashPnl: number
percentPnl: number
totalBought: number
realizedPnl: number
percentRealizedPnl: number
curPrice: number
redeemable: boolean
mergeable: boolean
title: string | null
slug: string | null
icon: string | null
eventSlug: string | null
outcome: string | null
outcomeIndex: number | null
oppositeOutcome: string | null
oppositeAsset: string | null
endDate: string | null
negativeRisk: boolean
}
export interface PolymarketTrade {
id: string
market: string
asset_id: string
proxyWallet: string | null
side: string
size: string
price: string
timestamp: string
maker: string
taker: string
asset: string
conditionId: string
size: number
price: number
timestamp: number
title: string | null
slug: string | null
icon: string | null
eventSlug: string | null
outcome: string | null
outcomeIndex: number | null
name: string | null
pseudonym: string | null
bio: string | null
profileImage: string | null
profileImageOptimized: string | null
transactionHash: string | null
}
export interface PolymarketActivity {
proxyWallet: string | null
timestamp: number
conditionId: string
type: string
size: number
usdcSize: number
transactionHash: string | null
price: number | null
asset: string | null
side: string | null
outcomeIndex: number | null
title: string | null
slug: string | null
icon: string | null
eventSlug: string | null
outcome: string | null
name: string | null
pseudonym: string | null
bio: string | null
profileImage: string | null
profileImageOptimized: string | null
}
export interface PolymarketLeaderboardEntry {
rank: string
proxyWallet: string
userName: string | null
vol: number
pnl: number
profileImage: string | null
xUsername: string | null
verifiedBadge: boolean
}
export interface PolymarketHolder {
proxyWallet: string
bio: string | null
asset: string
pseudonym: string | null
amount: number
displayUsernamePublic: boolean
outcomeIndex: number
name: string | null
profileImage: string | null
profileImageOptimized: string | null
}
export interface PolymarketMarketHolders {
token: string
holders: PolymarketHolder[]
}
export function handlePolymarketError(data: any, status: number, operation: string): never {

View File

@@ -746,22 +746,39 @@ import {
} from '@/tools/jsm'
import {
kalshiAmendOrderTool,
kalshiAmendOrderV2Tool,
kalshiCancelOrderTool,
kalshiCancelOrderV2Tool,
kalshiCreateOrderTool,
kalshiCreateOrderV2Tool,
kalshiGetBalanceTool,
kalshiGetBalanceV2Tool,
kalshiGetCandlesticksTool,
kalshiGetCandlesticksV2Tool,
kalshiGetEventsTool,
kalshiGetEventsV2Tool,
kalshiGetEventTool,
kalshiGetEventV2Tool,
kalshiGetExchangeStatusTool,
kalshiGetExchangeStatusV2Tool,
kalshiGetFillsTool,
kalshiGetFillsV2Tool,
kalshiGetMarketsTool,
kalshiGetMarketsV2Tool,
kalshiGetMarketTool,
kalshiGetMarketV2Tool,
kalshiGetOrderbookTool,
kalshiGetOrderbookV2Tool,
kalshiGetOrdersTool,
kalshiGetOrdersV2Tool,
kalshiGetOrderTool,
kalshiGetOrderV2Tool,
kalshiGetPositionsTool,
kalshiGetPositionsV2Tool,
kalshiGetSeriesByTickerTool,
kalshiGetSeriesByTickerV2Tool,
kalshiGetTradesTool,
kalshiGetTradesV2Tool,
} from '@/tools/kalshi'
import {
knowledgeCreateDocumentTool,
@@ -1072,9 +1089,12 @@ import {
pipedriveUpdateLeadTool,
} from '@/tools/pipedrive'
import {
polymarketGetActivityTool,
polymarketGetEventsTool,
polymarketGetEventTool,
polymarketGetHoldersTool,
polymarketGetLastTradePriceTool,
polymarketGetLeaderboardTool,
polymarketGetMarketsTool,
polymarketGetMarketTool,
polymarketGetMidpointTool,
@@ -1815,22 +1835,39 @@ export const tools: Record<string, ToolConfig> = {
jsm_get_approvals: jsmGetApprovalsTool,
jsm_answer_approval: jsmAnswerApprovalTool,
kalshi_get_markets: kalshiGetMarketsTool,
kalshi_get_markets_v2: kalshiGetMarketsV2Tool,
kalshi_get_market: kalshiGetMarketTool,
kalshi_get_market_v2: kalshiGetMarketV2Tool,
kalshi_get_events: kalshiGetEventsTool,
kalshi_get_events_v2: kalshiGetEventsV2Tool,
kalshi_get_event: kalshiGetEventTool,
kalshi_get_event_v2: kalshiGetEventV2Tool,
kalshi_get_balance: kalshiGetBalanceTool,
kalshi_get_balance_v2: kalshiGetBalanceV2Tool,
kalshi_get_positions: kalshiGetPositionsTool,
kalshi_get_positions_v2: kalshiGetPositionsV2Tool,
kalshi_get_orders: kalshiGetOrdersTool,
kalshi_get_orders_v2: kalshiGetOrdersV2Tool,
kalshi_get_order: kalshiGetOrderTool,
kalshi_get_order_v2: kalshiGetOrderV2Tool,
kalshi_get_orderbook: kalshiGetOrderbookTool,
kalshi_get_orderbook_v2: kalshiGetOrderbookV2Tool,
kalshi_get_trades: kalshiGetTradesTool,
kalshi_get_trades_v2: kalshiGetTradesV2Tool,
kalshi_get_candlesticks: kalshiGetCandlesticksTool,
kalshi_get_candlesticks_v2: kalshiGetCandlesticksV2Tool,
kalshi_get_fills: kalshiGetFillsTool,
kalshi_get_fills_v2: kalshiGetFillsV2Tool,
kalshi_get_series_by_ticker: kalshiGetSeriesByTickerTool,
kalshi_get_series_by_ticker_v2: kalshiGetSeriesByTickerV2Tool,
kalshi_get_exchange_status: kalshiGetExchangeStatusTool,
kalshi_get_exchange_status_v2: kalshiGetExchangeStatusV2Tool,
kalshi_create_order: kalshiCreateOrderTool,
kalshi_create_order_v2: kalshiCreateOrderV2Tool,
kalshi_cancel_order: kalshiCancelOrderTool,
kalshi_cancel_order_v2: kalshiCancelOrderV2Tool,
kalshi_amend_order: kalshiAmendOrderTool,
kalshi_amend_order_v2: kalshiAmendOrderV2Tool,
polymarket_get_markets: polymarketGetMarketsTool,
polymarket_get_market: polymarketGetMarketTool,
polymarket_get_events: polymarketGetEventsTool,
@@ -1848,6 +1885,9 @@ export const tools: Record<string, ToolConfig> = {
polymarket_get_tick_size: polymarketGetTickSizeTool,
polymarket_get_positions: polymarketGetPositionsTool,
polymarket_get_trades: polymarketGetTradesTool,
polymarket_get_activity: polymarketGetActivityTool,
polymarket_get_leaderboard: polymarketGetLeaderboardTool,
polymarket_get_holders: polymarketGetHoldersTool,
slack_message: slackMessageTool,
slack_message_reader: slackMessageReaderTool,
slack_list_channels: slackListChannelsTool,