Skip to content

Implement prediction market SwapExecuted event pipeline (Slice 4)#13390

Merged
dillchen merged 4 commits intomasterfrom
ro/feature-13389-implement-prediction-market-swapexecuted
Feb 14, 2026
Merged

Implement prediction market SwapExecuted event pipeline (Slice 4)#13390
dillchen merged 4 commits intomasterfrom
ro/feature-13389-implement-prediction-market-swapexecuted

Conversation

@Rotorsoft
Copy link
Contributor

Summary

  • Implement the complete EVM event pipeline for prediction market SwapExecuted (FutarchyRouter) and TokensMinted (BinaryVault) events — including event signatures, ABI-based log mappers, and projection handlers that record trades, update user positions, and track market probability
  • Add binaryVaultSource and futarchyRouterSource contract source exports for runtime-deployed per-market contracts, with mappers registered in chainEventMappers keyed by event signature
  • All projection mutations are wrapped in Sequelize transactions with idempotency enforced via composite PK (eth_chain_id, transaction_hash) on PredictionMarketTrade

Test Plan

  • Verify event signature hashes match keccak256 of Solidity signatures for TokensMinted and SwapExecuted
  • Run mint projection tests: trade creation, position upsert, total_collateral accumulation, idempotency, multi-user isolation, graceful skip on missing market (prediction-market-mint.spec.ts)
  • Run swap projection tests: buy_pass=true vs false produce correct action enum and position deltas, probability updates, accumulation across swaps, idempotency, graceful skip on missing market (prediction-market-swap.spec.ts)
  • Run pnpm -r check-types to verify type safety across all packages
  • Run pnpm lint-branch-warnings for clean lint

Closes #13389


Created with Claude by gent

rotorsoft and others added 2 commits February 13, 2026 13:21
Add the EVM event pipeline for prediction market mint operations:
- Register TokensMinted event signature in eventSignatures.ts
- Export BinaryVault contract source with ABI from @commonxyz/common-protocol-abis
- Add predictionMarketTokensMintedMapper to decode raw EVM logs
- Extend PredictionMarketProjection with TokensMinted handler that
  inserts trades, upserts positions, and increments market total_collateral
- All DB mutations wrapped in a single Sequelize transaction
- Idempotent: duplicate events (same tx hash) skip position/market updates
- Add unit tests for mapper, projection handler, idempotency, and multi-user

Completed GitHub issue #13387

Co-Authored-By: Claude <noreply@anthropic.com>
Completed GitHub issue #13389

Co-Authored-By: Claude <noreply@anthropic.com>
@Rotorsoft
Copy link
Contributor Author

fix: gate prediction market projection behind feature flag

Conditionally register PredictionMarketProjection in rascalConsumerMap
only when FLAG_FUTARCHY is enabled, preventing event consumption when
the feature is disabled.

Completed GitHub issue #13389

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@egetekiner egetekiner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All changes looks good to me, signatures matching and looks like all important events hve been covered.

@dillchen dillchen merged commit 4e8ac11 into master Feb 14, 2026
8 checks passed
rbentcw added a commit that referenced this pull request Feb 23, 2026
* Add prediction market schemas, Sequelize models, and database migration behind FLAG_FUTARCHY (#13369)

* feat: add prediction market foundation

Completed GitHub issue #13361

Co-Authored-By: Codex <noreply@openai.com>

* fix: association to user

* fix: tests

---------

Co-authored-by: rotorsoft <rotorsoft@outlook.com>
Co-authored-by: Codex <noreply@openai.com>

* Implement prediction market deploy flow, policy, and read model (slice 2) (#13372)

* feat: implement prediction market deploy flow, policy, and read model

Implement slice 2 of the prediction market plan:
- CreatePredictionMarket command: creates draft market with thread author auth,
  validates no existing market on thread, loads eth_chain_id from ChainNode
- DeployPredictionMarket command: transitions draft to active, sets contract
  addresses and times, emits PredictionMarketDeployed event
- ProjectPredictionMarketProposal/Market commands: reconcile on-chain IDs
- PredictionMarketPolicy: consumes ProposalCreated/MarketCreated events and
  dispatches projection commands via systemActor
- PredictionMarket.projection: read model event handler (mirrors write model)
- Lifecycle test: covers create -> deploy -> policy reconciliation end-to-end
- Schema test fixes: added thread_id to command fixtures

Completed GitHub issue #13370

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: wire prediction market commands to internal router behind FLAG_FUTARCHY

- Remove unused PredictionMarket.projection (policy handles projecting chain events)
- Add GetPredictionMarkets query with paginated raw SQL
- Create predictionMarket tRPC router with create/deploy/get endpoints
- Register router in internal-router behind config.MARKETS.FUTARCHY_ENABLED
- Register PredictionMarketPolicy in rascalConsumerMap for event consumption
- Add PredictionMarket tag to tRPC Tag enum

Completed GitHub issue #13370

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: rotorsoft <rotorsoft@outlook.com>
Co-authored-by: Claude <noreply@anthropic.com>

* Improve performance of thread/comment search (#13357)

* improve trcp request size

* add search index for threads + comments

* min 3 chars

* remove redundant migration + improve query

* Enforce policy vs projection architecture rule and fix misclassified files (#13381)

* refactor: enforce policy vs projection architecture rule and fix misclassified files

Reclassify 5 misclassified policies as projections:
- CreateUnverifiedUser → aggregates/user/
- Governance → aggregates/chain-events/
- Nominations → aggregates/community/
- ReactionWorker → aggregates/reaction/
- UpgradeTier → aggregates/user/ (rename only)

Split hybrid files:
- ChainEventCreated.policy: extract DB-mutating handlers into ChainEventCreated.projection
- FarcasterWorker.policy: extract FarcasterReplyCastDeleted into FarcasterContest.projection

Eliminate Project... command indirection:
- PredictionMarket.policy → PredictionMarket.projection (inline logic)
- ProjectLaunchpadTrade.command → LaunchpadTrade.projection
- Remove ProjectPredictionMarketProposal/Market commands and schemas

Update consumer registrations, barrel exports, test imports, and docs.

Completed GitHub issue #13379

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: relocate projection handlers from policies/ to aggregates/

Move handleCommunityStakeTrades and handleReferralFeeDistributed from
policies/handlers/ to aggregates/community/handlers/ where their
projection consumers live. Move chainNodeMustExist utility from
policies/utils/utils to the shared utils/utils module.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: rename projection helpers to projections/project* convention

Rename handlers/handle* to projections/project* for projection helper
files, aligning the naming convention with the projection architecture.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: break circular dependency in model utils by extracting chainNodeMustExist

Moving chainNodeMustExist to utils/utils.ts created a circular import:
database.ts → models/ → models/thread.ts → utils/utils.ts → database.ts

Extracted chainNodeMustExist into its own utils/chainNodeUtils.ts module,
which is only imported by projection files (not model files), breaking
the cycle. Also fixes checkIconSize test import.

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: remove agent file

---------

Co-authored-by: rotorsoft <rotorsoft@outlook.com>
Co-authored-by: Claude <noreply@anthropic.com>

* init gent (#13295)

* init gent

* update gent config

---------

Co-authored-by: rotorsoft <rotorsoft@outlook.com>
Co-authored-by: Dillon Chen <5334557+dillchen@users.noreply.github.com>

* updated abis (#13384)

* Auto-cleanup deprecated RabbitMQ queues from removed subscriptions on broker init (#13383)

* feat: auto-cleanup deprecated RabbitMQ queues on broker init

Add cleanupDeprecatedQueues method to RabbitMQAdapter that uses the
RabbitMQ Management HTTP API to discover orphaned queues. Empty
deprecated queues are deleted; non-empty ones trigger a warning log.
Only targets queues matching the *Queue naming convention to avoid
touching system queues. Cleanup runs after broker init in
bootstrapBindings, guarded by CLEANUP_DEPRECATED_QUEUES (default true)
and RABBITMQ_MANAGEMENT_URL config flags. For local dev, the management
URL is auto-derived from the AMQP URI (localhost:15672, guest:guest).

Also sorts rascalConsumerMap entries alphabetically by consumer name.

Completed GitHub issue #13382

Co-Authored-By: Claude <noreply@anthropic.com>

* fix map

---------

Co-authored-by: rotorsoft <rotorsoft@outlook.com>
Co-authored-by: Claude <noreply@anthropic.com>

* docs: update prediction markets plan for projection architecture and ABI events (#13386)

- Replace all PredictionMarketPolicy references with PredictionMarketProjection
- Remove ProjectPredictionMarketTrade/Resolution command indirection pattern
- Update PM-4 to import ABIs from @commonxyz/common-protocol-abis (no local files)
- Mark PM-1 and PM-2 (Slices 1+2) as completed
- Add complete EVM event-to-mapper-to-projection mapping table with all 8 ABI signatures
- Update all diagrams to show projection-based flow (no policy/system command boxes)
- Update dependency graph to reflect current progress

Completed GitHub issue #13385

Co-authored-by: rotorsoft <rotorsoft@outlook.com>
Co-authored-by: Claude <noreply@anthropic.com>

* docs: expand frontend touch points with all integration surfaces (#13380)

* docs: expand frontend touch points with all integration surfaces

Appends 12 standalone frontend tickets (PM-7 through PM-18) with
inline ASCII wireframes for each surface:

- PM-7:  PredictionMarketCard (component hierarchy + card states)
- PM-8:  Thread View (sidebar card wireframe)
- PM-9:  Editor Modal (creation form + NewThreadForm integration)
- PM-10: Trade Modal (all 4 tabs + frontend-to-chain data flow)
- PM-11: Resolve Modal (TWAP resolution wireframe)
- PM-12: Explore Page (tab bar + AllTabContent + filtered list)
- PM-13: Homepages (horizontal scroll section wireframe)
- PM-14: Sidebar + Admin (nav layout + app page with 3 tabs)
- PM-15: Thread Badge (feed tag + hover popover)
- PM-16: Routing (4 routes)
- PM-17: Feature Flag + Community Setting
- PM-18: Testing + QA

Each ticket maps to an existing pattern (ActiveContestList,
MarketsList, ThreadPollCard, ThreadContestTag, etc.) with
inline code snippets and ASCII wireframes showing exactly
what the surface looks like. PM-8 through PM-15 parallelizable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add testing & integration tickets PM-19 through PM-25

Expands the prediction markets spec with 7 detailed testing tickets
covering unit tests (schemas, models, commands, queries), integration
tests (API routes, chain events pipeline), devnet tests (Anvil
on-chain lifecycle), frontend utility tests, and E2E browser
automation (Playwright). Includes ~146 test cases across 18 test
files with setup patterns, test tables, ASCII diagrams, dependency
graph, and coverage matrix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat: implement prediction market TokensMinted event pipeline (#13388)

Add the EVM event pipeline for prediction market mint operations:
- Register TokensMinted event signature in eventSignatures.ts
- Export BinaryVault contract source with ABI from @commonxyz/common-protocol-abis
- Add predictionMarketTokensMintedMapper to decode raw EVM logs
- Extend PredictionMarketProjection with TokensMinted handler that
  inserts trades, upserts positions, and increments market total_collateral
- All DB mutations wrapped in a single Sequelize transaction
- Idempotent: duplicate events (same tx hash) skip position/market updates
- Add unit tests for mapper, projection handler, idempotency, and multi-user

Completed GitHub issue #13387

Co-authored-by: rotorsoft <rotorsoft@outlook.com>
Co-authored-by: Claude <noreply@anthropic.com>

* Implement prediction market SwapExecuted event pipeline (Slice 4) (#13390)

* feat: implement prediction market TokensMinted event pipeline

Add the EVM event pipeline for prediction market mint operations:
- Register TokensMinted event signature in eventSignatures.ts
- Export BinaryVault contract source with ABI from @commonxyz/common-protocol-abis
- Add predictionMarketTokensMintedMapper to decode raw EVM logs
- Extend PredictionMarketProjection with TokensMinted handler that
  inserts trades, upserts positions, and increments market total_collateral
- All DB mutations wrapped in a single Sequelize transaction
- Idempotent: duplicate events (same tx hash) skip position/market updates
- Add unit tests for mapper, projection handler, idempotency, and multi-user

Completed GitHub issue #13387

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: implement prediction market SwapExecuted event pipeline

Completed GitHub issue #13389

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: gate prediction market projection behind feature flag

Conditionally register PredictionMarketProjection in rascalConsumerMap
only when FLAG_FUTARCHY is enabled, preventing event consumption when
the feature is disabled.

Completed GitHub issue #13389

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: rotorsoft <rotorsoft@outlook.com>
Co-authored-by: Claude <noreply@anthropic.com>

* Add Playwright E2E + visual regression test infrastructure (#13314)

* Add Playwright E2E + visual regression test infrastructure

- Upgrade playwright.config.ts with baseURL, viewport, video, dual webServer
- Add E2E helpers: auth (mock getStatus), navigation, selectors, fixtures, API
- Add data-testid attributes to Layout, auth, nav, modal components
- Add E2E tests: home, auth-flow, community-browse, thread-lifecycle
- Add visual regression tests with toHaveScreenshot() for /components + key pages
- Add CI jobs for e2e-smoke and visual-regression in CI.yml
- Add .gitignore for test-results/ and visual-report/ output directories

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Remove visual snapshots from git, generate in CI instead

Baselines are platform-specific (darwin vs linux), so committing them
causes cross-platform mismatches. CI now runs test-visual:update to
generate fresh screenshots on every run and uploads them as artifacts
for human inspection.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Marcin Maslanka <maslankam92@gmail.com>

* Implement prediction market event pipelines for slices 5-8 (Merge, Resolution, Redemption, Cancellation) (#13393)

* feat: implement prediction market event pipelines for slices 5-8

Implement the remaining four core domain slices for the Futarchy
prediction market integration:

- Slice 5 (Merge): TokensMerged EVM event pipeline — mapper, projection
  handler that inserts trades, decrements position balances, decrements
  market total_collateral
- Slice 6 (Resolution): ProposalResolved + MarketResolved EVM events,
  ResolvePredictionMarket command with author/admin auth and active
  status validation
- Slice 7 (Redemption): TokensRedeemed EVM event pipeline — mapper maps
  outcome to winning token, projection decrements winning token balance
- Slice 8 (Cancellation): CancelPredictionMarket command with
  author/admin auth, validates draft or active status

Also adds GetPredictionMarketTrades and GetPredictionMarketPositions
query endpoints, and exposes all new commands/queries via tRPC router
behind FLAG_FUTARCHY.

Completed GitHub issue #13392

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: update plan

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: use string types for PG DECIMAL and DATE fields in prediction market query schemas

PostgreSQL returns DECIMAL(78,0) as strings and BigInt cannot be
JSON-serialized. Created View schemas that override PG_ETH fields with
z.string() for trade and position query outputs, matching the established
LaunchpadTradeView pattern. Documented the convention in CLAUDE.md.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: view schema

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: rotorsoft <rotorsoft@outlook.com>
Co-authored-by: Claude <noreply@anthropic.com>

* docs: update Phase 1 refactor test-hardening plan for automation-first execution (#13406)

* rotorsoft: prediction market fixes (router, output schemas, import, t… (#13409)

* rotorsoft: prediction market fixes (schemas, model, server, tests) - no client changes

- fix output schemas (command/query schemas)
- fix prediction market test type errors: query DB instead of using boolean command returns
- fix CreatePredictionMarket, DeployPredictionMarket, ResolvePredictionMarket commands
- fix internal-router prediction market wiring
- add prediction market editor validation unit test

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix test

---------

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fixed post token (#13410)

* optimize member search query (#13391)

* docs: refresh epic-2 refactor plan status and migration assumptions (#13423)

* fix broken form validations (#13183)

* Build prediction market editor modal with create and deploy flow (fixes #13374) (#13407)

* feat(prediction-markets): add prediction market editor modal (issue #13374)

- Add PredictionMarketEditorModal with form: prompt, collateral (USDC/WETH/custom),
  duration (1-90 days), resolution threshold (51-99%, default 55%), initial liquidity
- Add createPredictionMarket flow: draft creation via API, success/error handling
- Add ThreadPredictionMarketEditorCard, shown on view thread when futarchy flag on
- Wire modal from view thread page (Polls section) for thread authors
- Add useCreatePredictionMarketMutation, useDeployPredictionMarketMutation,
  useGetPredictionMarketsQuery (conditional predictionMarket router)
- Add predictionMarketEditorValidation and unit tests for form validation
- On-chain deploy (Governor.propose + deployPredictionMarket) left for follow-up

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix import

* fix output schemas

* fix prediction market test type errors: query DB instead of using boolean command returns

Commands return boolean but tests accessed properties like .id and .status on the result.
Fixed by querying PredictionMarket model after each command. Also removed references to
non-existent ProjectPredictionMarketTrade and ProjectPredictionMarketResolution schemas.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: router

* implemented contract flow

* fix ci

* added draft deployment resume logic and contract structural calls

* docs: test plan note on chainConfig address and status chip wording

Co-authored-by: Cursor <cursoragent@cursor.com>

* reordered comps

* use correct Futarchy contract + fixed community creation flow

* updated contract addresses

* updated contract

* fix contract signing flow

* removed extra doc

* fix ci

* fix ci

* fix ci

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: rotorsoft <rotorsoft@outlook.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat(frontend-refactor): implement EPIC 2.1-2.6 shared contracts and module migration (#13431)

* feat(epic-2.1): harden component test harness contracts

* feat(epic-2.2): add scoped shared/features aliases and scaffolding

* feat(epic-2.3): migrate shared reusable hooks with compatibility stubs

* feat(epic-2.4): migrate shared utility helpers with compatibility stubs

* feat(epic-2.5): move trpc client to shared api with stub

* feat(epic-2.6): rewire shared hook consumer imports

* fix(ci): resolve lint and cleanup guard failures

* fix(ci): narrow deprecated stub import guard matching

* fix(ci): scope circular guard to newly added import edges

* Allow leading 0 to be removed (#13424)

* Fixed post token

* fixed token widget

* minor fix

* Updated codeowners

* Fix ui issues (#13293)

* fix ui issues

* fix ci

* fix ci

* Bug Fixes (#13302)

* Hide Transactions tab when no token exists in community home

* Added horizontal rotating carousel for Recently Launched & Trending tokens

* fix ci

* fix sui signin auth (#13436)

---------

Co-authored-by: Roger Torres <41707007+Rotorsoft@users.noreply.github.com>
Co-authored-by: rotorsoft <rotorsoft@outlook.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: rbentcw <126922418+rbentcw@users.noreply.github.com>
Co-authored-by: Dillon Chen <5334557+dillchen@users.noreply.github.com>
Co-authored-by: kurtassad <kurtisassad@gmail.com>
Co-authored-by: Marcin Maslanka <maslankam92@gmail.com>
Co-authored-by: Malik Zulqurnain <51641047+mzparacha@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement prediction market SwapExecuted event pipeline (Slice 4)

3 participants