An automated bot that monitors and redeems redeemable positions on Polymarket using the Builder Relayer service.
This bot continuously monitors your Polymarket positions and automatically redeems them when they become redeemable. It:
- Polls the Polymarket Data API for redeemable positions
- Batches multiple redeems into a single transaction for efficiency
- Handles relayer quota limits with automatic retry logic
- Supports both PROXY and SAFE wallet transaction types
- Monitors transaction status until confirmed on-chain
- Node.js (v18 or higher recommended)
- A Polymarket account with positions
- Polymarket Builder API credentials (key, secret, passphrase)
- An Ethereum private key that controls your Polymarket wallet
- An RPC endpoint for Polygon network
- Clone the repository:
git clone <repository-url>
cd poly-redeem- Install dependencies:
npm install- Copy the example environment file:
cp .env.example .env- Configure your environment variables (see Configuration below)
Create a .env file in the root directory with the following variables:
PRIVATE_KEY- Your Ethereum private key (without 0x prefix) that controls the wallet with Polymarket positionsPOLY_BUILDER_API_KEY- Your Polymarket Builder API keyPOLY_BUILDER_SECRET- Your Polymarket Builder API secretPOLY_BUILDER_PASSPHRASE- Your Polymarket Builder API passphrasePOLY_USER_ADDRESS- The Ethereum address where your Polymarket positions are heldRPC_URL- Polygon RPC endpoint URL (e.g., from Alchemy, Infura, or QuickNode)
POLL_INTERVAL_MS- How often to check for redeemable positions (default:60000= 1 minute)TX_STATUS_POLL_MS- How often to poll transaction status (default:5000= 5 seconds)TX_STATUS_MAX_POLLS- Maximum number of status polls before timeout (default:36)POSITIONS_SIZE_THRESHOLD- Minimum position size to consider (default:1)POSITIONS_LIMIT- Maximum positions to fetch per API call (default:100, max:500)POSITIONS_SORT_BY- Sort field for positions (default:TOKENS)POSITIONS_SORT_DIRECTION- Sort direction:ASCorDESC(default:DESC)POLY_DATA_API_URL- Polymarket Data API base URL (default:https://data-api.polymarket.com)RELAYER_URL- Polymarket Relayer service URL (default:https://relayer-v2.polymarket.com/)RELAYER_TX_TYPE- Transaction type:PROXYorSAFE(default:SAFE)PROXY_GAS_LIMIT_PER_REDEEM- Gas limit per redeem in a batch (default:153500)PROXY_GAS_LIMIT_CAP- Maximum gas limit for proxy transactions (default:2000000)CTF_ADDRESS- Conditional Token Framework contract address (default:0x4d97dcd97ec945f40cf65f87097ace5ea0476045)COLLATERAL_TOKEN- Collateral token address (default:0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174for USDCe)
The bot supports two transaction types:
- SAFE (default): Uses a Safe wallet for transaction execution. The bot will automatically deploy the Safe if needed.
- PROXY: Uses a proxy wallet. The
PRIVATE_KEYmust control the proxy wallet address, andPOLY_USER_ADDRESSmust match the derived proxy wallet address.
The bot validates that your PRIVATE_KEY and POLY_USER_ADDRESS are correctly configured for the selected transaction type.
Run the bot continuously, polling for redeemable positions:
npm startor
node src/bot.jsThe bot will:
- Check for redeemable positions every
POLL_INTERVAL_MSmilliseconds - Batch multiple redeems into a single transaction
- Submit transactions via the Polymarket Builder Relayer
- Monitor transaction status until confirmed
- Handle relayer quota limits with automatic retries
Run the bot once to check and redeem positions immediately:
npm run redeem:onceor
node src/bot.js --once-
Position Discovery: The bot queries the Polymarket Data API for redeemable positions associated with your
POLY_USER_ADDRESS. -
Position Filtering: Only positions that are:
- Redeemable (market resolved)
- Meet the
POSITIONS_SIZE_THRESHOLD - Are binary markets (can infer index sets)
-
Batching: Positions are grouped by
conditionIdand batched together. The bot prevents duplicate redeems by tracking recently redeemed conditions (10-minute cooldown). -
Transaction Building: For each condition, the bot builds a
redeemPositionstransaction to the Conditional Token Framework contract. -
Submission: Transactions are submitted via the Polymarket Builder Relayer service, which handles gas fees and execution.
-
Monitoring: The bot monitors transaction status until it reaches a terminal state (
STATE_CONFIRMED,STATE_MINED,STATE_FAILED, orSTATE_INVALID). -
Quota Handling: If the relayer quota is exceeded, the bot automatically waits for the specified retry period before attempting again.
- Automatic Batching: Multiple redeems are combined into a single transaction to save gas
- Duplicate Prevention: Tracks recently redeemed conditions to avoid duplicate submissions
- Quota Management: Automatically handles relayer rate limits with exponential backoff
- Transaction Monitoring: Tracks transaction status until on-chain confirmation
- Error Handling: Graceful error handling with detailed logging
- Flexible Configuration: Extensive configuration options via environment variables
The bot provides detailed console logging with timestamps:
- Position discovery and filtering
- Batch creation and submission
- Transaction status updates
- Error messages and warnings
- Quota limit notifications
- Never commit your
.envfile - It contains sensitive credentials - Keep your private key secure - Anyone with access can control your wallet
- Use environment-specific keys - Consider using different API keys for testing vs production
- Review transactions - Monitor the bot's activity, especially when first deploying
This error occurs when your PRIVATE_KEY and POLY_USER_ADDRESS don't match the expected wallet type:
- For
RELAYER_TX_TYPE=PROXY: ThePRIVATE_KEYmust control the proxy wallet, andPOLY_USER_ADDRESSmust be the derived proxy wallet address - For
RELAYER_TX_TYPE=SAFE: ThePRIVATE_KEYmust be a signer for the Safe, andPOLY_USER_ADDRESSmust be the Safe address
If you see quota exceeded errors, the bot will automatically wait and retry. You can:
- Increase
POLL_INTERVAL_MSto reduce submission frequency - Wait for the quota to reset (usually 1 hour)
- Contact Polymarket support if you need higher limits
This occurs for non-binary markets where the bot cannot automatically determine the index sets. The bot will skip these positions. Binary markets (Yes/No) are fully supported.
ISC