worm-sdk 0.9.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.
Files changed (64) hide show
  1. worm_sdk-0.9.0/.github/workflows/release.yml +44 -0
  2. worm_sdk-0.9.0/.gitignore +22 -0
  3. worm_sdk-0.9.0/LICENSE +21 -0
  4. worm_sdk-0.9.0/Makefile +10 -0
  5. worm_sdk-0.9.0/PKG-INFO +218 -0
  6. worm_sdk-0.9.0/README.md +183 -0
  7. worm_sdk-0.9.0/examples/account.py +36 -0
  8. worm_sdk-0.9.0/examples/api_keys.py +24 -0
  9. worm_sdk-0.9.0/examples/margin.py +82 -0
  10. worm_sdk-0.9.0/examples/margin_settlements.py +49 -0
  11. worm_sdk-0.9.0/examples/markets.py +77 -0
  12. worm_sdk-0.9.0/examples/orders.py +48 -0
  13. worm_sdk-0.9.0/examples/quickstart.py +28 -0
  14. worm_sdk-0.9.0/examples/redeems.py +37 -0
  15. worm_sdk-0.9.0/examples/trades.py +30 -0
  16. worm_sdk-0.9.0/pyproject.toml +64 -0
  17. worm_sdk-0.9.0/src/worm_sdk/__init__.py +62 -0
  18. worm_sdk-0.9.0/src/worm_sdk/_version.py +1 -0
  19. worm_sdk-0.9.0/src/worm_sdk/api/__init__.py +23 -0
  20. worm_sdk-0.9.0/src/worm_sdk/api/account.py +76 -0
  21. worm_sdk-0.9.0/src/worm_sdk/api/api_keys.py +29 -0
  22. worm_sdk-0.9.0/src/worm_sdk/api/events.py +69 -0
  23. worm_sdk-0.9.0/src/worm_sdk/api/margin.py +388 -0
  24. worm_sdk-0.9.0/src/worm_sdk/api/markets.py +215 -0
  25. worm_sdk-0.9.0/src/worm_sdk/api/orders.py +185 -0
  26. worm_sdk-0.9.0/src/worm_sdk/api/redeems.py +102 -0
  27. worm_sdk-0.9.0/src/worm_sdk/api/search.py +93 -0
  28. worm_sdk-0.9.0/src/worm_sdk/api/sports.py +24 -0
  29. worm_sdk-0.9.0/src/worm_sdk/api/trades.py +44 -0
  30. worm_sdk-0.9.0/src/worm_sdk/auth/__init__.py +4 -0
  31. worm_sdk-0.9.0/src/worm_sdk/auth/bootstrap.py +80 -0
  32. worm_sdk-0.9.0/src/worm_sdk/auth/signer.py +103 -0
  33. worm_sdk-0.9.0/src/worm_sdk/client.py +116 -0
  34. worm_sdk-0.9.0/src/worm_sdk/constants.py +64 -0
  35. worm_sdk-0.9.0/src/worm_sdk/exceptions.py +53 -0
  36. worm_sdk-0.9.0/src/worm_sdk/http.py +236 -0
  37. worm_sdk-0.9.0/src/worm_sdk/py.typed +0 -0
  38. worm_sdk-0.9.0/src/worm_sdk/types/__init__.py +149 -0
  39. worm_sdk-0.9.0/src/worm_sdk/types/account.py +77 -0
  40. worm_sdk-0.9.0/src/worm_sdk/types/auth.py +34 -0
  41. worm_sdk-0.9.0/src/worm_sdk/types/common.py +43 -0
  42. worm_sdk-0.9.0/src/worm_sdk/types/enums.py +165 -0
  43. worm_sdk-0.9.0/src/worm_sdk/types/event.py +29 -0
  44. worm_sdk-0.9.0/src/worm_sdk/types/margin.py +117 -0
  45. worm_sdk-0.9.0/src/worm_sdk/types/market.py +219 -0
  46. worm_sdk-0.9.0/src/worm_sdk/types/order.py +60 -0
  47. worm_sdk-0.9.0/src/worm_sdk/types/redeem.py +30 -0
  48. worm_sdk-0.9.0/src/worm_sdk/types/search.py +30 -0
  49. worm_sdk-0.9.0/src/worm_sdk/types/sports.py +24 -0
  50. worm_sdk-0.9.0/src/worm_sdk/types/trade.py +23 -0
  51. worm_sdk-0.9.0/src/worm_sdk/wire.py +31 -0
  52. worm_sdk-0.9.0/tests/conftest.py +74 -0
  53. worm_sdk-0.9.0/tests/test_account.py +96 -0
  54. worm_sdk-0.9.0/tests/test_auth.py +118 -0
  55. worm_sdk-0.9.0/tests/test_events.py +78 -0
  56. worm_sdk-0.9.0/tests/test_http.py +227 -0
  57. worm_sdk-0.9.0/tests/test_margin.py +260 -0
  58. worm_sdk-0.9.0/tests/test_markets.py +318 -0
  59. worm_sdk-0.9.0/tests/test_orders.py +127 -0
  60. worm_sdk-0.9.0/tests/test_redeems.py +76 -0
  61. worm_sdk-0.9.0/tests/test_search.py +130 -0
  62. worm_sdk-0.9.0/tests/test_sports.py +34 -0
  63. worm_sdk-0.9.0/tests/test_trades.py +56 -0
  64. worm_sdk-0.9.0/tests/test_wire.py +41 -0
@@ -0,0 +1,44 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ build:
9
+ name: Build distribution
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: actions/setup-python@v5
14
+ with:
15
+ python-version: "3.x"
16
+ - name: Build sdist and wheel
17
+ run: |
18
+ python -m pip install --upgrade build
19
+ python -m build
20
+ - name: Validate metadata
21
+ run: |
22
+ python -m pip install --upgrade twine
23
+ python -m twine check dist/*
24
+ - uses: actions/upload-artifact@v4
25
+ with:
26
+ name: dist
27
+ path: dist/
28
+
29
+ publish:
30
+ name: Publish to PyPI
31
+ needs: build
32
+ runs-on: ubuntu-latest
33
+ environment:
34
+ name: pypi
35
+ url: https://pypi.org/p/worm-sdk
36
+ permissions:
37
+ id-token: write
38
+ steps:
39
+ - uses: actions/download-artifact@v4
40
+ with:
41
+ name: dist
42
+ path: dist/
43
+ - name: Publish
44
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,22 @@
1
+ .venv/
2
+ venv/
3
+ .pip-cache/
4
+ __pycache__
5
+ dist/
6
+ build/
7
+ *.egg-info/
8
+ .pypirc
9
+ __MACOSX/
10
+ .idea/
11
+ .vscode/
12
+ .pytest_cache/
13
+ .ruff_cache/
14
+ .mypy_cache/
15
+ .DS_Store
16
+ .env
17
+ .env.local
18
+ .env.development.local
19
+ .env.test.local
20
+ .env.production.local
21
+
22
+ local
worm_sdk-0.9.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Worm
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,10 @@
1
+ PYTHON=python
2
+
3
+ build:
4
+ $(PYTHON) -m build
5
+
6
+ clean:
7
+ rm -rf dist/ build/ src/worm_sdk.egg-info worm_sdk.egg-info
8
+
9
+ upload:
10
+ twine upload dist/*
@@ -0,0 +1,218 @@
1
+ Metadata-Version: 2.4
2
+ Name: worm-sdk
3
+ Version: 0.9.0
4
+ Summary: Python SDK for the Worm prediction markets platform
5
+ Project-URL: Homepage, https://worm.wtf
6
+ Project-URL: Documentation, https://docs.worm.wtf
7
+ Project-URL: Repository, https://github.com/wormwtf/worm-sdk
8
+ Project-URL: Issues, https://github.com/wormwtf/worm-sdk/issues
9
+ Author-email: Worm <support@worm.wtf>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: api-client,prediction-markets,sdk,solana,worm
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: httpx[http2]>=0.25
25
+ Requires-Dist: pydantic>=2.4.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: mypy>=1.0; extra == 'dev'
28
+ Requires-Dist: pytest>=7.0; extra == 'dev'
29
+ Requires-Dist: respx>=0.21; extra == 'dev'
30
+ Requires-Dist: ruff>=0.1; extra == 'dev'
31
+ Provides-Extra: signing
32
+ Requires-Dist: base58>=2.1; extra == 'signing'
33
+ Requires-Dist: solders>=0.21; extra == 'signing'
34
+ Description-Content-Type: text/markdown
35
+
36
+ # worm-sdk
37
+
38
+ Official Python client for the [Worm](https://worm.wtf) prediction markets API.
39
+
40
+ [![CI](https://github.com/wormwtf/worm-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/wormwtf/worm-sdk/actions/workflows/ci.yml)
41
+ [![PyPI version](https://badge.fury.io/py/worm-sdk.svg)](https://pypi.org/project/worm-sdk/)
42
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
43
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
44
+
45
+ ## Features
46
+
47
+ - Full coverage of the Worm REST API — markets, events, search, spot orders, margin, redeems, and account data
48
+ - Typed responses with [Pydantic](https://docs.pydantic.dev/) models
49
+ - HMAC authentication for private endpoints
50
+ - Optional Solana wallet signing for order, margin, and redeem flows
51
+ - Cursor-based pagination helpers
52
+ - HTTP/2 via [httpx](https://www.python-httpx.org/)
53
+
54
+ ## Requirements
55
+
56
+ - Python 3.10 or later
57
+
58
+ ## Installation
59
+
60
+ ```bash
61
+ pip install worm-sdk
62
+ ```
63
+
64
+ Install from source:
65
+
66
+ ```bash
67
+ git clone https://github.com/wormwtf/worm-sdk.git
68
+ cd worm-sdk
69
+ pip install -e .
70
+ ```
71
+
72
+ For wallet signing (orders, margin, redeems):
73
+
74
+ ```bash
75
+ pip install "worm-sdk[signing]"
76
+ ```
77
+
78
+ ## Quickstart
79
+
80
+ Fetch public market data — no credentials required:
81
+
82
+ ```python
83
+ from worm_sdk import WormClient
84
+
85
+ with WormClient() as client:
86
+ page = client.markets.list(sort="trending", limit=5)
87
+ for market in page.items:
88
+ print(market.title, market.condition_id)
89
+ ```
90
+
91
+ ## Authentication
92
+
93
+ Worm uses HMAC-signed API keys. Create a key once with a Solana wallet, then reuse the key and secret for all authenticated calls.
94
+
95
+ ```python
96
+ from worm_sdk import WormClient
97
+ from worm_sdk.auth import SolanaWalletSigner
98
+
99
+ # One-time setup — store the returned credentials securely
100
+ signer = SolanaWalletSigner("YOUR_SOLANA_PRIVATE_KEY")
101
+ credentials = WormClient.create_api_key(signer)
102
+
103
+ # Authenticated client
104
+ client = WormClient(
105
+ api_key=credentials.api_key,
106
+ api_secret=credentials.secret,
107
+ signer=signer, # optional; needed for place/redeem/open_position helpers
108
+ )
109
+
110
+ profile = client.account.get_summary()
111
+ print(profile.username)
112
+ ```
113
+
114
+ `SolanaWalletSigner` accepts a base58 string, 128-character hex keypair, or raw 64-byte keypair bytes. You can also provide any object that implements `SignerProtocol` (Ledger, KMS, etc.).
115
+
116
+ Set credentials via environment variables when running the examples:
117
+
118
+ ```bash
119
+ export WORM_API_KEY="..."
120
+ export WORM_API_SECRET="..."
121
+ export WORM_PRIVATE_KEY="..." # only for signing flows
122
+ ```
123
+
124
+ ## Usage
125
+
126
+ `WormClient` exposes namespaced APIs:
127
+
128
+ | Namespace | Auth | Description |
129
+ |-----------|------|-------------|
130
+ | `client.markets` | — | Market listings, order books, candles, prices, trades |
131
+ | `client.events` | — | Event listings and detail |
132
+ | `client.search` | — | Search markets and events |
133
+ | `client.sports` | — | Sports and league catalog |
134
+ | `client.orders` | ✓ | Spot order lifecycle |
135
+ | `client.trades` | ✓ | Your trade history |
136
+ | `client.account` | ✓ | Profile, portfolio, P&L |
137
+ | `client.margin` | ✓ / — | Margin estimate (public); positions, requests, settlements |
138
+ | `client.redeems` | ✓ | Redeem resolved positions |
139
+ | `client.api_keys` | ✓ | List and revoke API keys |
140
+
141
+ List endpoints return a `CursorPage[T]` with `items`, `next_cursor`, and `limit`:
142
+
143
+ ```python
144
+ page = client.markets.list(limit=20)
145
+ while page.next_cursor:
146
+ page = client.markets.list(limit=20, cursor=page.next_cursor)
147
+ ```
148
+
149
+ Convenience methods combine draft, sign, and submit in one call when a signer is configured:
150
+
151
+ ```python
152
+ from worm_sdk import OrderSide, OrderType
153
+
154
+ client.orders.place(
155
+ market_condition_id="...",
156
+ is_yes=True,
157
+ side=OrderSide.BUY,
158
+ order_type=OrderType.LIMIT,
159
+ amount="10",
160
+ price="0.55",
161
+ )
162
+ ```
163
+
164
+ See the [`examples/`](examples/) directory for complete scripts covering markets, orders, margin, redeems, and more.
165
+
166
+ ## Error handling
167
+
168
+ ```python
169
+ from worm_sdk import AuthenticationRequired, WormAPIError
170
+
171
+ try:
172
+ client.orders.list(limit=1)
173
+ except WormAPIError as exc:
174
+ print(exc.error_code, exc.slug, exc.message)
175
+ except AuthenticationRequired:
176
+ print("Pass api_key and api_secret to WormClient")
177
+ ```
178
+
179
+ ## Configuration
180
+
181
+ ```python
182
+ client = WormClient(
183
+ api_key="...",
184
+ api_secret="...",
185
+ base_url="https://api.worm.wtf", # default
186
+ timeout=30.0,
187
+ signer=signer,
188
+ )
189
+ ```
190
+
191
+ Inspect rate limits and response metadata on `client.last_response` after each request.
192
+
193
+ ## Development
194
+
195
+ ```bash
196
+ pip install -e ".[dev,signing]"
197
+ pytest
198
+ ruff check .
199
+ mypy src
200
+ ```
201
+
202
+ Build locally:
203
+
204
+ ```bash
205
+ python -m build
206
+ ```
207
+
208
+ Releases are published to PyPI automatically when you push a version tag (e.g. `v0.9.0`) or publish a GitHub Release. Set the `PYPI_API_TOKEN` repository secret first.
209
+
210
+ ## Links
211
+
212
+ - [Worm](https://worm.wtf)
213
+ - [API documentation](https://docs.worm.wtf)
214
+ - [Issue tracker](https://github.com/wormwtf/worm-sdk/issues)
215
+
216
+ ## License
217
+
218
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,183 @@
1
+ # worm-sdk
2
+
3
+ Official Python client for the [Worm](https://worm.wtf) prediction markets API.
4
+
5
+ [![CI](https://github.com/wormwtf/worm-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/wormwtf/worm-sdk/actions/workflows/ci.yml)
6
+ [![PyPI version](https://badge.fury.io/py/worm-sdk.svg)](https://pypi.org/project/worm-sdk/)
7
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
9
+
10
+ ## Features
11
+
12
+ - Full coverage of the Worm REST API — markets, events, search, spot orders, margin, redeems, and account data
13
+ - Typed responses with [Pydantic](https://docs.pydantic.dev/) models
14
+ - HMAC authentication for private endpoints
15
+ - Optional Solana wallet signing for order, margin, and redeem flows
16
+ - Cursor-based pagination helpers
17
+ - HTTP/2 via [httpx](https://www.python-httpx.org/)
18
+
19
+ ## Requirements
20
+
21
+ - Python 3.10 or later
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ pip install worm-sdk
27
+ ```
28
+
29
+ Install from source:
30
+
31
+ ```bash
32
+ git clone https://github.com/wormwtf/worm-sdk.git
33
+ cd worm-sdk
34
+ pip install -e .
35
+ ```
36
+
37
+ For wallet signing (orders, margin, redeems):
38
+
39
+ ```bash
40
+ pip install "worm-sdk[signing]"
41
+ ```
42
+
43
+ ## Quickstart
44
+
45
+ Fetch public market data — no credentials required:
46
+
47
+ ```python
48
+ from worm_sdk import WormClient
49
+
50
+ with WormClient() as client:
51
+ page = client.markets.list(sort="trending", limit=5)
52
+ for market in page.items:
53
+ print(market.title, market.condition_id)
54
+ ```
55
+
56
+ ## Authentication
57
+
58
+ Worm uses HMAC-signed API keys. Create a key once with a Solana wallet, then reuse the key and secret for all authenticated calls.
59
+
60
+ ```python
61
+ from worm_sdk import WormClient
62
+ from worm_sdk.auth import SolanaWalletSigner
63
+
64
+ # One-time setup — store the returned credentials securely
65
+ signer = SolanaWalletSigner("YOUR_SOLANA_PRIVATE_KEY")
66
+ credentials = WormClient.create_api_key(signer)
67
+
68
+ # Authenticated client
69
+ client = WormClient(
70
+ api_key=credentials.api_key,
71
+ api_secret=credentials.secret,
72
+ signer=signer, # optional; needed for place/redeem/open_position helpers
73
+ )
74
+
75
+ profile = client.account.get_summary()
76
+ print(profile.username)
77
+ ```
78
+
79
+ `SolanaWalletSigner` accepts a base58 string, 128-character hex keypair, or raw 64-byte keypair bytes. You can also provide any object that implements `SignerProtocol` (Ledger, KMS, etc.).
80
+
81
+ Set credentials via environment variables when running the examples:
82
+
83
+ ```bash
84
+ export WORM_API_KEY="..."
85
+ export WORM_API_SECRET="..."
86
+ export WORM_PRIVATE_KEY="..." # only for signing flows
87
+ ```
88
+
89
+ ## Usage
90
+
91
+ `WormClient` exposes namespaced APIs:
92
+
93
+ | Namespace | Auth | Description |
94
+ |-----------|------|-------------|
95
+ | `client.markets` | — | Market listings, order books, candles, prices, trades |
96
+ | `client.events` | — | Event listings and detail |
97
+ | `client.search` | — | Search markets and events |
98
+ | `client.sports` | — | Sports and league catalog |
99
+ | `client.orders` | ✓ | Spot order lifecycle |
100
+ | `client.trades` | ✓ | Your trade history |
101
+ | `client.account` | ✓ | Profile, portfolio, P&L |
102
+ | `client.margin` | ✓ / — | Margin estimate (public); positions, requests, settlements |
103
+ | `client.redeems` | ✓ | Redeem resolved positions |
104
+ | `client.api_keys` | ✓ | List and revoke API keys |
105
+
106
+ List endpoints return a `CursorPage[T]` with `items`, `next_cursor`, and `limit`:
107
+
108
+ ```python
109
+ page = client.markets.list(limit=20)
110
+ while page.next_cursor:
111
+ page = client.markets.list(limit=20, cursor=page.next_cursor)
112
+ ```
113
+
114
+ Convenience methods combine draft, sign, and submit in one call when a signer is configured:
115
+
116
+ ```python
117
+ from worm_sdk import OrderSide, OrderType
118
+
119
+ client.orders.place(
120
+ market_condition_id="...",
121
+ is_yes=True,
122
+ side=OrderSide.BUY,
123
+ order_type=OrderType.LIMIT,
124
+ amount="10",
125
+ price="0.55",
126
+ )
127
+ ```
128
+
129
+ See the [`examples/`](examples/) directory for complete scripts covering markets, orders, margin, redeems, and more.
130
+
131
+ ## Error handling
132
+
133
+ ```python
134
+ from worm_sdk import AuthenticationRequired, WormAPIError
135
+
136
+ try:
137
+ client.orders.list(limit=1)
138
+ except WormAPIError as exc:
139
+ print(exc.error_code, exc.slug, exc.message)
140
+ except AuthenticationRequired:
141
+ print("Pass api_key and api_secret to WormClient")
142
+ ```
143
+
144
+ ## Configuration
145
+
146
+ ```python
147
+ client = WormClient(
148
+ api_key="...",
149
+ api_secret="...",
150
+ base_url="https://api.worm.wtf", # default
151
+ timeout=30.0,
152
+ signer=signer,
153
+ )
154
+ ```
155
+
156
+ Inspect rate limits and response metadata on `client.last_response` after each request.
157
+
158
+ ## Development
159
+
160
+ ```bash
161
+ pip install -e ".[dev,signing]"
162
+ pytest
163
+ ruff check .
164
+ mypy src
165
+ ```
166
+
167
+ Build locally:
168
+
169
+ ```bash
170
+ python -m build
171
+ ```
172
+
173
+ Releases are published to PyPI automatically when you push a version tag (e.g. `v0.9.0`) or publish a GitHub Release. Set the `PYPI_API_TOKEN` repository secret first.
174
+
175
+ ## Links
176
+
177
+ - [Worm](https://worm.wtf)
178
+ - [API documentation](https://docs.worm.wtf)
179
+ - [Issue tracker](https://github.com/wormwtf/worm-sdk/issues)
180
+
181
+ ## License
182
+
183
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,36 @@
1
+ """View account summary, assets, and P&L."""
2
+
3
+ import os
4
+
5
+ from worm_sdk import WormClient
6
+
7
+ API_KEY = os.getenv("WORM_API_KEY")
8
+ API_SECRET = os.getenv("WORM_API_SECRET")
9
+
10
+ client = WormClient(api_key=API_KEY, api_secret=API_SECRET)
11
+
12
+ # --- Account summary ---
13
+ summary = client.account.get_summary()
14
+ print(f"Username: {summary.username}")
15
+ print(f"Twitter: {summary.twitter_username}")
16
+ print(f"Joined at: {summary.joined_at}")
17
+
18
+ # --- Market share balances ---
19
+ assets = client.account.get_assets(limit=10)
20
+ for a in assets.items:
21
+ print(
22
+ f" {a.position.outcome_text} ({a.token.symbol}) "
23
+ f"total={a.amounts.total} available={a.amounts.available} "
24
+ f"value_usdt={a.value.usdt}"
25
+ )
26
+
27
+ # --- P&L ---
28
+ pnl = client.account.get_pnl()
29
+ print(f"\nMargin settlements P&L: {pnl.margin_position_settlements_pnl}")
30
+ print(f"Margin unrealized P&L: {pnl.margin_positions_unrealized_pnl}")
31
+ print(f"Redeems funds: {pnl.redeems_funds}")
32
+ print(f"Active assets value: {pnl.active_assets_value}")
33
+ print(f"Creator fees: {pnl.creator_fees}")
34
+ print(f"Total P&L: {pnl.total_pnl}")
35
+
36
+ client.close()
@@ -0,0 +1,24 @@
1
+ """List and revoke API keys for the authenticated account."""
2
+
3
+ import os
4
+
5
+ from worm_sdk import WormClient
6
+
7
+ API_KEY = os.getenv("WORM_API_KEY")
8
+ API_SECRET = os.getenv("WORM_API_SECRET")
9
+
10
+ client = WormClient(api_key=API_KEY, api_secret=API_SECRET)
11
+
12
+ # --- List keys (each entry includes an id / key identifier for revocation) ---
13
+ keys = client.api_keys.list()
14
+ for k in keys:
15
+ print(
16
+ f"key_id={k.key_id} "
17
+ f"created={k.created} revoked_at={k.revoked_at}"
18
+ )
19
+
20
+ # --- Revoke a key by id (use `key_id` from list(); not the secret) ---
21
+ # KEY_ID_TO_REVOKE = "key-id-from-list-response"
22
+ # client.api_keys.revoke(KEY_ID_TO_REVOKE)
23
+
24
+ client.close()
@@ -0,0 +1,82 @@
1
+ """Margin trading: estimate, open positions, set TP/SL, close, and claim."""
2
+
3
+ import os
4
+
5
+ from worm_sdk import WormClient
6
+ from worm_sdk.auth import SolanaWalletSigner
7
+ from worm_sdk.types.enums import MarginPositionRequestType
8
+
9
+ API_KEY = os.getenv("WORM_API_KEY")
10
+ API_SECRET = os.getenv("WORM_API_SECRET")
11
+ PRIVATE_KEY = os.getenv("WORM_PRIVATE_KEY")
12
+
13
+ signer = SolanaWalletSigner(PRIVATE_KEY)
14
+ client = WormClient(api_key=API_KEY, api_secret=API_SECRET, signer=signer)
15
+
16
+ MARKET_CONDITION_ID = "your-market-condition-id"
17
+
18
+ # --- Estimate a position (public, no auth) ---
19
+ estimate = client.margin.estimate(
20
+ market_condition_id=MARKET_CONDITION_ID,
21
+ funds="100",
22
+ leverage="5",
23
+ is_yes=True,
24
+ )
25
+ print(f"Estimated shares: {estimate}")
26
+
27
+ # --- Position request lifecycle (same paths as API reference under /margin/positions/requests/) ---
28
+ page = client.margin.list_requests(market_condition_id=MARKET_CONDITION_ID, limit=10)
29
+ print(f"Open requests: {len(page.items)}")
30
+ # draft = client.margin.create_request(...)
31
+ # client.margin.submit_request(draft.pubkey, signature=your_signature)
32
+ # client.margin.cancel_request(draft.pubkey)
33
+ # row = client.margin.get_request("request-pubkey")
34
+
35
+ # --- Open a market position (funds-based; convenience: create + sign + submit) ---
36
+ market_result = client.margin.open_position(
37
+ market_condition_id=MARKET_CONDITION_ID,
38
+ position_request_type=MarginPositionRequestType.MARKET,
39
+ funds="100",
40
+ leverage="5",
41
+ is_yes=True,
42
+ take_profit_price="0.95",
43
+ stop_loss_price="0.40",
44
+ )
45
+ print(f"Market position request submitted: {market_result.pubkey}")
46
+
47
+ # --- Open a limit position (price + shares; resting limit order) ---
48
+ limit_result = client.margin.open_position(
49
+ market_condition_id=MARKET_CONDITION_ID,
50
+ position_request_type=MarginPositionRequestType.LIMIT,
51
+ price="0.55",
52
+ shares="200",
53
+ leverage="3",
54
+ is_yes=True,
55
+ take_profit_price="0.90",
56
+ stop_loss_price="0.35",
57
+ )
58
+ print(f"Limit position request submitted: {limit_result.pubkey}")
59
+
60
+ # --- List positions ---
61
+ positions = client.margin.list_positions(limit=5)
62
+ for p in positions.items:
63
+ print(f" Position: {p.pubkey} — closed={p.is_closed}")
64
+
65
+ pubkey = input("Enter position pubkey to set TP/SL / close: ")
66
+
67
+ # --- Update TP/SL ---
68
+ if pubkey:
69
+ tp_sl = client.margin.set_tp_sl(pubkey, take_profit_price="0.90", stop_loss_price="0.35")
70
+ print(f"TP/SL updated: {tp_sl}")
71
+
72
+ # --- Close a position ---
73
+ if pubkey:
74
+ close_result = client.margin.close_position(pubkey)
75
+ print(f"Close result: {close_result}")
76
+
77
+ # --- Claim settlement ---
78
+ if pubkey:
79
+ claim = client.margin.claim_settlement(pubkey)
80
+ print(f"Settlement claimed: {claim}")
81
+
82
+ client.close()
@@ -0,0 +1,49 @@
1
+ """Margin: inspect a single position and list settlements across positions."""
2
+
3
+ import os
4
+
5
+ from worm_sdk import WormClient
6
+ from worm_sdk.auth import SolanaWalletSigner
7
+
8
+ API_KEY = os.getenv("WORM_API_KEY")
9
+ API_SECRET = os.getenv("WORM_API_SECRET")
10
+ PRIVATE_KEY = os.getenv("WORM_PRIVATE_KEY")
11
+
12
+ signer = SolanaWalletSigner(PRIVATE_KEY)
13
+ client = WormClient(api_key=API_KEY, api_secret=API_SECRET, signer=signer)
14
+
15
+ # Set this to a known position pubkey, or leave as placeholder to use the first listed position.
16
+ POSITION_PUBKEY = "your-position-pubkey"
17
+ MARKET_CONDITION_ID = "your-market-condition-id"
18
+
19
+ positions = client.margin.list_positions(limit=5)
20
+ for p in positions.items:
21
+ print(f" {p.pubkey} — closed={p.is_closed}")
22
+
23
+ pubkey = (
24
+ POSITION_PUBKEY
25
+ if POSITION_PUBKEY != "your-position-pubkey"
26
+ else (positions.items[0].pubkey if positions.items else None)
27
+ )
28
+
29
+ if pubkey:
30
+ detail = client.margin.get_position(pubkey)
31
+ print(f"\nDetail for {pubkey}: {detail}")
32
+
33
+ # --- Settlements list (cursor pagination) ---
34
+ page = client.margin.list_settlements(limit=20)
35
+ for s in page.items:
36
+ print(f" settlement: {s}")
37
+
38
+ if page.next_cursor:
39
+ more = client.margin.list_settlements(limit=20, cursor=page.next_cursor)
40
+ print(f"Next page: {len(more.items)} settlements")
41
+
42
+ # --- Optional filters ---
43
+ filtered = client.margin.list_settlements(
44
+ market_condition_id=MARKET_CONDITION_ID,
45
+ limit=10,
46
+ )
47
+ print(f"Filtered by market: {len(filtered.items)}")
48
+
49
+ client.close()