|
28 | 28 | - Allocation skew: more capital on the likely-winning side |
29 | 29 | - Auto-approves USDC gaslessly when entering a new market |
30 | 30 | - Automatic market transition when 15-minute markets rotate |
31 | | - - Automatic claiming of winnings from resolved markets |
| 31 | + - Automatic claiming of winnings via Multicall3 on-chain discovery (every 5 min) |
32 | 32 |
|
33 | 33 | Usage: |
34 | 34 | TURBINE_PRIVATE_KEY=0x... python examples/market_maker.py |
@@ -1088,43 +1088,38 @@ async def monitor_market_transitions(self) -> None: |
1088 | 1088 | await asyncio.sleep(5) |
1089 | 1089 |
|
1090 | 1090 | async def claim_resolved_markets(self) -> None: |
1091 | | - """Background task to claim winnings from resolved markets.""" |
1092 | | - while self.running: |
1093 | | - try: |
1094 | | - all_traded: list[tuple[str, str, AssetState]] = [] |
1095 | | - for state in self.asset_states.values(): |
1096 | | - for market_id, contract_address in list(state.traded_markets.items()): |
1097 | | - all_traded.append((market_id, contract_address, state)) |
| 1091 | + """Background task to periodically discover and claim all winnings. |
1098 | 1092 |
|
1099 | | - if not all_traded: |
1100 | | - await asyncio.sleep(120) |
1101 | | - continue |
| 1093 | + Uses Multicall3-based on-chain discovery (claim_all_winnings) to find |
| 1094 | + and claim ALL resolved positions — not just markets traded in this session. |
| 1095 | + This ensures the MM recycles liquidity from any prior session or wallet activity. |
| 1096 | + """ |
| 1097 | + # Wait for initial market setup before first claim attempt |
| 1098 | + await asyncio.sleep(60) |
1102 | 1099 |
|
1103 | | - for market_id, contract_address, state in all_traded: |
1104 | | - try: |
1105 | | - resolution = self.client.get_resolution(market_id) |
1106 | | - if not (resolution and resolution.resolved): |
1107 | | - continue |
1108 | | - except Exception: |
1109 | | - continue |
| 1100 | + while self.running: |
| 1101 | + try: |
| 1102 | + print("[CLAIM] Scanning for claimable positions (Multicall3 discovery)...") |
| 1103 | + result = self.client.claim_all_winnings() |
| 1104 | + tx_hash = result.get("txHash", result.get("tx_hash", "unknown")) |
| 1105 | + print(f"[CLAIM] 💰 Claimed winnings! TX: {tx_hash}") |
1110 | 1106 |
|
1111 | | - try: |
1112 | | - result = self.client.claim_winnings(contract_address) |
1113 | | - tx_hash = result.get("txHash", result.get("tx_hash", "unknown")) |
1114 | | - print(f"[{state.asset}] 💰 Claimed winnings from {market_id[:8]}... TX: {tx_hash}") |
1115 | | - del state.traded_markets[market_id] |
1116 | | - except ValueError as e: |
1117 | | - if "no winning tokens" in str(e).lower(): |
1118 | | - del state.traded_markets[market_id] |
1119 | | - except Exception as e: |
1120 | | - print(f"[{state.asset}] Claim error: {e}") |
1121 | | - |
1122 | | - await asyncio.sleep(15) |
| 1107 | + # Clear tracked markets that were just claimed |
| 1108 | + for state in self.asset_states.values(): |
| 1109 | + state.traded_markets.clear() |
1123 | 1110 |
|
| 1111 | + except ValueError as e: |
| 1112 | + # "No claimable positions found" — normal, nothing to claim |
| 1113 | + if "no claimable" in str(e).lower(): |
| 1114 | + print(f"[CLAIM] No claimable positions found — all clear") |
| 1115 | + else: |
| 1116 | + print(f"[CLAIM] Error: {e}") |
1124 | 1117 | except Exception as e: |
1125 | | - print(f"Claim monitor error: {e}") |
| 1118 | + print(f"[CLAIM] Discovery/claim error: {e}") |
1126 | 1119 |
|
1127 | | - await asyncio.sleep(120) |
| 1120 | + # Run every 5 minutes — frequent enough to recycle liquidity promptly |
| 1121 | + # after 15-min markets resolve, without hammering the RPC |
| 1122 | + await asyncio.sleep(300) |
1128 | 1123 |
|
1129 | 1124 | # ------------------------------------------------------------------ |
1130 | 1125 | # Main trading loop (fast poll) |
|
0 commit comments