poly-web3 0.0.6__tar.gz → 1.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {poly_web3-0.0.6 → poly_web3-1.0.1}/PKG-INFO +85 -60
  2. {poly_web3-0.0.6 → poly_web3-1.0.1}/README.md +83 -58
  3. {poly_web3-0.0.6 → poly_web3-1.0.1}/examples/example_redeem.py +7 -7
  4. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3/const.py +5 -5
  5. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3/web3_service/base.py +3 -3
  6. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3/web3_service/proxy_service.py +6 -7
  7. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3.egg-info/PKG-INFO +85 -60
  8. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3.egg-info/requires.txt +1 -1
  9. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3.egg-info/top_level.txt +1 -0
  10. {poly_web3-0.0.6 → poly_web3-1.0.1}/pyproject.toml +2 -2
  11. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3/__init__.py +0 -0
  12. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3/log.py +0 -0
  13. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3/schema.py +0 -0
  14. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3/signature/__init__.py +0 -0
  15. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3/signature/build.py +0 -0
  16. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3/signature/hash_message.py +0 -0
  17. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3/signature/secp256k1.py +0 -0
  18. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3/web3_service/__init__.py +0 -0
  19. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3/web3_service/eoa_service.py +0 -0
  20. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3/web3_service/safe_service.py +0 -0
  21. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3.egg-info/SOURCES.txt +0 -0
  22. {poly_web3-0.0.6 → poly_web3-1.0.1}/poly_web3.egg-info/dependency_links.txt +0 -0
  23. {poly_web3-0.0.6 → poly_web3-1.0.1}/setup.cfg +0 -0
  24. {poly_web3-0.0.6 → poly_web3-1.0.1}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: poly-web3
3
- Version: 0.0.6
3
+ Version: 1.0.1
4
4
  Summary: Polymarket Proxy wallet redeem SDK - Execute redeem operations on Polymarket using proxy wallets
5
5
  Home-page: https://github.com/tosmart01/poly-web3
6
6
  Author: PinBar
@@ -19,7 +19,7 @@ Requires-Python: >=3.11
19
19
  Description-Content-Type: text/markdown
20
20
  Requires-Dist: py-clob-client>=0.25.0
21
21
  Requires-Dist: py-builder-relayer-client>=0.0.1
22
- Requires-Dist: web3==6.8
22
+ Requires-Dist: web3<8,>=7.0.0
23
23
  Requires-Dist: eth-utils==5.3.1
24
24
  Requires-Dist: setuptools>=80.9.0
25
25
  Dynamic: home-page
@@ -27,13 +27,42 @@ Dynamic: requires-python
27
27
 
28
28
  # poly-web3
29
29
 
30
- Python SDK for Polymarket Proxy wallet redeem operations. Supports executing Conditional Token Fund (CTF) redeem operations on Polymarket through proxy wallets, Free gas.
30
+ Python SDK for redeeming Polymarket positions via Proxy/Safe wallets (gas-free).
31
31
 
32
32
  [English](README.md) | [中文](README.zh.md)
33
33
 
34
+ ```bash
35
+ pip install poly-web3
36
+ ```
37
+
38
+ ```python
39
+ from poly_web3 import PolyWeb3Service
40
+
41
+ service = PolyWeb3Service(
42
+ clob_client=client,
43
+ relayer_client=relayer_client,
44
+ )
45
+
46
+ # Redeem all redeemable positions for the current account.
47
+ service.redeem_all(batch_size=20)
48
+ ```
49
+
50
+ [See the full example](#quick-start)
51
+
52
+ ## Redeem Behavior Notes
53
+
54
+ - Redeemable positions are fetched via the official Positions API, which typically has ~1 minute latency.
55
+ - `redeem_all` returns an empty list if there are no redeemable positions. If the returned list contains `None`, the redeem failed and should be retried.
56
+
57
+ ## Troubleshooting
58
+
59
+ 1. **UI shows redeemable, but `redeem_all` returns `[]`**: The official Positions API can be delayed by 1–3 minutes. Wait a bit and retry.
60
+ 2. **RPC error during redeem**: Switch RPC endpoints by setting `rpc_url` when instantiating `PolyWeb3Service`.
61
+ 3. **Redeem stuck in `execute`**: The official relayer may be congested. Stop redeeming for 1 hour to avoid nonce looping from repeated submissions.
62
+
34
63
  ## About the Project
35
64
 
36
- 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 wallet redeem operations on Polymarket.
65
+ 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.
37
66
 
38
67
  **Important Notes:**
39
68
  - This project **only implements the official redeem functionality**, focusing on Conditional Token Fund (CTF) redeem operations
@@ -46,18 +75,10 @@ Reference:
46
75
 
47
76
  **Current Status:**
48
77
  - ✅ **Proxy Wallet** - Fully supported for redeem functionality
49
- - 🚧 **Safe Wallet** - Under development
78
+ - **Safe Wallet** - Fully supported for redeem functionality
50
79
  - 🚧 **EOA Wallet** - Under development
51
80
 
52
- We welcome community contributions! If you'd like to help implement Safe or EOA wallet redeem functionality, or have other improvement suggestions, please feel free to submit a Pull Request.
53
-
54
- ## Features
55
-
56
- - ✅ Support for Polymarket Proxy wallet redeem operations (currently only Proxy wallet is supported)
57
- - ✅ Check if conditions are resolved
58
- - ✅ Get redeemable indexes and balances
59
- - ✅ Support for standard CTF redeem and negative risk (neg_risk) redeem
60
- - ✅ Automatic transaction execution through Relayer service
81
+ 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.
61
82
 
62
83
  ## Installation
63
84
 
@@ -79,7 +100,7 @@ uv add poly-web3
79
100
 
80
101
  - `py-clob-client >= 0.25.0` - Polymarket CLOB client
81
102
  - `py-builder-relayer-client >= 0.0.1` - Builder Relayer client
82
- - `web3 == 6.8` - Web3.py library
103
+ - `web3 >= 7.0.0` - Web3.py library
83
104
  - `eth-utils == 5.3.1` - Ethereum utilities library
84
105
 
85
106
  ## Quick Start
@@ -104,7 +125,7 @@ client = ClobClient(
104
125
  host,
105
126
  key=os.getenv("POLY_API_KEY"),
106
127
  chain_id=chain_id,
107
- signature_type=1, # Proxy wallet type
128
+ signature_type=1, # Proxy wallet type (signature_type=2 for Safe)
108
129
  funder=os.getenv("POLYMARKET_PROXY_ADDRESS"),
109
130
  )
110
131
 
@@ -143,33 +164,51 @@ print(f"Redeem batch result: {redeem_batch_result}")
143
164
  # Redeem all positions that are currently redeemable
144
165
  redeem_all_result = service.redeem_all(batch_size=20)
145
166
  print(f"Redeem all result: {redeem_all_result}")
167
+ if redeem_all_result and any(item is None for item in redeem_all_result):
168
+ print("Redeem failed for some items; please retry.")
146
169
  ```
147
170
 
148
- ### Optional - Query Operations
171
+ ## API Documentation
149
172
 
150
- Before executing redeem, you can optionally check the condition status and query redeemable balances:
173
+ ### PolyWeb3Service
151
174
 
152
- ```python
153
- # Check if condition is resolved
154
- condition_id = "0xc3df016175463c44f9c9f98bddaa3bf3daaabb14b069fb7869621cffe73ddd1c"
155
- can_redeem = service.is_condition_resolved(condition_id)
175
+ The main service class that automatically selects the appropriate service implementation based on wallet type.
156
176
 
157
- # Get redeemable indexes and balances
158
- redeem_balance = service.get_redeemable_index_and_balance(
159
- condition_id, owner=client.builder.funder
160
- )
177
+ #### Methods
161
178
 
162
- print(f"Can redeem: {can_redeem}")
163
- print(f"Redeemable balance: {redeem_balance}")
179
+ ##### `redeem(condition_ids: list[str], batch_size: int = 20)`
180
+
181
+ Execute redeem operation.
182
+
183
+ **Parameters:**
184
+ - `condition_ids` (list[str]): List of condition IDs
185
+ - `batch_size` (int): Batch size for redeem requests
186
+
187
+ **Returns:**
188
+ - `dict | list[dict]`: Transaction result(s) containing transaction status and related information
189
+
190
+ **Examples:**
191
+
192
+ ```python
193
+ # Batch redeem
194
+ result = service.redeem(["0x...", "0x..."], batch_size=20)
164
195
  ```
165
196
 
166
- ## API Documentation
197
+ ##### `redeem_all(batch_size: int = 20) -> list[dict]`
167
198
 
168
- ### PolyWeb3Service
199
+ Redeem all positions that are currently redeemable for the authenticated account.
169
200
 
170
- The main service class that automatically selects the appropriate service implementation based on wallet type.
201
+ **Returns:**
202
+ - `list[dict]`: List of redeem results; empty list if no redeemable positions. If the list contains `None`, the redeem failed and should be retried.
171
203
 
172
- #### Methods
204
+ **Examples:**
205
+
206
+ ```python
207
+ # Redeem all positions that can be redeemed
208
+ service.redeem_all(batch_size=20)
209
+ ```
210
+
211
+ #### Optional APIs
173
212
 
174
213
  ##### `is_condition_resolved(condition_id: str) -> bool`
175
214
 
@@ -202,36 +241,22 @@ Get redeemable indexes and balances for the specified address.
202
241
  **Returns:**
203
242
  - `list[tuple]`: List of tuples containing (index, balance), balance is in USDC units
204
243
 
205
- ##### `redeem(condition_ids: list[str], batch_size: int = 20)`
206
-
207
- Execute redeem operation.
208
-
209
- **Parameters:**
210
- - `condition_ids` (list[str]): List of condition IDs
211
- - `batch_size` (int): Batch size for redeem requests
244
+ ## Optional: Query Operations
212
245
 
213
- **Returns:**
214
- - `dict | list[dict]`: Transaction result(s) containing transaction status and related information
215
-
216
- **Examples:**
246
+ Before executing redeem, you can optionally check the condition status and query redeemable balances:
217
247
 
218
248
  ```python
219
- # Batch redeem
220
- result = service.redeem(["0x...", "0x..."], batch_size=20)
221
- ```
222
-
223
- ##### `redeem_all(batch_size: int = 20) -> list[dict] | None`
224
-
225
- Redeem all positions that are currently redeemable for the authenticated account.
226
-
227
- **Returns:**
228
- - `list[dict] | None`: List of redeem results, or `None` if no redeemable positions
249
+ # Check if condition is resolved
250
+ condition_id = "0xc3df016175463c44f9c9f98bddaa3bf3daaabb14b069fb7869621cffe73ddd1c"
251
+ can_redeem = service.is_condition_resolved(condition_id)
229
252
 
230
- **Examples:**
253
+ # Get redeemable indexes and balances
254
+ redeem_balance = service.get_redeemable_index_and_balance(
255
+ condition_id, owner=client.builder.funder
256
+ )
231
257
 
232
- ```python
233
- # Redeem all positions that can be redeemed
234
- service.redeem_all(batch_size=20)
258
+ print(f"Can redeem: {can_redeem}")
259
+ print(f"Redeemable balance: {redeem_balance}")
235
260
  ```
236
261
 
237
262
  ## Project Structure
@@ -249,14 +274,14 @@ poly_web3/
249
274
  ├── base.py # Base service class
250
275
  ├── proxy_service.py # Proxy wallet service (✅ Implemented)
251
276
  ├── eoa_service.py # EOA wallet service (🚧 Under development)
252
- └── safe_service.py # Safe wallet service (🚧 Under development)
277
+ └── safe_service.py # Safe wallet service ( Implemented)
253
278
  ```
254
279
 
255
280
  ## Notes
256
281
 
257
282
  1. **Environment Variable Security**: Make sure `.env` file is added to `.gitignore`, do not commit sensitive information to the code repository
258
283
  2. **Network Support**: Currently mainly supports Polygon mainnet (chain_id: 137), Amoy testnet may have limited functionality
259
- 3. **Wallet Type**: **Currently only Proxy wallet is supported** (signature_type: 1), Safe and EOA wallet redeem functionality is under development
284
+ 3. **Wallet Type**: Proxy (signature_type: 1) and Safe (signature_type: 2) are supported; EOA wallet redeem functionality is under development
260
285
  4. **Gas Fees**: Transactions are executed through Relayer, gas fees are handled by the Relayer
261
286
 
262
287
  ## Development
@@ -277,7 +302,7 @@ python examples/example_redeem.py
277
302
 
278
303
  We welcome all forms of contributions! If you'd like to:
279
304
 
280
- - Implement Safe or EOA wallet support
305
+ - Implement EOA wallet support
281
306
  - Fix bugs or improve existing functionality
282
307
  - Add new features or improve documentation
283
308
  - Make suggestions or report issues
@@ -1,12 +1,41 @@
1
1
  # poly-web3
2
2
 
3
- Python SDK for Polymarket Proxy wallet redeem operations. Supports executing Conditional Token Fund (CTF) redeem operations on Polymarket through proxy wallets, Free gas.
3
+ Python SDK for redeeming Polymarket positions via Proxy/Safe wallets (gas-free).
4
4
 
5
5
  [English](README.md) | [中文](README.zh.md)
6
6
 
7
+ ```bash
8
+ pip install poly-web3
9
+ ```
10
+
11
+ ```python
12
+ from poly_web3 import PolyWeb3Service
13
+
14
+ service = PolyWeb3Service(
15
+ clob_client=client,
16
+ relayer_client=relayer_client,
17
+ )
18
+
19
+ # Redeem all redeemable positions for the current account.
20
+ service.redeem_all(batch_size=20)
21
+ ```
22
+
23
+ [See the full example](#quick-start)
24
+
25
+ ## Redeem Behavior Notes
26
+
27
+ - Redeemable positions are fetched via the official Positions API, which typically has ~1 minute latency.
28
+ - `redeem_all` returns an empty list if there are no redeemable positions. If the returned list contains `None`, the redeem failed and should be retried.
29
+
30
+ ## Troubleshooting
31
+
32
+ 1. **UI shows redeemable, but `redeem_all` returns `[]`**: The official Positions API can be delayed by 1–3 minutes. Wait a bit and retry.
33
+ 2. **RPC error during redeem**: Switch RPC endpoints by setting `rpc_url` when instantiating `PolyWeb3Service`.
34
+ 3. **Redeem stuck in `execute`**: The official relayer may be congested. Stop redeeming for 1 hour to avoid nonce looping from repeated submissions.
35
+
7
36
  ## About the Project
8
37
 
9
- 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 wallet redeem operations on Polymarket.
38
+ 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.
10
39
 
11
40
  **Important Notes:**
12
41
  - This project **only implements the official redeem functionality**, focusing on Conditional Token Fund (CTF) redeem operations
@@ -19,18 +48,10 @@ Reference:
19
48
 
20
49
  **Current Status:**
21
50
  - ✅ **Proxy Wallet** - Fully supported for redeem functionality
22
- - 🚧 **Safe Wallet** - Under development
51
+ - **Safe Wallet** - Fully supported for redeem functionality
23
52
  - 🚧 **EOA Wallet** - Under development
24
53
 
25
- We welcome community contributions! If you'd like to help implement Safe or EOA wallet redeem functionality, or have other improvement suggestions, please feel free to submit a Pull Request.
26
-
27
- ## Features
28
-
29
- - ✅ Support for Polymarket Proxy wallet redeem operations (currently only Proxy wallet is supported)
30
- - ✅ Check if conditions are resolved
31
- - ✅ Get redeemable indexes and balances
32
- - ✅ Support for standard CTF redeem and negative risk (neg_risk) redeem
33
- - ✅ Automatic transaction execution through Relayer service
54
+ 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.
34
55
 
35
56
  ## Installation
36
57
 
@@ -52,7 +73,7 @@ uv add poly-web3
52
73
 
53
74
  - `py-clob-client >= 0.25.0` - Polymarket CLOB client
54
75
  - `py-builder-relayer-client >= 0.0.1` - Builder Relayer client
55
- - `web3 == 6.8` - Web3.py library
76
+ - `web3 >= 7.0.0` - Web3.py library
56
77
  - `eth-utils == 5.3.1` - Ethereum utilities library
57
78
 
58
79
  ## Quick Start
@@ -77,7 +98,7 @@ client = ClobClient(
77
98
  host,
78
99
  key=os.getenv("POLY_API_KEY"),
79
100
  chain_id=chain_id,
80
- signature_type=1, # Proxy wallet type
101
+ signature_type=1, # Proxy wallet type (signature_type=2 for Safe)
81
102
  funder=os.getenv("POLYMARKET_PROXY_ADDRESS"),
82
103
  )
83
104
 
@@ -116,33 +137,51 @@ print(f"Redeem batch result: {redeem_batch_result}")
116
137
  # Redeem all positions that are currently redeemable
117
138
  redeem_all_result = service.redeem_all(batch_size=20)
118
139
  print(f"Redeem all result: {redeem_all_result}")
140
+ if redeem_all_result and any(item is None for item in redeem_all_result):
141
+ print("Redeem failed for some items; please retry.")
119
142
  ```
120
143
 
121
- ### Optional - Query Operations
144
+ ## API Documentation
122
145
 
123
- Before executing redeem, you can optionally check the condition status and query redeemable balances:
146
+ ### PolyWeb3Service
124
147
 
125
- ```python
126
- # Check if condition is resolved
127
- condition_id = "0xc3df016175463c44f9c9f98bddaa3bf3daaabb14b069fb7869621cffe73ddd1c"
128
- can_redeem = service.is_condition_resolved(condition_id)
148
+ The main service class that automatically selects the appropriate service implementation based on wallet type.
129
149
 
130
- # Get redeemable indexes and balances
131
- redeem_balance = service.get_redeemable_index_and_balance(
132
- condition_id, owner=client.builder.funder
133
- )
150
+ #### Methods
134
151
 
135
- print(f"Can redeem: {can_redeem}")
136
- print(f"Redeemable balance: {redeem_balance}")
152
+ ##### `redeem(condition_ids: list[str], batch_size: int = 20)`
153
+
154
+ Execute redeem operation.
155
+
156
+ **Parameters:**
157
+ - `condition_ids` (list[str]): List of condition IDs
158
+ - `batch_size` (int): Batch size for redeem requests
159
+
160
+ **Returns:**
161
+ - `dict | list[dict]`: Transaction result(s) containing transaction status and related information
162
+
163
+ **Examples:**
164
+
165
+ ```python
166
+ # Batch redeem
167
+ result = service.redeem(["0x...", "0x..."], batch_size=20)
137
168
  ```
138
169
 
139
- ## API Documentation
170
+ ##### `redeem_all(batch_size: int = 20) -> list[dict]`
140
171
 
141
- ### PolyWeb3Service
172
+ Redeem all positions that are currently redeemable for the authenticated account.
142
173
 
143
- The main service class that automatically selects the appropriate service implementation based on wallet type.
174
+ **Returns:**
175
+ - `list[dict]`: List of redeem results; empty list if no redeemable positions. If the list contains `None`, the redeem failed and should be retried.
144
176
 
145
- #### Methods
177
+ **Examples:**
178
+
179
+ ```python
180
+ # Redeem all positions that can be redeemed
181
+ service.redeem_all(batch_size=20)
182
+ ```
183
+
184
+ #### Optional APIs
146
185
 
147
186
  ##### `is_condition_resolved(condition_id: str) -> bool`
148
187
 
@@ -175,36 +214,22 @@ Get redeemable indexes and balances for the specified address.
175
214
  **Returns:**
176
215
  - `list[tuple]`: List of tuples containing (index, balance), balance is in USDC units
177
216
 
178
- ##### `redeem(condition_ids: list[str], batch_size: int = 20)`
179
-
180
- Execute redeem operation.
181
-
182
- **Parameters:**
183
- - `condition_ids` (list[str]): List of condition IDs
184
- - `batch_size` (int): Batch size for redeem requests
217
+ ## Optional: Query Operations
185
218
 
186
- **Returns:**
187
- - `dict | list[dict]`: Transaction result(s) containing transaction status and related information
188
-
189
- **Examples:**
219
+ Before executing redeem, you can optionally check the condition status and query redeemable balances:
190
220
 
191
221
  ```python
192
- # Batch redeem
193
- result = service.redeem(["0x...", "0x..."], batch_size=20)
194
- ```
195
-
196
- ##### `redeem_all(batch_size: int = 20) -> list[dict] | None`
197
-
198
- Redeem all positions that are currently redeemable for the authenticated account.
199
-
200
- **Returns:**
201
- - `list[dict] | None`: List of redeem results, or `None` if no redeemable positions
222
+ # Check if condition is resolved
223
+ condition_id = "0xc3df016175463c44f9c9f98bddaa3bf3daaabb14b069fb7869621cffe73ddd1c"
224
+ can_redeem = service.is_condition_resolved(condition_id)
202
225
 
203
- **Examples:**
226
+ # Get redeemable indexes and balances
227
+ redeem_balance = service.get_redeemable_index_and_balance(
228
+ condition_id, owner=client.builder.funder
229
+ )
204
230
 
205
- ```python
206
- # Redeem all positions that can be redeemed
207
- service.redeem_all(batch_size=20)
231
+ print(f"Can redeem: {can_redeem}")
232
+ print(f"Redeemable balance: {redeem_balance}")
208
233
  ```
209
234
 
210
235
  ## Project Structure
@@ -222,14 +247,14 @@ poly_web3/
222
247
  ├── base.py # Base service class
223
248
  ├── proxy_service.py # Proxy wallet service (✅ Implemented)
224
249
  ├── eoa_service.py # EOA wallet service (🚧 Under development)
225
- └── safe_service.py # Safe wallet service (🚧 Under development)
250
+ └── safe_service.py # Safe wallet service ( Implemented)
226
251
  ```
227
252
 
228
253
  ## Notes
229
254
 
230
255
  1. **Environment Variable Security**: Make sure `.env` file is added to `.gitignore`, do not commit sensitive information to the code repository
231
256
  2. **Network Support**: Currently mainly supports Polygon mainnet (chain_id: 137), Amoy testnet may have limited functionality
232
- 3. **Wallet Type**: **Currently only Proxy wallet is supported** (signature_type: 1), Safe and EOA wallet redeem functionality is under development
257
+ 3. **Wallet Type**: Proxy (signature_type: 1) and Safe (signature_type: 2) are supported; EOA wallet redeem functionality is under development
233
258
  4. **Gas Fees**: Transactions are executed through Relayer, gas fees are handled by the Relayer
234
259
 
235
260
  ## Development
@@ -250,7 +275,7 @@ python examples/example_redeem.py
250
275
 
251
276
  We welcome all forms of contributions! If you'd like to:
252
277
 
253
- - Implement Safe or EOA wallet support
278
+ - Implement EOA wallet support
254
279
  - Fix bugs or improve existing functionality
255
280
  - Add new features or improve documentation
256
281
  - Make suggestions or report issues
@@ -24,7 +24,7 @@ if __name__ == "__main__":
24
24
  host,
25
25
  key=os.getenv("POLY_API_KEY"),
26
26
  chain_id=chain_id,
27
- signature_type=1,
27
+ signature_type=1, # signature_type=2 for Safe
28
28
  funder=os.getenv("POLYMARKET_PROXY_ADDRESS"),
29
29
  )
30
30
  creds = client.create_or_derive_api_creds()
@@ -41,27 +41,27 @@ if __name__ == "__main__":
41
41
  )
42
42
  ),
43
43
  )
44
- condition_id = "0x31fb435a9506d14f00b9de5e5e4491cf2223b6d40a2525d9afa8b620b61b50e2"
45
44
  service = PolyWeb3Service(
46
45
  clob_client=client,
47
46
  relayer_client=relayer_client,
48
47
  rpc_url="https://polygon-bor.publicnode.com",
49
48
  )
49
+
50
+ # Redeem all positions that are currently redeemable (returns list or None)
51
+ redeem_all = service.redeem_all(batch_size=10)
52
+ print(redeem_all)
53
+
50
54
  # Redeem in batch
51
55
  condition_ids = [
52
- condition_id,
53
56
  "0x31fb435a9506d14f00b9de5e5e4491cf2223b6d40a2525d9afa8b620b61b50e2",
54
57
  ]
55
58
  redeem_batch = service.redeem(condition_ids, batch_size=10)
56
59
  print(redeem_batch)
57
60
 
58
- # Redeem all positions that are currently redeemable (returns list or None)
59
- redeem_all = service.redeem_all(batch_size=10)
60
- print(redeem_all)
61
61
 
62
62
  # Optional - Query operations (可选操作,用于查询)
63
63
  # can_redeem = service.is_condition_resolved(condition_id)
64
64
  # redeem_balance = service.get_redeemable_index_and_balance(
65
- # condition_id, owner=client.builder.funder
65
+ # condition_id
66
66
  # )
67
67
  # print(can_redeem, redeem_balance)
@@ -4,7 +4,7 @@
4
4
  # @Site:
5
5
  # @File: const.py
6
6
  # @Software: PyCharm
7
- from web3 import Web3
7
+ from eth_utils import to_checksum_address
8
8
 
9
9
  GET_NONCE = "/nonce"
10
10
  GET_RELAY_PAYLOAD = "/relay-payload"
@@ -23,13 +23,13 @@ STATE_CONFIRMED = "STATE_CONFIRMED"
23
23
  STATE_FAILED = "STATE_FAILED"
24
24
 
25
25
  # address
26
- CTF_ADDRESS = Web3.to_checksum_address("0x4d97dcd97ec945f40cf65f87097ace5ea0476045")
27
- USDC_POLYGON = Web3.to_checksum_address("0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174")
28
- NEG_RISK_ADAPTER_ADDRESS = Web3.to_checksum_address(
26
+ CTF_ADDRESS = to_checksum_address("0x4d97dcd97ec945f40cf65f87097ace5ea0476045")
27
+ USDC_POLYGON = to_checksum_address("0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174")
28
+ NEG_RISK_ADAPTER_ADDRESS = to_checksum_address(
29
29
  "0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296"
30
30
  )
31
31
  ZERO_BYTES32 = "0x" + "00" * 32
32
- proxy_factory_address = Web3.to_checksum_address(
32
+ proxy_factory_address = to_checksum_address(
33
33
  "0xaB45c5A4B0c941a2F231C04C3f49182e1A254052"
34
34
  )
35
35
  SAFE_INIT_CODE_HASH = (
@@ -8,6 +8,7 @@ from typing import Any
8
8
 
9
9
  from py_builder_relayer_client.client import RelayClient
10
10
  from py_clob_client.client import ClobClient
11
+ from eth_utils import to_checksum_address
11
12
  from web3 import Web3
12
13
  import requests
13
14
 
@@ -132,7 +133,7 @@ class BaseWeb3Service:
132
133
  if not winners:
133
134
  return []
134
135
  ctf = self.w3.eth.contract(address=CTF_ADDRESS, abi=CTF_ABI_PAYOUT)
135
- owner_checksum = Web3.to_checksum_address(owner)
136
+ owner_checksum = to_checksum_address(owner)
136
137
  redeemable: list[tuple] = []
137
138
  for index in winners:
138
139
  index_set = 1 << index
@@ -149,7 +150,6 @@ class BaseWeb3Service:
149
150
 
150
151
  def build_ctf_redeem_tx_data(self, condition_id: str) -> str:
151
152
  ctf = self.w3.eth.contract(address=CTF_ADDRESS, abi=CTF_ABI_REDEEM)
152
- # 只需要 calldata:encodeABI 即可
153
153
  return ctf.functions.redeemPositions(
154
154
  USDC_POLYGON,
155
155
  ZERO_BYTES32,
@@ -264,7 +264,7 @@ class BaseWeb3Service:
264
264
  )
265
265
  except Exception as e:
266
266
  error_list.extend(batch)
267
- logger.info(f"redeem batch error, {batch=}, error={e}")
267
+ logger.error(f"redeem batch error, {batch=}, error={e}")
268
268
  if error_list:
269
269
  logger.warning(f"error redeem condition list, {error_list}")
270
270
  return redeem_list
@@ -6,8 +6,7 @@
6
6
  # @Software: PyCharm
7
7
  import requests
8
8
 
9
- from web3 import Web3
10
- from eth_utils import to_bytes
9
+ from eth_utils import to_bytes, to_checksum_address
11
10
 
12
11
  from poly_web3.const import (
13
12
  proxy_wallet_factory_abi,
@@ -22,6 +21,8 @@ from poly_web3.web3_service.base import BaseWeb3Service
22
21
  from poly_web3.signature.build import derive_proxy_wallet, create_struct_hash
23
22
  from poly_web3.signature.hash_message import hash_message
24
23
  from poly_web3.signature import secp256k1
24
+
25
+
25
26
  class ProxyWeb3Service(BaseWeb3Service):
26
27
  def _build_redeem_tx(self, to: str, data: str) -> dict:
27
28
  return {
@@ -92,15 +93,13 @@ class ProxyWeb3Service(BaseWeb3Service):
92
93
  # Create the contract object
93
94
  contract = self.w3.eth.contract(abi=proxy_wallet_factory_abi)
94
95
 
95
- # Encode function data
96
- function_data = contract.encodeABI(fn_name="proxy", args=[calls_data])
97
-
98
- return function_data
96
+ # Encode function data (compatible with web3 6/7)
97
+ return contract.functions.proxy(calls_data)._encode_transaction_data()
99
98
 
100
99
  def _submit_redeem(self, txs: list[dict]) -> dict:
101
100
  if self.clob_client is None:
102
101
  raise Exception("signer not found")
103
- _from = Web3.to_checksum_address(self.clob_client.get_address())
102
+ _from = to_checksum_address(self.clob_client.get_address())
104
103
  rp = self._get_relay_payload(_from, self.wallet_type)
105
104
  args = {
106
105
  "from": _from,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: poly-web3
3
- Version: 0.0.6
3
+ Version: 1.0.1
4
4
  Summary: Polymarket Proxy wallet redeem SDK - Execute redeem operations on Polymarket using proxy wallets
5
5
  Home-page: https://github.com/tosmart01/poly-web3
6
6
  Author: PinBar
@@ -19,7 +19,7 @@ Requires-Python: >=3.11
19
19
  Description-Content-Type: text/markdown
20
20
  Requires-Dist: py-clob-client>=0.25.0
21
21
  Requires-Dist: py-builder-relayer-client>=0.0.1
22
- Requires-Dist: web3==6.8
22
+ Requires-Dist: web3<8,>=7.0.0
23
23
  Requires-Dist: eth-utils==5.3.1
24
24
  Requires-Dist: setuptools>=80.9.0
25
25
  Dynamic: home-page
@@ -27,13 +27,42 @@ Dynamic: requires-python
27
27
 
28
28
  # poly-web3
29
29
 
30
- Python SDK for Polymarket Proxy wallet redeem operations. Supports executing Conditional Token Fund (CTF) redeem operations on Polymarket through proxy wallets, Free gas.
30
+ Python SDK for redeeming Polymarket positions via Proxy/Safe wallets (gas-free).
31
31
 
32
32
  [English](README.md) | [中文](README.zh.md)
33
33
 
34
+ ```bash
35
+ pip install poly-web3
36
+ ```
37
+
38
+ ```python
39
+ from poly_web3 import PolyWeb3Service
40
+
41
+ service = PolyWeb3Service(
42
+ clob_client=client,
43
+ relayer_client=relayer_client,
44
+ )
45
+
46
+ # Redeem all redeemable positions for the current account.
47
+ service.redeem_all(batch_size=20)
48
+ ```
49
+
50
+ [See the full example](#quick-start)
51
+
52
+ ## Redeem Behavior Notes
53
+
54
+ - Redeemable positions are fetched via the official Positions API, which typically has ~1 minute latency.
55
+ - `redeem_all` returns an empty list if there are no redeemable positions. If the returned list contains `None`, the redeem failed and should be retried.
56
+
57
+ ## Troubleshooting
58
+
59
+ 1. **UI shows redeemable, but `redeem_all` returns `[]`**: The official Positions API can be delayed by 1–3 minutes. Wait a bit and retry.
60
+ 2. **RPC error during redeem**: Switch RPC endpoints by setting `rpc_url` when instantiating `PolyWeb3Service`.
61
+ 3. **Redeem stuck in `execute`**: The official relayer may be congested. Stop redeeming for 1 hour to avoid nonce looping from repeated submissions.
62
+
34
63
  ## About the Project
35
64
 
36
- 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 wallet redeem operations on Polymarket.
65
+ 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.
37
66
 
38
67
  **Important Notes:**
39
68
  - This project **only implements the official redeem functionality**, focusing on Conditional Token Fund (CTF) redeem operations
@@ -46,18 +75,10 @@ Reference:
46
75
 
47
76
  **Current Status:**
48
77
  - ✅ **Proxy Wallet** - Fully supported for redeem functionality
49
- - 🚧 **Safe Wallet** - Under development
78
+ - **Safe Wallet** - Fully supported for redeem functionality
50
79
  - 🚧 **EOA Wallet** - Under development
51
80
 
52
- We welcome community contributions! If you'd like to help implement Safe or EOA wallet redeem functionality, or have other improvement suggestions, please feel free to submit a Pull Request.
53
-
54
- ## Features
55
-
56
- - ✅ Support for Polymarket Proxy wallet redeem operations (currently only Proxy wallet is supported)
57
- - ✅ Check if conditions are resolved
58
- - ✅ Get redeemable indexes and balances
59
- - ✅ Support for standard CTF redeem and negative risk (neg_risk) redeem
60
- - ✅ Automatic transaction execution through Relayer service
81
+ 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.
61
82
 
62
83
  ## Installation
63
84
 
@@ -79,7 +100,7 @@ uv add poly-web3
79
100
 
80
101
  - `py-clob-client >= 0.25.0` - Polymarket CLOB client
81
102
  - `py-builder-relayer-client >= 0.0.1` - Builder Relayer client
82
- - `web3 == 6.8` - Web3.py library
103
+ - `web3 >= 7.0.0` - Web3.py library
83
104
  - `eth-utils == 5.3.1` - Ethereum utilities library
84
105
 
85
106
  ## Quick Start
@@ -104,7 +125,7 @@ client = ClobClient(
104
125
  host,
105
126
  key=os.getenv("POLY_API_KEY"),
106
127
  chain_id=chain_id,
107
- signature_type=1, # Proxy wallet type
128
+ signature_type=1, # Proxy wallet type (signature_type=2 for Safe)
108
129
  funder=os.getenv("POLYMARKET_PROXY_ADDRESS"),
109
130
  )
110
131
 
@@ -143,33 +164,51 @@ print(f"Redeem batch result: {redeem_batch_result}")
143
164
  # Redeem all positions that are currently redeemable
144
165
  redeem_all_result = service.redeem_all(batch_size=20)
145
166
  print(f"Redeem all result: {redeem_all_result}")
167
+ if redeem_all_result and any(item is None for item in redeem_all_result):
168
+ print("Redeem failed for some items; please retry.")
146
169
  ```
147
170
 
148
- ### Optional - Query Operations
171
+ ## API Documentation
149
172
 
150
- Before executing redeem, you can optionally check the condition status and query redeemable balances:
173
+ ### PolyWeb3Service
151
174
 
152
- ```python
153
- # Check if condition is resolved
154
- condition_id = "0xc3df016175463c44f9c9f98bddaa3bf3daaabb14b069fb7869621cffe73ddd1c"
155
- can_redeem = service.is_condition_resolved(condition_id)
175
+ The main service class that automatically selects the appropriate service implementation based on wallet type.
156
176
 
157
- # Get redeemable indexes and balances
158
- redeem_balance = service.get_redeemable_index_and_balance(
159
- condition_id, owner=client.builder.funder
160
- )
177
+ #### Methods
161
178
 
162
- print(f"Can redeem: {can_redeem}")
163
- print(f"Redeemable balance: {redeem_balance}")
179
+ ##### `redeem(condition_ids: list[str], batch_size: int = 20)`
180
+
181
+ Execute redeem operation.
182
+
183
+ **Parameters:**
184
+ - `condition_ids` (list[str]): List of condition IDs
185
+ - `batch_size` (int): Batch size for redeem requests
186
+
187
+ **Returns:**
188
+ - `dict | list[dict]`: Transaction result(s) containing transaction status and related information
189
+
190
+ **Examples:**
191
+
192
+ ```python
193
+ # Batch redeem
194
+ result = service.redeem(["0x...", "0x..."], batch_size=20)
164
195
  ```
165
196
 
166
- ## API Documentation
197
+ ##### `redeem_all(batch_size: int = 20) -> list[dict]`
167
198
 
168
- ### PolyWeb3Service
199
+ Redeem all positions that are currently redeemable for the authenticated account.
169
200
 
170
- The main service class that automatically selects the appropriate service implementation based on wallet type.
201
+ **Returns:**
202
+ - `list[dict]`: List of redeem results; empty list if no redeemable positions. If the list contains `None`, the redeem failed and should be retried.
171
203
 
172
- #### Methods
204
+ **Examples:**
205
+
206
+ ```python
207
+ # Redeem all positions that can be redeemed
208
+ service.redeem_all(batch_size=20)
209
+ ```
210
+
211
+ #### Optional APIs
173
212
 
174
213
  ##### `is_condition_resolved(condition_id: str) -> bool`
175
214
 
@@ -202,36 +241,22 @@ Get redeemable indexes and balances for the specified address.
202
241
  **Returns:**
203
242
  - `list[tuple]`: List of tuples containing (index, balance), balance is in USDC units
204
243
 
205
- ##### `redeem(condition_ids: list[str], batch_size: int = 20)`
206
-
207
- Execute redeem operation.
208
-
209
- **Parameters:**
210
- - `condition_ids` (list[str]): List of condition IDs
211
- - `batch_size` (int): Batch size for redeem requests
244
+ ## Optional: Query Operations
212
245
 
213
- **Returns:**
214
- - `dict | list[dict]`: Transaction result(s) containing transaction status and related information
215
-
216
- **Examples:**
246
+ Before executing redeem, you can optionally check the condition status and query redeemable balances:
217
247
 
218
248
  ```python
219
- # Batch redeem
220
- result = service.redeem(["0x...", "0x..."], batch_size=20)
221
- ```
222
-
223
- ##### `redeem_all(batch_size: int = 20) -> list[dict] | None`
224
-
225
- Redeem all positions that are currently redeemable for the authenticated account.
226
-
227
- **Returns:**
228
- - `list[dict] | None`: List of redeem results, or `None` if no redeemable positions
249
+ # Check if condition is resolved
250
+ condition_id = "0xc3df016175463c44f9c9f98bddaa3bf3daaabb14b069fb7869621cffe73ddd1c"
251
+ can_redeem = service.is_condition_resolved(condition_id)
229
252
 
230
- **Examples:**
253
+ # Get redeemable indexes and balances
254
+ redeem_balance = service.get_redeemable_index_and_balance(
255
+ condition_id, owner=client.builder.funder
256
+ )
231
257
 
232
- ```python
233
- # Redeem all positions that can be redeemed
234
- service.redeem_all(batch_size=20)
258
+ print(f"Can redeem: {can_redeem}")
259
+ print(f"Redeemable balance: {redeem_balance}")
235
260
  ```
236
261
 
237
262
  ## Project Structure
@@ -249,14 +274,14 @@ poly_web3/
249
274
  ├── base.py # Base service class
250
275
  ├── proxy_service.py # Proxy wallet service (✅ Implemented)
251
276
  ├── eoa_service.py # EOA wallet service (🚧 Under development)
252
- └── safe_service.py # Safe wallet service (🚧 Under development)
277
+ └── safe_service.py # Safe wallet service ( Implemented)
253
278
  ```
254
279
 
255
280
  ## Notes
256
281
 
257
282
  1. **Environment Variable Security**: Make sure `.env` file is added to `.gitignore`, do not commit sensitive information to the code repository
258
283
  2. **Network Support**: Currently mainly supports Polygon mainnet (chain_id: 137), Amoy testnet may have limited functionality
259
- 3. **Wallet Type**: **Currently only Proxy wallet is supported** (signature_type: 1), Safe and EOA wallet redeem functionality is under development
284
+ 3. **Wallet Type**: Proxy (signature_type: 1) and Safe (signature_type: 2) are supported; EOA wallet redeem functionality is under development
260
285
  4. **Gas Fees**: Transactions are executed through Relayer, gas fees are handled by the Relayer
261
286
 
262
287
  ## Development
@@ -277,7 +302,7 @@ python examples/example_redeem.py
277
302
 
278
303
  We welcome all forms of contributions! If you'd like to:
279
304
 
280
- - Implement Safe or EOA wallet support
305
+ - Implement EOA wallet support
281
306
  - Fix bugs or improve existing functionality
282
307
  - Add new features or improve documentation
283
308
  - Make suggestions or report issues
@@ -1,5 +1,5 @@
1
1
  py-clob-client>=0.25.0
2
2
  py-builder-relayer-client>=0.0.1
3
- web3==6.8
3
+ web3<8,>=7.0.0
4
4
  eth-utils==5.3.1
5
5
  setuptools>=80.9.0
@@ -1,3 +1,4 @@
1
1
  dist
2
2
  examples
3
3
  poly_web3
4
+ tests
@@ -1,13 +1,13 @@
1
1
  [project]
2
2
  name = "poly-web3"
3
- version = "0.0.6"
3
+ version = "1.0.1"
4
4
  description = "Polymarket Proxy wallet redeem SDK - Execute redeem operations on Polymarket using proxy wallets"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
7
7
  dependencies = [
8
8
  "py-clob-client>=0.25.0",
9
9
  "py-builder-relayer-client>=0.0.1",
10
- "web3==6.8",
10
+ "web3>=7.0.0,<8",
11
11
  "eth-utils==5.3.1",
12
12
  "setuptools>=80.9.0",
13
13
  ]
File without changes
File without changes
File without changes
File without changes