problee 0.1.0__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.
- problee-0.1.0/LICENSE +21 -0
- problee-0.1.0/PKG-INFO +209 -0
- problee-0.1.0/README.md +172 -0
- problee-0.1.0/problee/__init__.py +35 -0
- problee-0.1.0/problee/api/__init__.py +13 -0
- problee-0.1.0/problee/api/markets.py +119 -0
- problee-0.1.0/problee/api/positions.py +49 -0
- problee-0.1.0/problee/api/quotes.py +85 -0
- problee-0.1.0/problee/client.py +255 -0
- problee-0.1.0/problee/exceptions.py +84 -0
- problee-0.1.0/problee/models/__init__.py +16 -0
- problee-0.1.0/problee/models/market.py +116 -0
- problee-0.1.0/problee/models/position.py +51 -0
- problee-0.1.0/problee/models/quote.py +65 -0
- problee-0.1.0/problee/streaming/__init__.py +11 -0
- problee-0.1.0/problee/streaming/sse.py +112 -0
- problee-0.1.0/problee/streaming/websocket.py +198 -0
- problee-0.1.0/problee.egg-info/PKG-INFO +209 -0
- problee-0.1.0/problee.egg-info/SOURCES.txt +24 -0
- problee-0.1.0/problee.egg-info/dependency_links.txt +1 -0
- problee-0.1.0/problee.egg-info/requires.txt +14 -0
- problee-0.1.0/problee.egg-info/top_level.txt +1 -0
- problee-0.1.0/pyproject.toml +81 -0
- problee-0.1.0/setup.cfg +4 -0
- problee-0.1.0/setup.py +5 -0
- problee-0.1.0/tests/test_client.py +223 -0
problee-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Problee
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
problee-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: problee
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Official Python SDK for the Problee prediction market API
|
|
5
|
+
Author-email: Problee <dev@problee.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://problee.com
|
|
8
|
+
Project-URL: Documentation, https://docs.problee.com
|
|
9
|
+
Project-URL: Repository, https://github.com/problee/problee-python
|
|
10
|
+
Project-URL: Changelog, https://github.com/problee/problee-python/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: problee,prediction-market,api,sdk,trading,world-chain
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.8
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: requests>=2.28.0
|
|
27
|
+
Provides-Extra: websocket
|
|
28
|
+
Requires-Dist: websockets>=10.0; extra == "websocket"
|
|
29
|
+
Provides-Extra: all
|
|
30
|
+
Requires-Dist: websockets>=10.0; extra == "all"
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
34
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
35
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
36
|
+
Requires-Dist: responses>=0.23.0; extra == "dev"
|
|
37
|
+
|
|
38
|
+
# Problee Python SDK
|
|
39
|
+
|
|
40
|
+
Official Python SDK for the Problee prediction market API.
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install problee
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
For WebSocket support:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install problee[websocket]
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Quick Start
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from problee import ProbClient
|
|
58
|
+
|
|
59
|
+
# Initialize client with your API key
|
|
60
|
+
client = ProbClient(api_key="pk_live_...")
|
|
61
|
+
|
|
62
|
+
# List open markets
|
|
63
|
+
markets = client.markets.list(status="open")
|
|
64
|
+
for market in markets.markets:
|
|
65
|
+
print(f"{market.question}")
|
|
66
|
+
print(f" YES: {market.prices.yes:.2%}")
|
|
67
|
+
print(f" NO: {market.prices.no:.2%}")
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Features
|
|
71
|
+
|
|
72
|
+
- **Markets API**: List, filter, and get market details
|
|
73
|
+
- **Positions API**: Check wallet positions
|
|
74
|
+
- **Quotes API**: Get trade quotes and build transactions
|
|
75
|
+
- **SSE Streaming**: Real-time price updates via Server-Sent Events
|
|
76
|
+
- **WebSocket**: Real-time market updates via WebSocket
|
|
77
|
+
|
|
78
|
+
## Usage Examples
|
|
79
|
+
|
|
80
|
+
### List Markets
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
# List all open markets
|
|
84
|
+
markets = client.markets.list(status="open")
|
|
85
|
+
|
|
86
|
+
# Filter by category
|
|
87
|
+
crypto_markets = client.markets.list(category="crypto")
|
|
88
|
+
|
|
89
|
+
# Sort by volume
|
|
90
|
+
trending = client.markets.list(sort="volume_24h")
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Get Market Details
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
# Get single market
|
|
97
|
+
market = client.markets.get("0x1234...")
|
|
98
|
+
print(f"Question: {market.question}")
|
|
99
|
+
print(f"Status: {market.status}")
|
|
100
|
+
print(f"YES Price: {market.prices.yes}")
|
|
101
|
+
|
|
102
|
+
# Get price history
|
|
103
|
+
history = client.markets.get_history("0x1234...", interval="1h")
|
|
104
|
+
|
|
105
|
+
# Get recent trades
|
|
106
|
+
trades = client.markets.get_trades("0x1234...", limit=50)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Get Quote
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
# Get quote to buy YES shares
|
|
113
|
+
quote = client.quotes.get(
|
|
114
|
+
market_id="0x1234...",
|
|
115
|
+
side="buy",
|
|
116
|
+
outcome="yes",
|
|
117
|
+
amount="1000000000000000000", # 1 USDC in wei
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
print(f"Price: {quote.price:.4f}")
|
|
121
|
+
print(f"Shares: {quote.shares_out}")
|
|
122
|
+
print(f"Price Impact: {quote.price_impact:.2%}")
|
|
123
|
+
print(f"Quote ID: {quote.quote_id}")
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Check Positions
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
# Get all positions for a wallet
|
|
130
|
+
positions = client.positions.list("0xYourWallet...")
|
|
131
|
+
for pos in positions.positions:
|
|
132
|
+
print(f"Market: {pos.market_address}")
|
|
133
|
+
print(f"YES Shares: {pos.yes_shares}")
|
|
134
|
+
print(f"NO Shares: {pos.no_shares}")
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Stream Prices (SSE)
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
# Stream real-time price updates
|
|
141
|
+
for update in client.stream.prices():
|
|
142
|
+
if update.event_type == "price":
|
|
143
|
+
print(f"Price: YES={update.data['yes']}, NO={update.data['no']}")
|
|
144
|
+
elif update.event_type == "tokenPrice":
|
|
145
|
+
print(f"Token: {update.data['symbol']} = ${update.data['price']}")
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### WebSocket Streaming
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
import asyncio
|
|
152
|
+
|
|
153
|
+
async def stream_updates():
|
|
154
|
+
async with client.ws.connect() as ws:
|
|
155
|
+
# Subscribe to market updates
|
|
156
|
+
await ws.subscribe("market", "0x1234...")
|
|
157
|
+
|
|
158
|
+
async for msg in ws:
|
|
159
|
+
if msg.type == "price_update":
|
|
160
|
+
print(f"Price: {msg.data['prices']}")
|
|
161
|
+
elif msg.type == "trade":
|
|
162
|
+
print(f"Trade: {msg.data}")
|
|
163
|
+
|
|
164
|
+
asyncio.run(stream_updates())
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Error Handling
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
from problee import ProbClient
|
|
171
|
+
from problee.exceptions import (
|
|
172
|
+
AuthenticationError,
|
|
173
|
+
RateLimitError,
|
|
174
|
+
NotFoundError,
|
|
175
|
+
ValidationError,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
client = ProbClient(api_key="pk_live_...")
|
|
179
|
+
|
|
180
|
+
try:
|
|
181
|
+
market = client.markets.get("0xinvalid")
|
|
182
|
+
except NotFoundError:
|
|
183
|
+
print("Market not found")
|
|
184
|
+
except AuthenticationError:
|
|
185
|
+
print("Invalid API key")
|
|
186
|
+
except RateLimitError as e:
|
|
187
|
+
print(f"Rate limited. Retry after {e.retry_after} seconds")
|
|
188
|
+
except ValidationError as e:
|
|
189
|
+
print(f"Invalid request: {e.errors}")
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Builder Attribution
|
|
193
|
+
|
|
194
|
+
If you're building an app on Problee, you can include your builder ID:
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
client = ProbClient(
|
|
198
|
+
api_key="pk_live_...",
|
|
199
|
+
builder_id="your-builder-id",
|
|
200
|
+
)
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## API Documentation
|
|
204
|
+
|
|
205
|
+
For full API documentation, visit: https://docs.problee.com
|
|
206
|
+
|
|
207
|
+
## License
|
|
208
|
+
|
|
209
|
+
MIT License - see LICENSE file for details.
|
problee-0.1.0/README.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Problee Python SDK
|
|
2
|
+
|
|
3
|
+
Official Python SDK for the Problee prediction market API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install problee
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
For WebSocket support:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install problee[websocket]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from problee import ProbClient
|
|
21
|
+
|
|
22
|
+
# Initialize client with your API key
|
|
23
|
+
client = ProbClient(api_key="pk_live_...")
|
|
24
|
+
|
|
25
|
+
# List open markets
|
|
26
|
+
markets = client.markets.list(status="open")
|
|
27
|
+
for market in markets.markets:
|
|
28
|
+
print(f"{market.question}")
|
|
29
|
+
print(f" YES: {market.prices.yes:.2%}")
|
|
30
|
+
print(f" NO: {market.prices.no:.2%}")
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
|
|
35
|
+
- **Markets API**: List, filter, and get market details
|
|
36
|
+
- **Positions API**: Check wallet positions
|
|
37
|
+
- **Quotes API**: Get trade quotes and build transactions
|
|
38
|
+
- **SSE Streaming**: Real-time price updates via Server-Sent Events
|
|
39
|
+
- **WebSocket**: Real-time market updates via WebSocket
|
|
40
|
+
|
|
41
|
+
## Usage Examples
|
|
42
|
+
|
|
43
|
+
### List Markets
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
# List all open markets
|
|
47
|
+
markets = client.markets.list(status="open")
|
|
48
|
+
|
|
49
|
+
# Filter by category
|
|
50
|
+
crypto_markets = client.markets.list(category="crypto")
|
|
51
|
+
|
|
52
|
+
# Sort by volume
|
|
53
|
+
trending = client.markets.list(sort="volume_24h")
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Get Market Details
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
# Get single market
|
|
60
|
+
market = client.markets.get("0x1234...")
|
|
61
|
+
print(f"Question: {market.question}")
|
|
62
|
+
print(f"Status: {market.status}")
|
|
63
|
+
print(f"YES Price: {market.prices.yes}")
|
|
64
|
+
|
|
65
|
+
# Get price history
|
|
66
|
+
history = client.markets.get_history("0x1234...", interval="1h")
|
|
67
|
+
|
|
68
|
+
# Get recent trades
|
|
69
|
+
trades = client.markets.get_trades("0x1234...", limit=50)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Get Quote
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
# Get quote to buy YES shares
|
|
76
|
+
quote = client.quotes.get(
|
|
77
|
+
market_id="0x1234...",
|
|
78
|
+
side="buy",
|
|
79
|
+
outcome="yes",
|
|
80
|
+
amount="1000000000000000000", # 1 USDC in wei
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
print(f"Price: {quote.price:.4f}")
|
|
84
|
+
print(f"Shares: {quote.shares_out}")
|
|
85
|
+
print(f"Price Impact: {quote.price_impact:.2%}")
|
|
86
|
+
print(f"Quote ID: {quote.quote_id}")
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Check Positions
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
# Get all positions for a wallet
|
|
93
|
+
positions = client.positions.list("0xYourWallet...")
|
|
94
|
+
for pos in positions.positions:
|
|
95
|
+
print(f"Market: {pos.market_address}")
|
|
96
|
+
print(f"YES Shares: {pos.yes_shares}")
|
|
97
|
+
print(f"NO Shares: {pos.no_shares}")
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Stream Prices (SSE)
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
# Stream real-time price updates
|
|
104
|
+
for update in client.stream.prices():
|
|
105
|
+
if update.event_type == "price":
|
|
106
|
+
print(f"Price: YES={update.data['yes']}, NO={update.data['no']}")
|
|
107
|
+
elif update.event_type == "tokenPrice":
|
|
108
|
+
print(f"Token: {update.data['symbol']} = ${update.data['price']}")
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### WebSocket Streaming
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
import asyncio
|
|
115
|
+
|
|
116
|
+
async def stream_updates():
|
|
117
|
+
async with client.ws.connect() as ws:
|
|
118
|
+
# Subscribe to market updates
|
|
119
|
+
await ws.subscribe("market", "0x1234...")
|
|
120
|
+
|
|
121
|
+
async for msg in ws:
|
|
122
|
+
if msg.type == "price_update":
|
|
123
|
+
print(f"Price: {msg.data['prices']}")
|
|
124
|
+
elif msg.type == "trade":
|
|
125
|
+
print(f"Trade: {msg.data}")
|
|
126
|
+
|
|
127
|
+
asyncio.run(stream_updates())
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Error Handling
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from problee import ProbClient
|
|
134
|
+
from problee.exceptions import (
|
|
135
|
+
AuthenticationError,
|
|
136
|
+
RateLimitError,
|
|
137
|
+
NotFoundError,
|
|
138
|
+
ValidationError,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
client = ProbClient(api_key="pk_live_...")
|
|
142
|
+
|
|
143
|
+
try:
|
|
144
|
+
market = client.markets.get("0xinvalid")
|
|
145
|
+
except NotFoundError:
|
|
146
|
+
print("Market not found")
|
|
147
|
+
except AuthenticationError:
|
|
148
|
+
print("Invalid API key")
|
|
149
|
+
except RateLimitError as e:
|
|
150
|
+
print(f"Rate limited. Retry after {e.retry_after} seconds")
|
|
151
|
+
except ValidationError as e:
|
|
152
|
+
print(f"Invalid request: {e.errors}")
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Builder Attribution
|
|
156
|
+
|
|
157
|
+
If you're building an app on Problee, you can include your builder ID:
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
client = ProbClient(
|
|
161
|
+
api_key="pk_live_...",
|
|
162
|
+
builder_id="your-builder-id",
|
|
163
|
+
)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## API Documentation
|
|
167
|
+
|
|
168
|
+
For full API documentation, visit: https://docs.problee.com
|
|
169
|
+
|
|
170
|
+
## License
|
|
171
|
+
|
|
172
|
+
MIT License - see LICENSE file for details.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Problee Python SDK
|
|
3
|
+
|
|
4
|
+
Official Python client for the Problee prediction market API.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
__version__ = "0.1.0"
|
|
8
|
+
|
|
9
|
+
from .client import ProbClient
|
|
10
|
+
from .models.market import Market, MarketStatus, MarketCategory
|
|
11
|
+
from .models.position import Position
|
|
12
|
+
from .models.quote import Quote
|
|
13
|
+
from .exceptions import (
|
|
14
|
+
ProbError,
|
|
15
|
+
AuthenticationError,
|
|
16
|
+
RateLimitError,
|
|
17
|
+
NotFoundError,
|
|
18
|
+
ValidationError,
|
|
19
|
+
APIError,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"ProbClient",
|
|
24
|
+
"Market",
|
|
25
|
+
"MarketStatus",
|
|
26
|
+
"MarketCategory",
|
|
27
|
+
"Position",
|
|
28
|
+
"Quote",
|
|
29
|
+
"ProbError",
|
|
30
|
+
"AuthenticationError",
|
|
31
|
+
"RateLimitError",
|
|
32
|
+
"NotFoundError",
|
|
33
|
+
"ValidationError",
|
|
34
|
+
"APIError",
|
|
35
|
+
]
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Markets API
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Optional, List, TYPE_CHECKING
|
|
6
|
+
from ..models.market import Market, MarketListResponse, MarketStatus, MarketCategory
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from ..client import ProbClient
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MarketsAPI:
|
|
13
|
+
"""Markets API methods."""
|
|
14
|
+
|
|
15
|
+
def __init__(self, client: "ProbClient"):
|
|
16
|
+
self._client = client
|
|
17
|
+
|
|
18
|
+
def list(
|
|
19
|
+
self,
|
|
20
|
+
status: Optional[str] = None,
|
|
21
|
+
category: Optional[str] = None,
|
|
22
|
+
sort: Optional[str] = None,
|
|
23
|
+
limit: int = 20,
|
|
24
|
+
cursor: Optional[str] = None,
|
|
25
|
+
) -> MarketListResponse:
|
|
26
|
+
"""
|
|
27
|
+
List markets with optional filters.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
status: Filter by status (open, closed, resolved)
|
|
31
|
+
category: Filter by category (sports, politics, crypto, entertainment, other)
|
|
32
|
+
sort: Sort order (new, trending, volume_24h, closing_soon)
|
|
33
|
+
limit: Max results per page (default 20, max 100)
|
|
34
|
+
cursor: Pagination cursor
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
MarketListResponse with list of markets and pagination info
|
|
38
|
+
"""
|
|
39
|
+
params = {"limit": limit}
|
|
40
|
+
if status:
|
|
41
|
+
params["status"] = status
|
|
42
|
+
if category:
|
|
43
|
+
params["category"] = category
|
|
44
|
+
if sort:
|
|
45
|
+
params["sort"] = sort
|
|
46
|
+
if cursor:
|
|
47
|
+
params["cursor"] = cursor
|
|
48
|
+
|
|
49
|
+
response = self._client._request("GET", "/api/v1/markets", params=params)
|
|
50
|
+
return MarketListResponse.from_dict(response)
|
|
51
|
+
|
|
52
|
+
def get(self, market_id: str) -> Market:
|
|
53
|
+
"""
|
|
54
|
+
Get a single market by ID (address).
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
market_id: Market address
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
Market object
|
|
61
|
+
"""
|
|
62
|
+
response = self._client._request("GET", f"/api/v1/markets/{market_id}")
|
|
63
|
+
return Market.from_dict(response)
|
|
64
|
+
|
|
65
|
+
def get_history(
|
|
66
|
+
self,
|
|
67
|
+
market_id: str,
|
|
68
|
+
interval: str = "1h",
|
|
69
|
+
limit: int = 100,
|
|
70
|
+
) -> List[dict]:
|
|
71
|
+
"""
|
|
72
|
+
Get price history for a market.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
market_id: Market address
|
|
76
|
+
interval: Time bucket (1m, 5m, 1h, 1d)
|
|
77
|
+
limit: Max data points
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
List of price history points
|
|
81
|
+
"""
|
|
82
|
+
params = {"interval": interval, "limit": limit}
|
|
83
|
+
response = self._client._request(
|
|
84
|
+
"GET", f"/api/v1/markets/{market_id}/history", params=params
|
|
85
|
+
)
|
|
86
|
+
return response.get("history", [])
|
|
87
|
+
|
|
88
|
+
def get_trades(
|
|
89
|
+
self,
|
|
90
|
+
market_id: str,
|
|
91
|
+
limit: int = 50,
|
|
92
|
+
) -> List[dict]:
|
|
93
|
+
"""
|
|
94
|
+
Get recent trades for a market.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
market_id: Market address
|
|
98
|
+
limit: Max trades to return
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
List of trade objects
|
|
102
|
+
"""
|
|
103
|
+
params = {"limit": limit}
|
|
104
|
+
response = self._client._request(
|
|
105
|
+
"GET", f"/api/v1/markets/{market_id}/trades", params=params
|
|
106
|
+
)
|
|
107
|
+
return response.get("trades", [])
|
|
108
|
+
|
|
109
|
+
def list_open(self, **kwargs) -> MarketListResponse:
|
|
110
|
+
"""List open markets."""
|
|
111
|
+
return self.list(status="open", **kwargs)
|
|
112
|
+
|
|
113
|
+
def list_resolved(self, **kwargs) -> MarketListResponse:
|
|
114
|
+
"""List resolved markets."""
|
|
115
|
+
return self.list(status="resolved", **kwargs)
|
|
116
|
+
|
|
117
|
+
def list_by_category(self, category: str, **kwargs) -> MarketListResponse:
|
|
118
|
+
"""List markets by category."""
|
|
119
|
+
return self.list(category=category, **kwargs)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Positions API
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Optional, TYPE_CHECKING
|
|
6
|
+
from ..models.position import Position, PositionListResponse
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from ..client import ProbClient
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PositionsAPI:
|
|
13
|
+
"""Positions API methods."""
|
|
14
|
+
|
|
15
|
+
def __init__(self, client: "ProbClient"):
|
|
16
|
+
self._client = client
|
|
17
|
+
|
|
18
|
+
def list(self, address: str) -> PositionListResponse:
|
|
19
|
+
"""
|
|
20
|
+
Get all positions for a wallet address.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
address: Wallet address (0x...)
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
PositionListResponse with list of positions
|
|
27
|
+
"""
|
|
28
|
+
response = self._client._request("GET", f"/api/v1/positions/{address}")
|
|
29
|
+
return PositionListResponse.from_dict(response)
|
|
30
|
+
|
|
31
|
+
def get(self, address: str, market_id: str) -> Optional[Position]:
|
|
32
|
+
"""
|
|
33
|
+
Get position for a specific market.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
address: Wallet address
|
|
37
|
+
market_id: Market address
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
Position or None if no position
|
|
41
|
+
"""
|
|
42
|
+
params = {"market_id": market_id}
|
|
43
|
+
response = self._client._request(
|
|
44
|
+
"GET", f"/api/v1/positions/{address}", params=params
|
|
45
|
+
)
|
|
46
|
+
positions = response.get("positions", [])
|
|
47
|
+
if positions:
|
|
48
|
+
return Position.from_dict(positions[0])
|
|
49
|
+
return None
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Quotes API
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Optional, TYPE_CHECKING
|
|
6
|
+
from ..models.quote import Quote, TransactionData
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from ..client import ProbClient
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class QuotesAPI:
|
|
13
|
+
"""Quotes API methods."""
|
|
14
|
+
|
|
15
|
+
def __init__(self, client: "ProbClient"):
|
|
16
|
+
self._client = client
|
|
17
|
+
|
|
18
|
+
def get(
|
|
19
|
+
self,
|
|
20
|
+
market_id: str,
|
|
21
|
+
side: str,
|
|
22
|
+
outcome: str,
|
|
23
|
+
amount: str,
|
|
24
|
+
slippage_bps: int = 50,
|
|
25
|
+
) -> Quote:
|
|
26
|
+
"""
|
|
27
|
+
Get a quote for a trade.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
market_id: Market address
|
|
31
|
+
side: "buy" or "sell"
|
|
32
|
+
outcome: "yes", "no", or "draw"
|
|
33
|
+
amount: Amount in wei (as string)
|
|
34
|
+
slippage_bps: Slippage tolerance in basis points (default 50 = 0.5%)
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
Quote object with price and execution details
|
|
38
|
+
"""
|
|
39
|
+
payload = {
|
|
40
|
+
"market_id": market_id,
|
|
41
|
+
"side": side,
|
|
42
|
+
"outcome": outcome,
|
|
43
|
+
"amount": amount,
|
|
44
|
+
"slippage_bps": slippage_bps,
|
|
45
|
+
}
|
|
46
|
+
response = self._client._request("POST", "/api/v1/quote", json=payload)
|
|
47
|
+
return Quote.from_dict(response)
|
|
48
|
+
|
|
49
|
+
def get_buy_yes(self, market_id: str, amount: str, **kwargs) -> Quote:
|
|
50
|
+
"""Get quote to buy YES shares."""
|
|
51
|
+
return self.get(market_id, "buy", "yes", amount, **kwargs)
|
|
52
|
+
|
|
53
|
+
def get_buy_no(self, market_id: str, amount: str, **kwargs) -> Quote:
|
|
54
|
+
"""Get quote to buy NO shares."""
|
|
55
|
+
return self.get(market_id, "buy", "no", amount, **kwargs)
|
|
56
|
+
|
|
57
|
+
def get_sell_yes(self, market_id: str, amount: str, **kwargs) -> Quote:
|
|
58
|
+
"""Get quote to sell YES shares."""
|
|
59
|
+
return self.get(market_id, "sell", "yes", amount, **kwargs)
|
|
60
|
+
|
|
61
|
+
def get_sell_no(self, market_id: str, amount: str, **kwargs) -> Quote:
|
|
62
|
+
"""Get quote to sell NO shares."""
|
|
63
|
+
return self.get(market_id, "sell", "no", amount, **kwargs)
|
|
64
|
+
|
|
65
|
+
def build_transaction(
|
|
66
|
+
self,
|
|
67
|
+
quote_id: str,
|
|
68
|
+
rpc_url: str,
|
|
69
|
+
) -> TransactionData:
|
|
70
|
+
"""
|
|
71
|
+
Build transaction data from a quote.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
quote_id: Quote ID from get() response
|
|
75
|
+
rpc_url: RPC URL for the chain
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
TransactionData with calldata for execution
|
|
79
|
+
"""
|
|
80
|
+
payload = {"quote_id": quote_id}
|
|
81
|
+
headers = {"X-RPC-URL": rpc_url}
|
|
82
|
+
response = self._client._request(
|
|
83
|
+
"POST", "/api/v1/tx/build", json=payload, headers=headers
|
|
84
|
+
)
|
|
85
|
+
return TransactionData.from_dict(response)
|