feat: add Kalshi support with grammar-based ticker parser (#19)#41
Merged
e35ventura merged 2 commits intoentrius:mainfrom Mar 13, 2026
Merged
Conversation
Implements issue entrius#19 — Synth Overlay now works on Kalshi pages. Architecture: - Grammar-based Kalshi ticker parser: derives asset and market type from ticker structure (KX + asset_code + suffix), not lookup tables. Adding a new Kalshi asset = 1 entry in _KX_CODES. - Rule-chain Polymarket inference: ordered (matcher, type) tuples replace if/else chains. - Config-driven platform definitions: data dicts, not classes. - Structured ResolveResult with typed error codes for actionable API error responses. - /api/platforms introspection endpoint. - platforms.js: centralized JS platform config. Extension changes: - content.js: Kalshi price scraper (3-pass: trading panel, fallback DOM, order book pattern), slug extraction, context invalidation. - background.js: platform-aware notifications and watchlist polling. - sidepanel.js/html: dynamic Kalshi/Poly labels, suggested markets. - alerts.js: watchlist stores platform field. - manifest.json: Kalshi permissions. Tests: 213 passing (74 matcher + 139 server).
7f4a5f4 to
8cbd185
Compare
Closed
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add Kalshi support to the Synth Overlay Chrome extension. Traders browsing Kalshi markets now see the same edge analysis, confidence scoring, and signal data they get on Polymarket — the side panel activates automatically on
kalshi.com, matches the market to a Synth forecast, and displays the edge between Synth's probability and Kalshi's price.Key architectural decisions
Grammar-based Kalshi ticker parser — Instead of maintaining a 25+ entry series→asset lookup map and 3 separate series→type frozensets, Kalshi tickers are structurally decomposed using their grammar:
KX{asset_code}{market_suffix}-{date}-{strike}. Asset and market type are derived from the ticker structure, not looked up. Adding a new Kalshi asset requires 1 entry in_KX_CODES— no series sets to update.Rule-chain market type inference — Polymarket market type detection uses ordered
(matcher, type)tuples instead of if/else chains. Rules are declarative data, not control flow.Config-driven platform definitions — Each platform is a data dict with domain, URL patterns, detection heuristics, and resolution strategy. A generic engine processes any config. Adding a third platform = adding a config entry + a resolver function — zero changes to existing platform code.
Structured
ResolveResult— Theresolve()pipeline returns typed error codes (invalid_input,unknown_platform,unsupported_market,normalize_failed) so the server produces actionable 400/404 responses instead of generic error strings. New/api/platformsendpoint provides runtime introspection of registered platforms, supported assets, and market types.Centralized JS platform config (
platforms.js) — Single source of truth for platform origins, labels, URL templates, and tab search patterns. All extension scripts reference this instead of hard-coding platform strings.Files changed
matcher.pyResolveResultdataclass,PlatformRegistryserver.py/api/platformsintrospection endpoint,registry.resolve()integrationextension/content.jsslugFromKalshi()(last-segment extraction), 3-pass Kalshi price scraper (trading panel → fallback DOM → order book pattern),scanKalshiMarketLinks()for browse pages, context invalidation guardsextension/background.jsisSupportedUrl()viaSynthPlatforms, watchlist polling passes&platform=param, notification click opens correct platform URL from stored platform fieldextension/sidepanel.jsfetchEdge()sends platform param, suggested market buttons on Kalshi browse pagesextension/sidepanel.htmlplatforms.jsscript importextension/alerts.jsplatformfield,addToWatchlist()accepts platform,formatMarketLabel()is platform-awareextension/manifest.jsonkalshi.comand*.kalshi.cominhost_permissionsandcontent_scripts.matches, version bump to 1.4.0extension/platforms.jstests/test_matcher.pyResolveResultstructured errors, registry introspection, custom platform registrationtests/test_server.py/api/platformsendpoint, structured error codes, unknown platform handlingREADME.mdKalshi price scraping strategy
The content script uses a multi-strategy approach to scrape live Yes/No prices from Kalshi's DOM:
"Best Yes: $0.52"/"Best Yes: 52¢"patterns.1 - found.Grammar parser example
Adding a new asset (e.g. LINK) →
_KX_CODES["link"] = "LINK"→kxlinkd,kxlink,kxlink15mall auto-work.Related Issues
Fixes #19
Type of Change
Testing
213 tests passing (74 matcher + 139 server):
Test coverage includes:
ResolveResultstructured diagnostics (success, invalid input, unknown platform, unsupported market)PlatformRegistryintrospection and custom platform registration/api/platformsendpoint, structured error codes in 400/404 responsesChecklist
Demo Video
screen-capture_a5RZ2H7W.mp4