noether-sdk
Official Python SDK for Noether — a decentralized perpetual exchange on Stellar / Soroban.
Async-first (httpx + pydantic), typed, mirrors the public surface of the TypeScript SDK (noether-sdk on npm).
Install
pip install noether-sdk
# Required for API-key issuance (keys.create) and local Keypair signing:
pip install "noether-sdk[stellar]"
Quick start — public reads
import asyncio
from noether_sdk import NoetherClient
async def main():
async with NoetherClient("https://api.noether.exchange") as client:
markets = await client.markets.list()
btc = await client.oracle.get_price("BTC")
print("BTC oracle:", btc.price_float)
asyncio.run(main())
Authed: account info
from noether_sdk.transport import Credentials
async with NoetherClient(
"https://api.noether.exchange",
credentials=Credentials("nk_...", "..."),
) as client:
me = await client.account.me()
mine = await client.account.positions() # mine.positions (open) + mine.events
Issue an API key (one-shot)
Requires the stellar extra. keys.create wraps the gateway challenge
as a manageData op on a placeholder transaction and asks your signer for
a signature over the transaction hash — the SDK never sees the secret.
from stellar_sdk import Keypair
kp = Keypair.from_secret(os.environ["STELLAR_SECRET"])
async with NoetherClient("https://api.noether.exchange") as client:
issued = await client.keys.create(
address=kp.public_key,
signer=lambda data: kp.sign(data),
label="mm-bot-1",
)
print(issued.key_id, issued.secret) # store immediately
Place an order — execute_trade
Trading needs collateral: fund your wallet with testnet USDC from the Noether faucet (Friendbot only provides XLM) before placing orders.
from stellar_sdk import Network, TransactionBuilder
def sign_xdr(xdr: str) -> str:
tx = TransactionBuilder.from_xdr(xdr, Network.TESTNET_NETWORK_PASSPHRASE)
tx.sign(kp)
return tx.to_xdr()
prepared, submitted = await authed.execute_trade(
{
"op": "open_position",
"asset": "XLM",
"collateral": 1_000 * 10_000_000,
"leverage": 2,
"direction": "Long",
},
sign_xdr,
)
print(submitted.hash, submitted.status)
execute_trade calls orders.prepare → asks your signer for the signed XDR → calls tx.submit and polls until SUCCESS / FAILED / timeout.
Sub-client cheatsheet
| Call | Auth |
|---|---|
client.health.ping() |
no |
client.markets.list() / get(asset) / stats() / candles(asset, ...) |
no |
client.oracle.get_price(asset) / get_prices() / health() |
no |
client.events.list(topic=, before_ts=, ...) |
no |
client.trades.list(trader=, asset=, before_ts=, ...) |
no |
client.adl.queue(asset, trader=...) |
no |
client.keys.beta_status(address=...) |
no |
client.keys.create(...) |
no |
client.keys.list() / revoke(id) |
yes |
client.account.me() / events() / positions() / orders() |
yes |
client.account.volume(address) / shortfall(address) |
no |
client.orders.prepare({op: ..., ...}) |
yes |
client.positions.open(trader=...) |
no |
client.tx.submit(signed_xdr=...) |
yes |
client.execute_trade({...}, signer) |
yes |
client.vaults.list() / get(id) / trades/deposits/withdraws/fee_claims(id) |
no |
client.referral.lookup_code(code) / info(address) |
no |
client.referral.me() / trades() / claims() |
yes |
WebSocket
from noether_sdk.ws import WsClient
ws = WsClient("wss://api.noether.exchange/v1/ws")
await ws.connect() # returns on server hello; raises on timeout/failure
await ws.subscribe("ticker.BTC", lambda data, ch: print(ch, data["priceFloat"]))
WsClient reconnects automatically with exponential backoff and replays your login + active subscriptions on every reconnect (account.* channels are re-sent after each login ack). connect() raises instead of hanging when the gateway is unreachable (connect_timeout, default 15s); subscription rejections and failed logins surface through the on_rejected / on_login callbacks.
Errors
from noether_sdk import (
AuthError, RateLimitError, BadRequestError, ServerError,
)
try:
await client.markets.get("DOGE")
except BadRequestError as err:
print("bad request:", err.body)
except RateLimitError as err:
print("retry in", err.retry_after_sec)
Examples
examples/place_order.py— Friendbot fund + key issuance + open_position end-to-end (fund the wallet with testnet USDC from the faucet first, or the open_position step will fail).examples/ws_ticker.py— minimal WebSocket subscription.
Dev
pip install -e ".[dev,stellar]"
pytest
Publish (maintainers)
# From sdk-py/ — do not put npm pack tarballs in dist/ (breaks twine).
export TWINE_USERNAME=__token__
export TWINE_PASSWORD=pypi-... # scope: entire account or project noether-sdk
./scripts/publish_pypi.sh
Status
REST surface complete + WS sub-client. Mirror of the TypeScript SDK shape so cross-language services can be written in either language without translation cost. See CHANGELOG.md.
Metadata
Release files for noether-sdk 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| noether_sdk-0.1.2.tar.gz | 26.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| noether_sdk-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 51.6 kB
Release files / noether_sdk-0.1.2.tar.gz
| Download URL | noether_sdk-0.1.2.tar.gz |
|---|---|
| Size | 26.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cec85b2768870b5bc7d6ddd4440e53f1f7ecd68418b5a8f5e066beb9996935f8
|
|
BLAKE2b-256 checksum How to use checksums |
6047030238e5908a35302e40d292e11f2a7dde59c89ca07f6d8f234c42096daf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Release files / noether_sdk-0.1.2-py3-none-any.whl
| Download URL | noether_sdk-0.1.2-py3-none-any.whl |
|---|---|
| Size | 25.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f57be15d6becefa0935f68991d0e6bfb6479b45c881cfa0af58e1bfd0367e802
|
|
BLAKE2b-256 checksum How to use checksums |
0e1abe8265d19cc9c38b77b347005c0fd64ae64ebafdcb0d6c4e864fa4ccd768
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Security for noether-sdk 0.1.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.