Polymarket Proxy wallet redeem SDK - Execute redeem operations on Polymarket using proxy wallets
Project description
poly-web3
Python SDK for redeeming Polymarket positions via Proxy/Safe wallets (gas-free).
pip install poly-web3
from poly_web3 import PolyWeb3Service
service = PolyWeb3Service(
clob_client=client,
relayer_client=relayer_client,
)
# Redeem all redeemable positions for the current account.
service.redeem_all(batch_size=20)
Redeem Behavior Notes
- Redeemable positions are fetched via the official Positions API, which typically has ~1 minute latency.
redeem_allreturns an empty list if there are no redeemable positions. If the returned list containsNone, the redeem failed and should be retried.
Troubleshooting
- UI shows redeemable, but
redeem_allreturns[]: The official Positions API can be delayed by 1–3 minutes. Wait a bit and retry. - RPC error during redeem: Switch RPC endpoints by setting
rpc_urlwhen instantiatingPolyWeb3Service. - Redeem stuck in
execute: The official relayer may be congested. Stop redeeming for 1 hour to avoid nonce looping from repeated submissions.
About the Project
This project is a Python rewrite of Polymarket's official TypeScript implementation of builder-relayer-client, designed to provide Python developers with a convenient tool for executing Proxy and Safe wallet redeem operations on Polymarket.
Important Notes:
- This project only implements the official redeem functionality, focusing on Conditional Token Fund (CTF) redeem operations
- Other features (such as trading, order placement, etc.) are not within the scope of this project
Some Polymarket-related redeem or write operations implemented in this project depend on access granted through Polymarket's Builder program. To perform real redeem operations against Polymarket, you must apply for and obtain a Builder key/credentials via Polymarket's official Builder application process. After approval you will receive the credentials required to use the Builder API—only then will the redeem flows in this repository work against the live service. For local development or automated tests, use mocks or testnet setups instead of real keys to avoid exposing production credentials.
Reference:
- Polymarket Builders — Introduction: https://docs.polymarket.com/developers/builders/builder-intro
Current Status:
- ✅ Proxy Wallet - Fully supported for redeem functionality
- ✅ Safe Wallet - Fully supported for redeem functionality
- 🚧 EOA Wallet - Under development
We welcome community contributions! If you'd like to help implement EOA wallet redeem functionality, or have other improvement suggestions, please feel free to submit a Pull Request.
Installation
pip install poly-web3
Or using uv:
uv add poly-web3
Requirements
- Python >= 3.11
Dependencies
py-clob-client >= 0.25.0- Polymarket CLOB clientpy-builder-relayer-client >= 0.0.1- Builder Relayer clientweb3 >= 7.0.0- Web3.py libraryeth-utils == 5.3.1- Ethereum utilities library
Quick Start
Basic Usage - Execute Redeem
import os
import dotenv
from py_builder_relayer_client.client import RelayClient
from py_builder_signing_sdk.config import BuilderConfig
from py_builder_signing_sdk.sdk_types import BuilderApiKeyCreds
from py_clob_client.client import ClobClient
from poly_web3 import RELAYER_URL, PolyWeb3Service
dotenv.load_dotenv()
# Initialize ClobClient
host = "https://clob.polymarket.com"
chain_id = 137 # Polygon mainnet
client = ClobClient(
host,
key=os.getenv("POLY_API_KEY"),
chain_id=chain_id,
signature_type=1, # Proxy wallet type (signature_type=2 for Safe)
funder=os.getenv("POLYMARKET_PROXY_ADDRESS"),
)
client.set_api_creds(client.create_or_derive_api_creds())
# Initialize RelayerClient
relayer_client = RelayClient(
RELAYER_URL,
chain_id,
os.getenv("POLY_API_KEY"),
BuilderConfig(
local_builder_creds=BuilderApiKeyCreds(
key=os.getenv("BUILDER_KEY"),
secret=os.getenv("BUILDER_SECRET"),
passphrase=os.getenv("BUILDER_PASSPHRASE"),
)
),
)
# Create service instance
service = PolyWeb3Service(
clob_client=client,
relayer_client=relayer_client,
rpc_url="https://polygon-bor.publicnode.com", # optional
)
# Execute redeem operation (batch)
condition_ids = [
"0xc3df016175463c44f9c9f98bddaa3bf3daaabb14b069fb7869621cffe73ddd1c",
"0x31fb435a9506d14f00b9de5e5e4491cf2223b6d40a2525d9afa8b620b61b50e2",
]
redeem_batch_result = service.redeem(condition_ids, batch_size=20)
print(f"Redeem batch result: {redeem_batch_result}")
# Redeem all positions that are currently redeemable
redeem_all_result = service.redeem_all(batch_size=20)
print(f"Redeem all result: {redeem_all_result}")
if redeem_all_result and any(item is None for item in redeem_all_result):
print("Redeem failed for some items; please retry.")
API Documentation
PolyWeb3Service
The main service class that automatically selects the appropriate service implementation based on wallet type.
Methods
redeem(condition_ids: list[str], batch_size: int = 20)
Execute redeem operation.
Parameters:
condition_ids(list[str]): List of condition IDsbatch_size(int): Batch size for redeem requests
Returns:
dict | list[dict]: Transaction result(s) containing transaction status and related information
Examples:
# Batch redeem
result = service.redeem(["0x...", "0x..."], batch_size=20)
redeem_all(batch_size: int = 20) -> list[dict]
Redeem all positions that are currently redeemable for the authenticated account.
Returns:
list[dict]: List of redeem results; empty list if no redeemable positions. If the list containsNone, the redeem failed and should be retried.
Examples:
# Redeem all positions that can be redeemed
service.redeem_all(batch_size=20)
Optional APIs
is_condition_resolved(condition_id: str) -> bool
Check if the specified condition is resolved.
Parameters:
condition_id(str): Condition ID (32-byte hexadecimal string)
Returns:
bool: ReturnsTrueif the condition is resolved, otherwiseFalse
get_winning_indexes(condition_id: str) -> list[int]
Get the list of winning indexes.
Parameters:
condition_id(str): Condition ID
Returns:
list[int]: List of winning indexes
get_redeemable_index_and_balance(condition_id: str, owner: str) -> list[tuple]
Get redeemable indexes and balances for the specified address.
Parameters:
condition_id(str): Condition IDowner(str): Wallet address
Returns:
list[tuple]: List of tuples containing (index, balance), balance is in USDC units
Optional: Query Operations
Before executing redeem, you can optionally check the condition status and query redeemable balances:
# Check if condition is resolved
condition_id = "0xc3df016175463c44f9c9f98bddaa3bf3daaabb14b069fb7869621cffe73ddd1c"
can_redeem = service.is_condition_resolved(condition_id)
# Get redeemable indexes and balances
redeem_balance = service.get_redeemable_index_and_balance(
condition_id, owner=client.builder.funder
)
print(f"Can redeem: {can_redeem}")
print(f"Redeemable balance: {redeem_balance}")
Project Structure
poly_web3/
├── __init__.py # Main entry point, exports PolyWeb3Service
├── const.py # Constant definitions (contract addresses, ABIs, etc.)
├── schema.py # Data models (WalletType, etc.)
├── signature/ # Signature-related modules
│ ├── build.py # Proxy wallet derivation and struct hashing
│ ├── hash_message.py # Message hashing
│ └── secp256k1.py # secp256k1 signing
└── web3_service/ # Web3 service implementations
├── base.py # Base service class
├── proxy_service.py # Proxy wallet service (✅ Implemented)
├── eoa_service.py # EOA wallet service (🚧 Under development)
└── safe_service.py # Safe wallet service (✅ Implemented)
Notes
- Environment Variable Security: Make sure
.envfile is added to.gitignore, do not commit sensitive information to the code repository - Network Support: Currently mainly supports Polygon mainnet (chain_id: 137), Amoy testnet may have limited functionality
- Wallet Type: Proxy (signature_type: 1) and Safe (signature_type: 2) are supported; EOA wallet redeem functionality is under development
- Gas Fees: Transactions are executed through Relayer, gas fees are handled by the Relayer
Development
Install Development Dependencies
uv pip install -e ".[dev]"
Run Examples
python examples/example_redeem.py
Contributing
We welcome all forms of contributions! If you'd like to:
- Implement EOA wallet support
- Fix bugs or improve existing functionality
- Add new features or improve documentation
- Make suggestions or report issues
Please feel free to submit an Issue or Pull Request. Your contributions will help make this project better!
License
MIT
Author
PinBar
Related Links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file poly_web3-1.0.1.tar.gz.
File metadata
- Download URL: poly_web3-1.0.1.tar.gz
- Upload date:
- Size: 19.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9f75cf3b88828a509f579ccf1d2ed0db7ca0d8618862d0c43e22c35d381e1710
|
|
| MD5 |
58d7c25b1f4ca0bbfc95bc44c736700e
|
|
| BLAKE2b-256 |
109c5451264b04b6663e36479424ac893aaf8e08d03d5ebcab0a479bab45e8c5
|
File details
Details for the file poly_web3-1.0.1-py3-none-any.whl.
File metadata
- Download URL: poly_web3-1.0.1-py3-none-any.whl
- Upload date:
- Size: 19.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a17691983451c455ca22dd3308bbef539cd1ddded47e166bf38fcd7b9949157
|
|
| MD5 |
9af3c1d18083dc61a08095a30ba03dd7
|
|
| BLAKE2b-256 |
96758066ea4331ae75d43e38dcd288aabd83665e9d625623a7f5bfaf05a84079
|