predict-sdk 0.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.
- predict_sdk-0.0.1/.gitignore +110 -0
- predict_sdk-0.0.1/LICENSE +21 -0
- predict_sdk-0.0.1/PKG-INFO +308 -0
- predict_sdk-0.0.1/README.md +284 -0
- predict_sdk-0.0.1/pyproject.toml +79 -0
- predict_sdk-0.0.1/src/predict_sdk/__init__.py +135 -0
- predict_sdk-0.0.1/src/predict_sdk/_internal/__init__.py +15 -0
- predict_sdk-0.0.1/src/predict_sdk/_internal/contracts.py +206 -0
- predict_sdk-0.0.1/src/predict_sdk/_internal/utils.py +170 -0
- predict_sdk-0.0.1/src/predict_sdk/abis/CTFExchange.json +1940 -0
- predict_sdk-0.0.1/src/predict_sdk/abis/ConditionalTokens.json +1313 -0
- predict_sdk-0.0.1/src/predict_sdk/abis/ECDSAValidator.json +279 -0
- predict_sdk-0.0.1/src/predict_sdk/abis/ERC20.json +221 -0
- predict_sdk-0.0.1/src/predict_sdk/abis/Kernel.json +1224 -0
- predict_sdk-0.0.1/src/predict_sdk/abis/NegRiskAdapter.json +1323 -0
- predict_sdk-0.0.1/src/predict_sdk/abis/NegRiskCtfExchange.json +1945 -0
- predict_sdk-0.0.1/src/predict_sdk/abis/YieldBearingConditionalTokens.json +1756 -0
- predict_sdk-0.0.1/src/predict_sdk/abis/__init__.py +39 -0
- predict_sdk-0.0.1/src/predict_sdk/constants.py +142 -0
- predict_sdk-0.0.1/src/predict_sdk/errors.py +84 -0
- predict_sdk-0.0.1/src/predict_sdk/logger.py +79 -0
- predict_sdk-0.0.1/src/predict_sdk/order_builder.py +1258 -0
- predict_sdk-0.0.1/src/predict_sdk/py.typed +0 -0
- predict_sdk-0.0.1/src/predict_sdk/types.py +243 -0
- predict_sdk-0.0.1/tests/__init__.py +1 -0
- predict_sdk-0.0.1/tests/conftest.py +68 -0
- predict_sdk-0.0.1/tests/test_amounts.py +228 -0
- predict_sdk-0.0.1/tests/test_order_builder.py +566 -0
- predict_sdk-0.0.1/tests/test_utils.py +152 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
*.manifest
|
|
31
|
+
*.spec
|
|
32
|
+
|
|
33
|
+
# Installer logs
|
|
34
|
+
pip-log.txt
|
|
35
|
+
pip-delete-this-directory.txt
|
|
36
|
+
|
|
37
|
+
# Unit test / coverage reports
|
|
38
|
+
htmlcov/
|
|
39
|
+
.tox/
|
|
40
|
+
.nox/
|
|
41
|
+
.coverage
|
|
42
|
+
.coverage.*
|
|
43
|
+
.cache
|
|
44
|
+
nosetests.xml
|
|
45
|
+
coverage.xml
|
|
46
|
+
*.cover
|
|
47
|
+
*.py,cover
|
|
48
|
+
.hypothesis/
|
|
49
|
+
.pytest_cache/
|
|
50
|
+
pytest_cache/
|
|
51
|
+
|
|
52
|
+
# Translations
|
|
53
|
+
*.mo
|
|
54
|
+
*.pot
|
|
55
|
+
|
|
56
|
+
# Environments
|
|
57
|
+
.env
|
|
58
|
+
.venv
|
|
59
|
+
env/
|
|
60
|
+
venv/
|
|
61
|
+
ENV/
|
|
62
|
+
env.bak/
|
|
63
|
+
venv.bak/
|
|
64
|
+
venv-test/
|
|
65
|
+
|
|
66
|
+
# Spyder project settings
|
|
67
|
+
.spyderproject
|
|
68
|
+
.spyproject
|
|
69
|
+
|
|
70
|
+
# Rope project settings
|
|
71
|
+
.ropeproject
|
|
72
|
+
|
|
73
|
+
# mkdocs documentation
|
|
74
|
+
/site
|
|
75
|
+
|
|
76
|
+
# mypy
|
|
77
|
+
.mypy_cache/
|
|
78
|
+
.dmypy.json
|
|
79
|
+
dmypy.json
|
|
80
|
+
|
|
81
|
+
# Pyre type checker
|
|
82
|
+
.pyre/
|
|
83
|
+
|
|
84
|
+
# pytype static type analyzer
|
|
85
|
+
.pytype/
|
|
86
|
+
|
|
87
|
+
# Cython debug symbols
|
|
88
|
+
cython_debug/
|
|
89
|
+
|
|
90
|
+
# IDE
|
|
91
|
+
.idea/
|
|
92
|
+
.vscode/
|
|
93
|
+
*.swp
|
|
94
|
+
*.swo
|
|
95
|
+
*~
|
|
96
|
+
|
|
97
|
+
# OS
|
|
98
|
+
.DS_Store
|
|
99
|
+
Thumbs.db
|
|
100
|
+
|
|
101
|
+
# Local development
|
|
102
|
+
.python-version
|
|
103
|
+
.pdm.toml
|
|
104
|
+
pdm.lock
|
|
105
|
+
|
|
106
|
+
# Secrets (never commit these)
|
|
107
|
+
*.pem
|
|
108
|
+
*.key
|
|
109
|
+
.env.local
|
|
110
|
+
.env.*.local
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 predict.fun
|
|
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.
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: predict_sdk
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A Python SDK to help developers interface with the Predict.fun protocol
|
|
5
|
+
Project-URL: Homepage, https://predict.fun/
|
|
6
|
+
Project-URL: Documentation, https://dev.predict.fun/
|
|
7
|
+
Project-URL: Repository, https://github.com/PredictDotFun/sdk-python
|
|
8
|
+
Project-URL: Issues, https://github.com/PredictDotFun/sdk-python/issues
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Requires-Dist: eth-abi>=5.0.0
|
|
13
|
+
Requires-Dist: eth-account>=0.11.0
|
|
14
|
+
Requires-Dist: eth-typing>=4.0.0
|
|
15
|
+
Requires-Dist: web3<8.0.0,>=6.0.0
|
|
16
|
+
Provides-Extra: dev
|
|
17
|
+
Requires-Dist: hypothesis>=6.0.0; extra == 'dev'
|
|
18
|
+
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
19
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
20
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
21
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
22
|
+
Requires-Dist: ruff>=0.1.0; extra == 'dev'
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# Predict SDK for Python
|
|
26
|
+
|
|
27
|
+
A Python SDK to help developers interface with the [Predict.fun](https://predict.fun/) protocol.
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install predict-sdk
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from predict_sdk import (
|
|
39
|
+
OrderBuilder,
|
|
40
|
+
ChainId,
|
|
41
|
+
Side,
|
|
42
|
+
BuildOrderInput,
|
|
43
|
+
LimitHelperInput,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# Create an OrderBuilder without a signer (read-only)
|
|
47
|
+
builder = OrderBuilder.make(ChainId.BNB_MAINNET)
|
|
48
|
+
|
|
49
|
+
# Calculate order amounts for a LIMIT order
|
|
50
|
+
amounts = builder.get_limit_order_amounts(
|
|
51
|
+
LimitHelperInput(
|
|
52
|
+
side=Side.BUY,
|
|
53
|
+
price_per_share_wei=500000000000000000, # 0.5 USDT per share
|
|
54
|
+
quantity_wei=10000000000000000000, # 10 shares
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
print(f"Maker Amount: {amounts.maker_amount}")
|
|
59
|
+
print(f"Taker Amount: {amounts.taker_amount}")
|
|
60
|
+
|
|
61
|
+
# Build an order
|
|
62
|
+
order = builder.build_order(
|
|
63
|
+
"LIMIT",
|
|
64
|
+
BuildOrderInput(
|
|
65
|
+
side=Side.BUY,
|
|
66
|
+
token_id="YOUR_TOKEN_ID",
|
|
67
|
+
maker_amount=str(amounts.maker_amount),
|
|
68
|
+
taker_amount=str(amounts.taker_amount),
|
|
69
|
+
fee_rate_bps=100, # Get from GET /markets endpoint
|
|
70
|
+
),
|
|
71
|
+
)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## With a Signer
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from eth_account import Account
|
|
78
|
+
from predict_sdk import OrderBuilder, ChainId
|
|
79
|
+
|
|
80
|
+
# Create from private key
|
|
81
|
+
private_key = "0x..." # Your private key
|
|
82
|
+
signer = Account.from_key(private_key)
|
|
83
|
+
|
|
84
|
+
# Or pass private key directly
|
|
85
|
+
builder = OrderBuilder.make(ChainId.BNB_MAINNET, private_key)
|
|
86
|
+
|
|
87
|
+
# Now you can sign orders and interact with contracts
|
|
88
|
+
typed_data = builder.build_typed_data(
|
|
89
|
+
order,
|
|
90
|
+
is_neg_risk=False,
|
|
91
|
+
is_yield_bearing=False,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
signed_order = builder.sign_typed_data_order(typed_data)
|
|
95
|
+
print(f"Signature: {signed_order.signature}")
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Setting Approvals
|
|
99
|
+
|
|
100
|
+
Before trading, you need to set approvals for the exchange contracts:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
# Set all approvals at once
|
|
104
|
+
result = builder.set_approvals(is_yield_bearing=False)
|
|
105
|
+
|
|
106
|
+
if result.success:
|
|
107
|
+
print("All approvals set successfully!")
|
|
108
|
+
else:
|
|
109
|
+
print("Some approvals failed")
|
|
110
|
+
for tx in result.transactions:
|
|
111
|
+
if not tx.success:
|
|
112
|
+
print(f"Failed: {tx.cause}")
|
|
113
|
+
|
|
114
|
+
# Or set individual approvals
|
|
115
|
+
builder.set_ctf_exchange_approval(is_neg_risk=False, is_yield_bearing=False)
|
|
116
|
+
builder.set_ctf_exchange_allowance(is_neg_risk=False, is_yield_bearing=False)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Using Predict Accounts (Smart Wallets)
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from predict_sdk import OrderBuilder, ChainId, OrderBuilderOptions
|
|
123
|
+
|
|
124
|
+
builder = OrderBuilder.make(
|
|
125
|
+
ChainId.BNB_MAINNET,
|
|
126
|
+
private_key, # Must be the Privy exported wallet
|
|
127
|
+
OrderBuilderOptions(
|
|
128
|
+
predict_account="0x...", # Your Predict account address
|
|
129
|
+
),
|
|
130
|
+
)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Market Orders
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from predict_sdk import MarketHelperInput, MarketHelperValueInput
|
|
137
|
+
|
|
138
|
+
# Market order by quantity (number of shares)
|
|
139
|
+
amounts = builder.get_market_order_amounts(
|
|
140
|
+
MarketHelperInput(
|
|
141
|
+
side=Side.BUY,
|
|
142
|
+
quantity_wei=10000000000000000000, # 10 shares
|
|
143
|
+
),
|
|
144
|
+
orderbook, # From GET /orderbook/{marketId}
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
# Market BUY by value (total USDT to spend)
|
|
148
|
+
amounts = builder.get_market_order_amounts(
|
|
149
|
+
MarketHelperValueInput(
|
|
150
|
+
side=Side.BUY,
|
|
151
|
+
value_wei=5000000000000000000, # 5 USDT
|
|
152
|
+
),
|
|
153
|
+
orderbook,
|
|
154
|
+
)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Redeeming Positions
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
# For standard markets
|
|
161
|
+
result = builder.redeem_positions(
|
|
162
|
+
condition_id="0x...",
|
|
163
|
+
index_set=1, # 1 or 2
|
|
164
|
+
is_neg_risk=False,
|
|
165
|
+
is_yield_bearing=False,
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
# For NegRisk (winner-takes-all) markets
|
|
169
|
+
result = builder.redeem_positions(
|
|
170
|
+
condition_id="0x...",
|
|
171
|
+
index_set=1,
|
|
172
|
+
amount=1000000000000000000, # Required for NegRisk
|
|
173
|
+
is_neg_risk=True,
|
|
174
|
+
is_yield_bearing=False,
|
|
175
|
+
)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Merging Positions
|
|
179
|
+
|
|
180
|
+
Merge both outcome tokens back into collateral (USDT). Useful when holding equal amounts of both YES and NO positions.
|
|
181
|
+
|
|
182
|
+
```python
|
|
183
|
+
# For standard markets
|
|
184
|
+
result = builder.merge_positions(
|
|
185
|
+
condition_id="0x...",
|
|
186
|
+
amount=1000000000000000000, # Amount to merge (in wei)
|
|
187
|
+
is_neg_risk=False,
|
|
188
|
+
is_yield_bearing=False,
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
# For NegRisk (winner-takes-all) markets
|
|
192
|
+
result = builder.merge_positions(
|
|
193
|
+
condition_id="0x...",
|
|
194
|
+
amount=1000000000000000000,
|
|
195
|
+
is_neg_risk=True,
|
|
196
|
+
is_yield_bearing=False,
|
|
197
|
+
)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Canceling Orders
|
|
201
|
+
|
|
202
|
+
```python
|
|
203
|
+
from predict_sdk import CancelOrdersOptions
|
|
204
|
+
|
|
205
|
+
result = builder.cancel_orders(
|
|
206
|
+
orders=[order1, order2],
|
|
207
|
+
options=CancelOrdersOptions(
|
|
208
|
+
is_neg_risk=False,
|
|
209
|
+
is_yield_bearing=False,
|
|
210
|
+
),
|
|
211
|
+
)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Checking Balance
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
balance = builder.balance_of("USDT")
|
|
218
|
+
print(f"USDT Balance: {balance}")
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Async Support
|
|
222
|
+
|
|
223
|
+
All contract interaction methods have async versions:
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
import asyncio
|
|
227
|
+
|
|
228
|
+
async def main():
|
|
229
|
+
balance = await builder.balance_of_async("USDT")
|
|
230
|
+
result = await builder.set_approvals_async(is_yield_bearing=False)
|
|
231
|
+
|
|
232
|
+
asyncio.run(main())
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## API Reference
|
|
236
|
+
|
|
237
|
+
### OrderBuilder
|
|
238
|
+
|
|
239
|
+
The main class for building and signing orders.
|
|
240
|
+
|
|
241
|
+
#### Factory Method
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
OrderBuilder.make(
|
|
245
|
+
chain_id: ChainId,
|
|
246
|
+
signer: LocalAccount | str | None = None,
|
|
247
|
+
options: OrderBuilderOptions | None = None,
|
|
248
|
+
) -> OrderBuilder
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
#### Order Building Methods
|
|
252
|
+
|
|
253
|
+
- `get_limit_order_amounts(data: LimitHelperInput) -> OrderAmounts`
|
|
254
|
+
- `get_market_order_amounts(data: MarketHelperInput | MarketHelperValueInput, book: Book) -> OrderAmounts`
|
|
255
|
+
- `build_order(strategy: "MARKET" | "LIMIT", data: BuildOrderInput) -> Order`
|
|
256
|
+
- `build_typed_data(order: Order, *, is_neg_risk: bool, is_yield_bearing: bool) -> EIP712TypedData`
|
|
257
|
+
- `build_typed_data_hash(typed_data: EIP712TypedData) -> str`
|
|
258
|
+
- `sign_typed_data_order(typed_data: EIP712TypedData) -> SignedOrder`
|
|
259
|
+
|
|
260
|
+
#### Approval Methods
|
|
261
|
+
|
|
262
|
+
- `set_approvals(*, is_yield_bearing: bool = False) -> SetApprovalsResult`
|
|
263
|
+
- `set_ctf_exchange_approval(*, is_neg_risk: bool, is_yield_bearing: bool, approved: bool = True) -> TransactionResult`
|
|
264
|
+
- `set_neg_risk_adapter_approval(*, is_yield_bearing: bool, approved: bool = True) -> TransactionResult`
|
|
265
|
+
- `set_ctf_exchange_allowance(*, is_neg_risk: bool, is_yield_bearing: bool, amount: int = MAX_UINT256) -> TransactionResult`
|
|
266
|
+
|
|
267
|
+
#### Position Management
|
|
268
|
+
|
|
269
|
+
- `balance_of(token: "USDT" = "USDT", address: str | None = None) -> int`
|
|
270
|
+
- `redeem_positions(condition_id: str, index_set: 1 | 2, amount: int | None = None, *, is_neg_risk: bool, is_yield_bearing: bool) -> TransactionResult`
|
|
271
|
+
- `merge_positions(condition_id: str, amount: int, *, is_neg_risk: bool, is_yield_bearing: bool) -> TransactionResult`
|
|
272
|
+
|
|
273
|
+
#### Order Cancellation
|
|
274
|
+
|
|
275
|
+
- `cancel_orders(orders: list[Order], options: CancelOrdersOptions) -> TransactionResult`
|
|
276
|
+
- `validate_token_ids(token_ids: list[int], *, is_neg_risk: bool, is_yield_bearing: bool) -> bool`
|
|
277
|
+
|
|
278
|
+
### Types
|
|
279
|
+
|
|
280
|
+
```python
|
|
281
|
+
from predict_sdk import (
|
|
282
|
+
ChainId, # BNB_MAINNET (56), BNB_TESTNET (97)
|
|
283
|
+
Side, # BUY (0), SELL (1)
|
|
284
|
+
SignatureType, # EOA (0), POLY_PROXY (1), POLY_GNOSIS_SAFE (2)
|
|
285
|
+
Order,
|
|
286
|
+
SignedOrder,
|
|
287
|
+
BuildOrderInput,
|
|
288
|
+
OrderAmounts,
|
|
289
|
+
LimitHelperInput,
|
|
290
|
+
MarketHelperInput,
|
|
291
|
+
MarketHelperValueInput,
|
|
292
|
+
Book,
|
|
293
|
+
EIP712TypedData,
|
|
294
|
+
TransactionResult,
|
|
295
|
+
SetApprovalsResult,
|
|
296
|
+
CancelOrdersOptions,
|
|
297
|
+
OrderBuilderOptions,
|
|
298
|
+
)
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Requirements
|
|
302
|
+
|
|
303
|
+
- Python >= 3.11
|
|
304
|
+
- web3.py >= 6.0.0
|
|
305
|
+
|
|
306
|
+
## License
|
|
307
|
+
|
|
308
|
+
MIT
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
# Predict SDK for Python
|
|
2
|
+
|
|
3
|
+
A Python SDK to help developers interface with the [Predict.fun](https://predict.fun/) protocol.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install predict-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from predict_sdk import (
|
|
15
|
+
OrderBuilder,
|
|
16
|
+
ChainId,
|
|
17
|
+
Side,
|
|
18
|
+
BuildOrderInput,
|
|
19
|
+
LimitHelperInput,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# Create an OrderBuilder without a signer (read-only)
|
|
23
|
+
builder = OrderBuilder.make(ChainId.BNB_MAINNET)
|
|
24
|
+
|
|
25
|
+
# Calculate order amounts for a LIMIT order
|
|
26
|
+
amounts = builder.get_limit_order_amounts(
|
|
27
|
+
LimitHelperInput(
|
|
28
|
+
side=Side.BUY,
|
|
29
|
+
price_per_share_wei=500000000000000000, # 0.5 USDT per share
|
|
30
|
+
quantity_wei=10000000000000000000, # 10 shares
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
print(f"Maker Amount: {amounts.maker_amount}")
|
|
35
|
+
print(f"Taker Amount: {amounts.taker_amount}")
|
|
36
|
+
|
|
37
|
+
# Build an order
|
|
38
|
+
order = builder.build_order(
|
|
39
|
+
"LIMIT",
|
|
40
|
+
BuildOrderInput(
|
|
41
|
+
side=Side.BUY,
|
|
42
|
+
token_id="YOUR_TOKEN_ID",
|
|
43
|
+
maker_amount=str(amounts.maker_amount),
|
|
44
|
+
taker_amount=str(amounts.taker_amount),
|
|
45
|
+
fee_rate_bps=100, # Get from GET /markets endpoint
|
|
46
|
+
),
|
|
47
|
+
)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## With a Signer
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from eth_account import Account
|
|
54
|
+
from predict_sdk import OrderBuilder, ChainId
|
|
55
|
+
|
|
56
|
+
# Create from private key
|
|
57
|
+
private_key = "0x..." # Your private key
|
|
58
|
+
signer = Account.from_key(private_key)
|
|
59
|
+
|
|
60
|
+
# Or pass private key directly
|
|
61
|
+
builder = OrderBuilder.make(ChainId.BNB_MAINNET, private_key)
|
|
62
|
+
|
|
63
|
+
# Now you can sign orders and interact with contracts
|
|
64
|
+
typed_data = builder.build_typed_data(
|
|
65
|
+
order,
|
|
66
|
+
is_neg_risk=False,
|
|
67
|
+
is_yield_bearing=False,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
signed_order = builder.sign_typed_data_order(typed_data)
|
|
71
|
+
print(f"Signature: {signed_order.signature}")
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Setting Approvals
|
|
75
|
+
|
|
76
|
+
Before trading, you need to set approvals for the exchange contracts:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
# Set all approvals at once
|
|
80
|
+
result = builder.set_approvals(is_yield_bearing=False)
|
|
81
|
+
|
|
82
|
+
if result.success:
|
|
83
|
+
print("All approvals set successfully!")
|
|
84
|
+
else:
|
|
85
|
+
print("Some approvals failed")
|
|
86
|
+
for tx in result.transactions:
|
|
87
|
+
if not tx.success:
|
|
88
|
+
print(f"Failed: {tx.cause}")
|
|
89
|
+
|
|
90
|
+
# Or set individual approvals
|
|
91
|
+
builder.set_ctf_exchange_approval(is_neg_risk=False, is_yield_bearing=False)
|
|
92
|
+
builder.set_ctf_exchange_allowance(is_neg_risk=False, is_yield_bearing=False)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Using Predict Accounts (Smart Wallets)
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from predict_sdk import OrderBuilder, ChainId, OrderBuilderOptions
|
|
99
|
+
|
|
100
|
+
builder = OrderBuilder.make(
|
|
101
|
+
ChainId.BNB_MAINNET,
|
|
102
|
+
private_key, # Must be the Privy exported wallet
|
|
103
|
+
OrderBuilderOptions(
|
|
104
|
+
predict_account="0x...", # Your Predict account address
|
|
105
|
+
),
|
|
106
|
+
)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Market Orders
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from predict_sdk import MarketHelperInput, MarketHelperValueInput
|
|
113
|
+
|
|
114
|
+
# Market order by quantity (number of shares)
|
|
115
|
+
amounts = builder.get_market_order_amounts(
|
|
116
|
+
MarketHelperInput(
|
|
117
|
+
side=Side.BUY,
|
|
118
|
+
quantity_wei=10000000000000000000, # 10 shares
|
|
119
|
+
),
|
|
120
|
+
orderbook, # From GET /orderbook/{marketId}
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# Market BUY by value (total USDT to spend)
|
|
124
|
+
amounts = builder.get_market_order_amounts(
|
|
125
|
+
MarketHelperValueInput(
|
|
126
|
+
side=Side.BUY,
|
|
127
|
+
value_wei=5000000000000000000, # 5 USDT
|
|
128
|
+
),
|
|
129
|
+
orderbook,
|
|
130
|
+
)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Redeeming Positions
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
# For standard markets
|
|
137
|
+
result = builder.redeem_positions(
|
|
138
|
+
condition_id="0x...",
|
|
139
|
+
index_set=1, # 1 or 2
|
|
140
|
+
is_neg_risk=False,
|
|
141
|
+
is_yield_bearing=False,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
# For NegRisk (winner-takes-all) markets
|
|
145
|
+
result = builder.redeem_positions(
|
|
146
|
+
condition_id="0x...",
|
|
147
|
+
index_set=1,
|
|
148
|
+
amount=1000000000000000000, # Required for NegRisk
|
|
149
|
+
is_neg_risk=True,
|
|
150
|
+
is_yield_bearing=False,
|
|
151
|
+
)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Merging Positions
|
|
155
|
+
|
|
156
|
+
Merge both outcome tokens back into collateral (USDT). Useful when holding equal amounts of both YES and NO positions.
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
# For standard markets
|
|
160
|
+
result = builder.merge_positions(
|
|
161
|
+
condition_id="0x...",
|
|
162
|
+
amount=1000000000000000000, # Amount to merge (in wei)
|
|
163
|
+
is_neg_risk=False,
|
|
164
|
+
is_yield_bearing=False,
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
# For NegRisk (winner-takes-all) markets
|
|
168
|
+
result = builder.merge_positions(
|
|
169
|
+
condition_id="0x...",
|
|
170
|
+
amount=1000000000000000000,
|
|
171
|
+
is_neg_risk=True,
|
|
172
|
+
is_yield_bearing=False,
|
|
173
|
+
)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Canceling Orders
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
from predict_sdk import CancelOrdersOptions
|
|
180
|
+
|
|
181
|
+
result = builder.cancel_orders(
|
|
182
|
+
orders=[order1, order2],
|
|
183
|
+
options=CancelOrdersOptions(
|
|
184
|
+
is_neg_risk=False,
|
|
185
|
+
is_yield_bearing=False,
|
|
186
|
+
),
|
|
187
|
+
)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Checking Balance
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
balance = builder.balance_of("USDT")
|
|
194
|
+
print(f"USDT Balance: {balance}")
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Async Support
|
|
198
|
+
|
|
199
|
+
All contract interaction methods have async versions:
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
import asyncio
|
|
203
|
+
|
|
204
|
+
async def main():
|
|
205
|
+
balance = await builder.balance_of_async("USDT")
|
|
206
|
+
result = await builder.set_approvals_async(is_yield_bearing=False)
|
|
207
|
+
|
|
208
|
+
asyncio.run(main())
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## API Reference
|
|
212
|
+
|
|
213
|
+
### OrderBuilder
|
|
214
|
+
|
|
215
|
+
The main class for building and signing orders.
|
|
216
|
+
|
|
217
|
+
#### Factory Method
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
OrderBuilder.make(
|
|
221
|
+
chain_id: ChainId,
|
|
222
|
+
signer: LocalAccount | str | None = None,
|
|
223
|
+
options: OrderBuilderOptions | None = None,
|
|
224
|
+
) -> OrderBuilder
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### Order Building Methods
|
|
228
|
+
|
|
229
|
+
- `get_limit_order_amounts(data: LimitHelperInput) -> OrderAmounts`
|
|
230
|
+
- `get_market_order_amounts(data: MarketHelperInput | MarketHelperValueInput, book: Book) -> OrderAmounts`
|
|
231
|
+
- `build_order(strategy: "MARKET" | "LIMIT", data: BuildOrderInput) -> Order`
|
|
232
|
+
- `build_typed_data(order: Order, *, is_neg_risk: bool, is_yield_bearing: bool) -> EIP712TypedData`
|
|
233
|
+
- `build_typed_data_hash(typed_data: EIP712TypedData) -> str`
|
|
234
|
+
- `sign_typed_data_order(typed_data: EIP712TypedData) -> SignedOrder`
|
|
235
|
+
|
|
236
|
+
#### Approval Methods
|
|
237
|
+
|
|
238
|
+
- `set_approvals(*, is_yield_bearing: bool = False) -> SetApprovalsResult`
|
|
239
|
+
- `set_ctf_exchange_approval(*, is_neg_risk: bool, is_yield_bearing: bool, approved: bool = True) -> TransactionResult`
|
|
240
|
+
- `set_neg_risk_adapter_approval(*, is_yield_bearing: bool, approved: bool = True) -> TransactionResult`
|
|
241
|
+
- `set_ctf_exchange_allowance(*, is_neg_risk: bool, is_yield_bearing: bool, amount: int = MAX_UINT256) -> TransactionResult`
|
|
242
|
+
|
|
243
|
+
#### Position Management
|
|
244
|
+
|
|
245
|
+
- `balance_of(token: "USDT" = "USDT", address: str | None = None) -> int`
|
|
246
|
+
- `redeem_positions(condition_id: str, index_set: 1 | 2, amount: int | None = None, *, is_neg_risk: bool, is_yield_bearing: bool) -> TransactionResult`
|
|
247
|
+
- `merge_positions(condition_id: str, amount: int, *, is_neg_risk: bool, is_yield_bearing: bool) -> TransactionResult`
|
|
248
|
+
|
|
249
|
+
#### Order Cancellation
|
|
250
|
+
|
|
251
|
+
- `cancel_orders(orders: list[Order], options: CancelOrdersOptions) -> TransactionResult`
|
|
252
|
+
- `validate_token_ids(token_ids: list[int], *, is_neg_risk: bool, is_yield_bearing: bool) -> bool`
|
|
253
|
+
|
|
254
|
+
### Types
|
|
255
|
+
|
|
256
|
+
```python
|
|
257
|
+
from predict_sdk import (
|
|
258
|
+
ChainId, # BNB_MAINNET (56), BNB_TESTNET (97)
|
|
259
|
+
Side, # BUY (0), SELL (1)
|
|
260
|
+
SignatureType, # EOA (0), POLY_PROXY (1), POLY_GNOSIS_SAFE (2)
|
|
261
|
+
Order,
|
|
262
|
+
SignedOrder,
|
|
263
|
+
BuildOrderInput,
|
|
264
|
+
OrderAmounts,
|
|
265
|
+
LimitHelperInput,
|
|
266
|
+
MarketHelperInput,
|
|
267
|
+
MarketHelperValueInput,
|
|
268
|
+
Book,
|
|
269
|
+
EIP712TypedData,
|
|
270
|
+
TransactionResult,
|
|
271
|
+
SetApprovalsResult,
|
|
272
|
+
CancelOrdersOptions,
|
|
273
|
+
OrderBuilderOptions,
|
|
274
|
+
)
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Requirements
|
|
278
|
+
|
|
279
|
+
- Python >= 3.11
|
|
280
|
+
- web3.py >= 6.0.0
|
|
281
|
+
|
|
282
|
+
## License
|
|
283
|
+
|
|
284
|
+
MIT
|