This guide covers how to claim your winnings from resolved prediction markets on Turbine.
Overview
When a market resolves, your winning shares (YES or NO) can be redeemed for USDC. Turbine uses a gasless claiming process - no RPC access or native gas tokens (MATIC, AVAX) required.
The claiming process:
Market expires (15 minutes for quick markets)
UMA Oracle resolves the market (declares YES or NO as winner)
You claim your winning shares via the API’s relayer
USDC is deposited to your wallet
Claiming is completely gasless - the Turbine relayer pays all gas fees. You only need your wallet’s private key to sign the claim message.
Prerequisites
Private key for your wallet
API credentials (automatically generated on first use)
Winning position in a resolved market
Check Resolution Status
Before claiming, verify that a market has resolved:
from turbine_client import TurbineClient
import os
from dotenv import load_dotenv
load_dotenv()
client = TurbineClient(
host = "https://api.turbinefi.com" ,
chain_id = 137 , # Polygon mainnet
private_key = os.getenv( "TURBINE_PRIVATE_KEY" ),
)
# Check if market is resolved
resolution = client.get_resolution( market_id = "0x1234..." )
if resolution.resolved:
outcome = "YES" if resolution.outcome == 0 else "NO"
print ( f "Market resolved: { outcome } won" )
print ( f "Assertion ID: { resolution.assertion_id } " )
print ( f "Timestamp: { resolution.timestamp } " )
else :
print ( "Market not yet resolved" )
Claim from a Single Market
To claim winnings from one resolved market:
from turbine_client import TurbineClient
import os
from dotenv import load_dotenv
load_dotenv()
client = TurbineClient(
host = "https://api.turbinefi.com" ,
chain_id = 137 ,
private_key = os.getenv( "TURBINE_PRIVATE_KEY" ),
)
# Claim from a resolved market
market_contract_address = "0xB8c45e915F8a78ff8FD691bBDED2125bc9Fa4d96"
try :
result = client.claim_winnings(market_contract_address)
print ( f "Claim successful!" )
print ( f "Transaction hash: { result.get( 'tx_hash' ) } " )
except ValueError as e:
print ( f "Claim failed: { e } " )
Important: You must provide the contract address (the ERC1155 market contract), not the market ID. These are different values.
Market ID - hex string identifier used in API calls
Contract Address - on-chain contract address for the market
Get the contract address from the market details: market = client.get_market( market_id = "0x1234..." )
contract_address = market.contract_address
Batch Claiming (Multiple Markets)
If you have winning positions in multiple resolved markets, claim them all in a single transaction:
# List of contract addresses (not market IDs!)
market_contracts = [
"0xB8c45e915F8a78ff8FD691bBDED2125bc9Fa4d96" ,
"0x3A2F8C1D0B4E9A7C6F5D8E2A1B9C4D7E3F6A8B5C" ,
"0x7E1B9D4C5A8F3E2D6B9C1A4E7F3D8B5C2A6E9F1D" ,
]
try :
result = client.batch_claim_winnings(market_contracts)
print ( f "Batch claim successful!" )
print ( f "Transaction hash: { result.get( 'txHash' ) } " )
except ValueError as e:
print ( f "Batch claim failed: { e } " )
Batch claiming is more gas-efficient when you have multiple markets to claim from, though gas is paid by the relayer either way.
Command Line Examples
You can use the example scripts directly from the command line:
Single Market Claim
# Claim from one market
python examples/claim_winnings.py 0xB8c45e915F8a78ff8FD691bBDED2125bc9Fa4d96
# Specify chain ID (default is 137 - Polygon)
python examples/claim_winnings.py 0xB8c45e915F8a78ff8FD691bBDED2125bc9Fa4d96 137
# Claim on Avalanche
python examples/claim_winnings.py 0x... 43114
Batch Claim
# Claim from multiple markets
python examples/batch_claim_winnings.py \
0xMarket1... \
0xMarket2... \
0xMarket3...
# Specify chain
python examples/batch_claim_winnings.py \
0xMarket1... \
0xMarket2... \
--chain 137
Automated Claiming in Bots
Trading bots should automatically claim winnings from resolved markets. Here’s a background task pattern:
import asyncio
import time
from turbine_client import TurbineClient
class AutoClaimBot :
def __init__ ( self , client : TurbineClient):
self .client = client
self .traded_markets = {} # market_id -> contract_address
self .running = True
async def claim_task ( self ):
"""Background task to claim from resolved markets."""
while self .running:
await self .check_and_claim()
await asyncio.sleep( 300 ) # Check every 5 minutes
async def check_and_claim ( self ):
"""Check all traded markets and claim if resolved."""
markets_to_remove = []
for market_id, contract_addr in self .traded_markets.items():
try :
# Check if market is resolved
resolution = self .client.get_resolution(market_id)
if resolution and resolution.resolved:
print ( f "Market { market_id[: 10 ] } ... resolved, claiming..." )
# Claim winnings
result = self .client.claim_winnings(contract_addr)
print ( f "Claimed: { result.get( 'tx_hash' ) } " )
# Mark for removal
markets_to_remove.append(market_id)
# Rate limit to avoid API throttling
await asyncio.sleep( 15 )
except Exception as e:
print ( f "Claim error for { market_id } : { e } " )
# Remove claimed markets from tracking
for market_id in markets_to_remove:
del self .traded_markets[market_id]
def track_market ( self , market_id : str , contract_address : str ):
"""Add a market to claim tracking."""
self .traded_markets[market_id] = contract_address
Integrate into your bot:
class TradingBot :
def __init__ ( self , client ):
self .client = client
self .auto_claim = AutoClaimBot(client)
async def run ( self ):
# Start claim task in background
asyncio.create_task( self .auto_claim.claim_task())
while True :
# Your trading logic
market = self .client.get_quick_market( "BTC" )
# Track this market for claiming
self .auto_claim.track_market(
market.market_id,
market.contract_address
)
# ... place orders, etc.
await asyncio.sleep( 10 )
See the complete implementation in examples/price_action_bot.py .
Rate Limiting: Enforce at least a 15-second delay between claim attempts to avoid API rate limits.
Finding Markets to Claim
Get Your Positions
Find all markets where you have a position:
# Get all your positions
positions = client.get_user_positions(
address = client.address,
chain_id = 137
)
print ( f "You have positions in { len (positions) } markets" )
for pos in positions:
market = client.get_market(pos.market_id)
print ( f " \n Market: { market.question } " )
print ( f " YES shares: { pos.yes_shares / 1e6 :.2f} " )
print ( f " NO shares: { pos.no_shares / 1e6 :.2f} " )
print ( f " Cost basis: $ { pos.total_invested / 1e6 :.2f} " )
# Check if resolved
resolution = client.get_resolution(pos.market_id)
if resolution and resolution.resolved:
winning_outcome = "YES" if resolution.outcome == 0 else "NO"
print ( f " RESOLVED: { winning_outcome } won" )
print ( f " Contract: { market.contract_address } " )
print ( f " ⚠️ Run: python examples/claim_winnings.py { market.contract_address } " )
Check Pending Claims
See if you have any claims waiting in the queue:
pending = client.get_pending_claims()
if pending:
print ( f "You have { len (pending) } pending claims" )
for claim in pending:
print ( f " Market: { claim.get( 'marketId' ) } " )
print ( f " Status: { claim.get( 'status' ) } " )
else :
print ( "No pending claims" )
Check Failed Claims
If a claim failed, you can retry:
failed = client.get_failed_claims()
if failed:
print ( f "You have { len (failed) } failed claims" )
for claim in failed:
print ( f " Market: { claim.get( 'marketId' ) } " )
print ( f " Error: { claim.get( 'error' ) } " )
print ( f " Contract: { claim.get( 'contractAddress' ) } " )
# Retry
try :
result = client.claim_winnings(claim[ 'contractAddress' ])
print ( f " Retry successful: { result[ 'tx_hash' ] } " )
except Exception as e:
print ( f " Retry failed: { e } " )
else :
print ( "No failed claims" )
Complete Claiming Script
Here’s a complete script to check and claim all your winnings:
import os
import time
from dotenv import load_dotenv
from turbine_client import TurbineClient
load_dotenv()
client = TurbineClient(
host = "https://api.turbinefi.com" ,
chain_id = 137 ,
private_key = os.getenv( "TURBINE_PRIVATE_KEY" ),
)
print ( f "Wallet: { client.address } \n " )
# Get all positions
positions = client.get_user_positions(
address = client.address,
chain_id = 137
)
print ( f "Found { len (positions) } positions \n " )
resolved_markets = []
# Check each position for resolution
for pos in positions:
try :
market = client.get_market(pos.market_id)
resolution = client.get_resolution(pos.market_id)
if resolution and resolution.resolved:
winning_outcome = "YES" if resolution.outcome == 0 else "NO"
# Calculate potential payout
winning_shares = pos.yes_shares if resolution.outcome == 0 else pos.no_shares
payout = winning_shares / 1e6 # Convert to USDC
if winning_shares > 0 :
print ( f "✓ { market.question[: 50 ] } ..." )
print ( f " Winner: { winning_outcome } " )
print ( f " Your { winning_outcome } shares: { winning_shares / 1e6 :.2f} " )
print ( f " Payout: $ { payout :.2f} USDC" )
print ( f " Contract: { market.contract_address } \n " )
resolved_markets.append(market.contract_address)
except Exception as e:
print ( f "Error checking { pos.market_id } : { e } " )
if not resolved_markets:
print ( "No winnings to claim!" )
exit ( 0 )
# Claim all at once
print ( f " \n Claiming from { len (resolved_markets) } market(s)... \n " )
if len (resolved_markets) == 1 :
# Single claim
result = client.claim_winnings(resolved_markets[ 0 ])
print ( f "Claimed! Transaction: { result.get( 'tx_hash' ) } " )
else :
# Batch claim
result = client.batch_claim_winnings(resolved_markets)
print ( f "Batch claimed! Transaction: { result.get( 'txHash' ) } " )
print ( " \n Done!" )
client.close()
Run it:
Troubleshooting
”No claimable balance” Error
This means:
You don’t have winning shares in this market
You already claimed from this market
The market hasn’t resolved yet
Double-check the resolution status and your position.
”Market not resolved” Error
The market hasn’t been resolved by the UMA Oracle yet. Quick markets typically resolve within a few minutes after expiration, but can take up to an hour.
”Invalid contract address” Error
Make sure you’re using the contract address from market.contract_address, not the market ID.
Transaction Pending Forever
Check the transaction status:
pending = client.get_pending_claims()
for claim in pending:
print ( f "Market: { claim[ 'marketId' ] } " )
print ( f "Status: { claim[ 'status' ] } " )
print ( f "Submitted: { claim[ 'timestamp' ] } " )
If stuck for > 30 minutes, contact support.
Next Steps
Build a Trading Bot Automate claiming in your bot
Market Data Track your positions
API Reference Complete API documentation
Example Code Browse claiming examples on GitHub