Metadata-Version: 2.4
Name: cowriepay
Version: 0.2.0
Summary: Official CowriePay Python SDK: signed Developer API client + webhook verification.
Project-URL: Homepage, https://gitlab.com/cowriex_com_public/cowriepay-sdks
Project-URL: Repository, https://gitlab.com/cowriex_com_public/cowriepay-sdks
Project-URL: Issues, https://gitlab.com/cowriex_com_public/cowriepay-sdks/-/issues
License-Expression: MIT
License-File: LICENSE
Keywords: africa,cowriepay,payments,stablecoin,tron,usdt,waas,wallet-as-a-service
Requires-Python: >=3.9
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: datamodel-code-generator>=0.25; extra == 'dev'
Requires-Dist: mypy>=1.11; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# cowriepay (Python)

Official CowriePay Python SDK: a signed client for the CowriePay Developer API (`/v2`) plus webhook
signature verification. Server-side only (your `cpk_*` secret must never reach a browser or mobile app).
**Zero runtime dependencies** (standard library only). Python ≥ 3.9.

## Install

```bash
pip install cowriepay
```

## Quickstart

```python
import os
from cowriepay import CowriePay

cowriepay = CowriePay(api_key=os.environ["CPK_KEY"], api_secret=os.environ["CPK_SECRET"])
# One base URL for everything: https://api.cowriepay.io
# The key you use selects the network, no host switch:
#   cpk_test_… → Sandbox (testnets: TRON Nile, BSC testnet, ETH Sepolia; fund from faucets)
#   cpk_live_… → Live (mainnets, real funds)
# Same code for both; swap the key to go live. Override the host with base_url=... (e.g. a dev host).

wallet = cowriepay.wallets.create(
    {"chain": "TRON", "asset": "USDT_TRON"},
    idempotency_key="a-uuid",  # makes the POST safe to auto-retry
)

balances = cowriepay.transactions.balances()
deposits = cowriepay.transactions.list_deposits(status="CONFIRMED", limit=20)
```

Namespaces: `chains` (open chains, via `cowriepay.chains.list()`), `wallets`, `customers`,
`transactions` (deposits / withdrawals / balances), `withdrawals`,
`fees`, `webhooks`, `api_keys`, `health`. For anything not wrapped, `cowriepay.request(method, path,
body=...)` is a signed escape hatch.

> CowriePay ships WaaS-first: this SDK is generated from the WaaS-only API view, so it does not include
> the checkout surface (payment intents / refunds). Those appear automatically when checkout launches.

## Errors

```python
from cowriepay import AuthenticationError, NotFoundError, CowriePayError

try:
    cowriepay.wallets.get("does-not-exist")
except NotFoundError:
    ...  # 404 / FEATURE_NOT_AVAILABLE
except AuthenticationError:
    ...  # 401 INVALID_SIGNATURE / TIMESTAMP_EXPIRED / ...
except CowriePayError as err:
    print(err.code, err.status, err.request_id)
```

## Verifying webhooks

Verify against the **raw** request body. During a secret rotation, pass both the current and previous
secrets so no delivery is rejected while you roll the secret.

```python
from cowriepay import verify_webhook

ok = verify_webhook(
    payload=raw_body_bytes,                       # the RAW body (bytes or str)
    signature_header=headers["X-CowriePay-Signature"],
    timestamp=headers["X-CowriePay-Timestamp"],
    secrets=[os.environ["WEBHOOK_SECRET"]],       # add the previous secret during rotation
    tolerance_seconds=300,                        # optional replay guard
)
```

## Development

```bash
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
python -m pytest        # golden vectors + prove-it-fails + client behaviour
python -m mypy          # strict type-check of the hand-written core
```

## License

MIT, Copyright (c) 2026 COWRIEX SAS. See [LICENSE](./LICENSE).

CowriePay and COWRIEX are trademarks of COWRIEX SAS. This license covers the source code
only and grants no right to the COWRIEX or CowriePay names or logos.
