Metadata-Version: 2.4
Name: mintarex
Version: 0.0.6
Summary: Official Python SDK for the Mintarex Corporate OTC API.
Project-URL: Homepage, https://developers.mintarex.com
Project-URL: Documentation, https://developers.mintarex.com
Project-URL: Repository, https://github.com/mintarex/mintarex-python
Project-URL: Issues, https://github.com/mintarex/mintarex-python/issues
Author-email: Mintarex <dev@mintarex.com>
License-Expression: MIT
License-File: LICENSE
Keywords: api,crypto,mintarex,otc,sdk,trading
Classifier: Development Status :: 3 - Alpha
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.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27
Description-Content-Type: text/markdown

<p align="center">
  <a href="https://mintarex.com">
    <img src="https://mintarex.com/mintarex.svg" alt="Mintarex" width="320" />
  </a>
</p>

<h1 align="center">mintarex</h1>

<p align="center">
  Official Python SDK for the <a href="https://developers.mintarex.com">Mintarex Corporate OTC API</a>.
</p>

<p align="center">
  <a href="https://pypi.org/project/mintarex/"><img src="https://img.shields.io/pypi/v/mintarex.svg?style=flat-square" alt="PyPI version" /></a>
  <a href="https://pypi.org/project/mintarex/"><img src="https://img.shields.io/pypi/dm/mintarex.svg?style=flat-square" alt="PyPI downloads" /></a>
  <a href="https://github.com/mintarex/mintarex-python/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/mintarex.svg?style=flat-square" alt="MIT License" /></a>
  <a href="https://www.python.org"><img src="https://img.shields.io/pypi/pyversions/mintarex.svg?style=flat-square" alt="Python version" /></a>
  <a href="https://mypy-lang.org"><img src="https://img.shields.io/badge/types-mypy_strict-blue?style=flat-square" alt="mypy strict" /></a>
</p>

---

- HMAC-SHA256 request signing (automatic)
- Typed errors per API error code
- RFQ trading, crypto deposits/withdrawals, webhooks, real-time SSE streams
- Webhook signature verification helper
- Built for Python 3.11+ — one runtime dependency (`httpx`)
- Full type hints (`py.typed`, mypy-strict clean)

## Installation

```bash
pip install mintarex
# or
uv add mintarex
```

Python 3.11+ required.

## Quick start

```python
import os

from mintarex import Mintarex

mx = Mintarex(
    api_key=os.environ["MX_KEY"],      # mxn_live_... or mxn_test_...
    api_secret=os.environ["MX_SECRET"],
)

# Account
balances = mx.account.balances()
print(balances["balances"])

# Request a quote
quote = mx.rfq.quote({
    "base": "BTC",
    "quote": "USD",
    "side": "buy",
    "amount": "0.5",
    "amount_type": "base",
})
print("quote_id:", quote["quote_id"], "price:", quote["price"])

# Accept — idempotency_key auto-generated if omitted
trade = mx.rfq.accept(quote["quote_id"])
print("filled:", trade)
```

## Features

| Area | Support |
|------|---------|
| HMAC-SHA256 request signing | Built-in, auto-generated nonces + timestamps |
| Typed errors | 13 exception classes mapping HTTP status + API error codes |
| Automatic retries | 429 / 503 / network errors (with Retry-After honored) |
| Rate-limit headers | IETF RFC 9331 `RateLimit-*` (legacy `X-RateLimit-*` fallback) |
| SSE streaming | `mx.streams.prices()` / `mx.streams.account()` with auto-reconnect + watchdog |
| Webhook verification | Constant-time HMAC check + timestamp tolerance |
| Environments | `live` or `sandbox` (inferred from key prefix) |
| Type hints | Full `py.typed`, mypy-strict clean |

## Environments

The environment is inferred from the key prefix:

| Key prefix | Environment |
|-----------|-------------|
| `mxn_live_...` | `live` |
| `mxn_test_...` | `sandbox` |

You can also set it explicitly:

```python
mx = Mintarex(api_key=..., api_secret=..., environment="sandbox")
```

## Error handling

All SDK errors inherit from `MintarexError`.

```python
from mintarex import (
    InsufficientBalanceError,
    QuoteExpiredError,
    RateLimitError,
    ValidationError,
)

try:
    trade = mx.rfq.accept(quote_id)
except QuoteExpiredError:
    quote = mx.rfq.quote({...})  # re-quote
    trade = mx.rfq.accept(quote["quote_id"])
except InsufficientBalanceError as e:
    print("top up:", e.message)
except RateLimitError as e:
    print("retry after ms:", e.retry_after, "remaining:", e.rate_limit.remaining)
except ValidationError as e:
    print("bad input:", e.message)
```

## Streaming (SSE)

```python
with mx.streams.prices() as stream:
    for msg in stream:
        print(msg.event, msg.data)
```

Reconnect on transient errors is automatic; a watchdog fires if no data
arrives within 2× the heartbeat interval. Call `stream.close()` to stop.

## Webhook verification

```python
from flask import Flask, request
from mintarex import verify_webhook, WebhookSignatureError

app = Flask(__name__)

@app.post("/hook")
def hook():
    try:
        event = verify_webhook(
            body=request.get_data(),      # exact raw bytes, NOT parsed JSON
            headers=dict(request.headers),
            secret=os.environ["MINTAREX_WEBHOOK_SECRET"],
        )
    except WebhookSignatureError:
        return "", 400

    if event["event_type"] == "trade.executed":
        handle_trade(event["data"])
    return "", 204
```

## Configuration

```python
mx = Mintarex(
    api_key=...,
    api_secret=...,
    environment="sandbox",          # optional — inferred from key prefix
    base_url="https://institutional.mintarex.com/v1",   # optional override
    stream_base_url="https://institutional.mintarex.com/v1/stream",
    timeout=30.0,                   # per-request timeout (seconds)
    max_retries=3,                  # for 429/503 and network errors
    user_agent="my-app/1.0",        # appended to the default UA
)
```

`http://` URLs are permitted only for `localhost` / `127.0.0.1` / `::1`
(dev and test scenarios). Public hosts must use HTTPS.

## Resources

| Namespace | Methods |
|-----------|---------|
| `mx.account` | `balances()`, `balance(currency)`, `fees()`, `limits()` |
| `mx.rfq` | `quote(...)`, `accept(quote_id, idempotency_key=...)` |
| `mx.trades` | `list(...)`, `get(trade_uuid)` |
| `mx.crypto` | `deposit_address(...)`, `deposits(...)`, `withdraw(...)`, `withdrawals(...)`, `get_withdrawal(...)`, `addresses.list/add/remove` |
| `mx.webhooks` | `create(...)`, `list()`, `remove(endpoint_uuid)` |
| `mx.streams` | `prices()`, `account()` |
| `mx.public` | `instruments()`, `networks(...)`, `fees()` |

## Support

- **API Docs**: https://developers.mintarex.com
- **Issues**: https://github.com/mintarex/mintarex-python/issues
- **Contact**: support@mintarex.com

## License

MIT © [Mintarex](https://mintarex.com)

<p align="center">
  <img src="https://mintarex.com/ICON-512X512.png" alt="Mintarex" width="64" />
</p>
