Metadata-Version: 2.4
Name: truemarkets
Version: 0.3.0
Summary: Python SDK for the True Markets public API.
Project-URL: Homepage, https://truemarkets.co
Project-URL: Documentation, https://docs.truemarkets.co
Project-URL: Repository, https://github.com/true-markets/sdk
Project-URL: Issues, https://github.com/true-markets/sdk/issues
Project-URL: Changelog, https://github.com/true-markets/sdk/blob/develop/CHANGELOG.md
Author-email: True Markets <support@truemarkets.co>
License-Expression: MIT
License-File: LICENSE
Keywords: api,cefi,crypto,defi,openapi,sdk,trading,truemarkets
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial :: Investment
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: attrs>=21.3
Requires-Dist: cryptography>=42
Requires-Dist: httpx>=0.27
Requires-Dist: posthog>=3.0
Requires-Dist: python-dateutil>=2.8
Requires-Dist: python-dotenv>=1.0
Provides-Extra: dev
Requires-Dist: openapi-python-client>=0.28; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Description-Content-Type: text/markdown

# truemarkets

Python SDK for the [True Markets](https://truemarkets.co) public API.

## Install

```sh
pip install truemarkets
```

Requires Python 3.10+.

## Quickstart

Sign up for and fund your TrueMarkets account on https://truemarkets.co/. Follow our [onboarding documentation](https://docs.truemarkets.co/getting-started/onboarding) to get started. 

Set `TM_KEY_FILE` (and optionally `TM_ENV=prod`) in a `.env` file or your
shell environment:

```sh
# .env
TM_ENV=prod
TM_KEY_FILE=/path/to/truemarkets-api-key-XXXXXXXX.json
```

Then call any operation on `c.gateway` or `c.defi`. Methods are generated
from the OpenAPI spec and named after the spec's `operationId`s, so the
full surface is discoverable via `dir(c.gateway)`:

```python
from truemarkets import Client
from truemarkets._generated.gateway.models import (
    OrderSide,
    QuoteRequest,
    QuoteRequestQtyUnit,
)

with Client() as c:
    q = c.gateway.compute_quote(body=QuoteRequest(
        base_asset="BTC", quote_asset="USDC",
        qty="25", qty_unit=QuoteRequestQtyUnit.QUOTE, side=OrderSide.BUY,
    ))

print(f"{q.qty} BTC @ {q.price} USDC/BTC")
```

`Client()` auto-loads `.env` from the current working directory (walking up).

## API surface

- `c.gateway.<operation_id>` — `compute_quote`, `create_order`, `execute_order`, `cancel_order`, `get_order_status`, `list_orders`, `create_transfer`, `execute_transfer`, `list_transfers`, `get_transfer`, `list_assets`, `list_balances`, `get_balances`.
- `c.defi.<operation_id>` — `get_assets`, `get_asset_by_chain_and_address`, `get_balances`, `get_history`, `get_profile`, `create_quote`, `execute_trade`, `prepare_transfer`, `execute_transfer`, `create_wallet`, `prepare_wallet_export`, `execute_wallet_export`, `get_watchlists`, `get_watchlist_by_id`.
- `c.sign_turnkey(payload)` — stamp a Turnkey activity payload with the cached API key.
- `truemarkets.auth.{load_key_file, mint_token, refresh_token, sign_challenge, turnkey_stamp}` — low-level helpers.

Models live under `truemarkets._generated.{gateway,defi,authapi}.models`.
Operations return the parsed response model directly.

## Telemetry

The SDK ships with opt-out telemetry so we
can prioritize features against real usage. The data is intentionally narrow:
operation, status, latency, SDK version. We never see request bodies, response
bodies, headers, API keys, or anything identifying a wallet/asset/human.

### Events

| Event | When | Properties |
|-------|------|------------|
| `sdk_initialized` | `Client()` | `sdk_lang`, `sdk_version`, `runtime` |
| `sdk_authenticated` | `c.authenticate()` succeeds | `sdk_lang`, `sdk_version`, `is_refresh` |
| `sdk_request` | Each HTTP response | `sdk_lang`, `sdk_version`, `method`, `path`, `status`, `latency_ms`, `ok` |

### Identity

`distinct_id` is derived in priority order:

1. The JWT's raw `uid` claim — a stable user UUID, set after the first
   successful `authenticate()`.
2. `sha256(api_key_id)[:16]` — once the key file is loaded, before first auth.
3. A per-process UUID — fully anonymous (e.g. read-only Marketdata calls).

On successful auth, the SDK sends an identify event attaching two
properties to the user: the raw `uid` and `hashed_email = sha256(jwt.sub)[:16]`
— the email is one-way hashed before leaving the SDK and is never sent in
raw form.

Alias events bridge the pre-auth identities under the user `uid` as
identity gets promoted, so the same human counts as one user across key
rotations and token refreshes.

### Disable

Either env var disables telemetry before any analytics code initializes:

```sh
TM_TELEMETRY=0       # 0|false|no|off
DO_NOT_TRACK=1       # 1|true|yes|on — industry convention
```

### Flushing

Events are buffered and flushed asynchronously from a daemon thread.
`with Client() as c: ...` flushes on `__exit__`; for ad-hoc scripts that
don't use the context manager, call `c.close()` before exit.

## DeFi trades

DeFi orders return Turnkey activity `payloads` that the SDK signs locally
with your API key:

```python
from truemarkets import Client
from truemarkets._generated.gateway.models import (
    Chain,
    CreateOrderRequest,
    CreateOrderRequestQtyUnit,
    ExecuteOrderRequest,
    OrderSide,
    OrderType,
    SigningMethod,
)

with Client() as c:
    order = c.gateway.create_order(body=CreateOrderRequest(
        base_asset="0xbaa5...",      # MORPHO
        quote_asset="0x8335...",     # USDC
        qty="0.5", qty_unit=CreateOrderRequestQtyUnit.BASE,
        side=OrderSide.SELL, type_=OrderType.MARKET, chain=Chain.BASE,
    ))
    stamps = [c.sign_turnkey(p.payload) for p in (order.payloads or [])]
    c.gateway.execute_order(
        id=order.order_id,
        body=ExecuteOrderRequest(signatures=stamps, auth_type=SigningMethod.API_KEY),
    )
```
