Metadata-Version: 2.4
Name: kryptoexpress-sdk
Version: 0.1.0
Summary: Production-grade Python SDK for the KryptoExpress API.
Project-URL: Homepage, https://kryptoexpress.pro/
Project-URL: Documentation, https://kryptoexpress.pro/api/swagger/documentation.yaml
Project-URL: Repository, https://github.com/kryptoexpress/kryptoexpress-sdk
Project-URL: Issues, https://github.com/kryptoexpress/kryptoexpress-sdk/issues
Author: kryptoexpress
License: MIT License
        
        Copyright (c) 2026 kryptoexpress
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: api,crypto,kryptoexpress,payments,sdk
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
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 :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx<1,>=0.27
Requires-Dist: pydantic<3,>=2.8
Provides-Extra: dev
Requires-Dist: build<2,>=1.2; extra == 'dev'
Requires-Dist: mypy<2,>=1.11; extra == 'dev'
Requires-Dist: pytest-asyncio<1,>=0.24; extra == 'dev'
Requires-Dist: pytest<9,>=8.3; extra == 'dev'
Requires-Dist: ruff<1,>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

# kryptoexpress-sdk

Typed Python SDK for the KryptoExpress API.

Sources used for this SDK:

- Swagger/OpenAPI: `https://kryptoexpress.pro/api/swagger/documentation.yaml`
- Practical docs: `https://raw.githubusercontent.com/kryptoexpress/kryptoexpress/refs/heads/main/api-docs.md`

## Features

- Python 3.10+
- sync and async clients
- `httpx` transport
- `pydantic` v2 models
- typed exceptions
- small, explicit public API
- client-side domain validation before HTTP calls

## Developer Notes

Business rules from the practical API documentation take priority over mechanically mirroring the
OpenAPI schema.

This SDK intentionally implements the following domain rules in a centralized validation layer:

- `PAYMENT` requires `fiatAmount`
- `DEPOSIT` does not send `fiatAmount`
- stablecoins support only `paymentType=PAYMENT`
- stablecoins support only exact payment semantics
- minimum payment amount must be at least the equivalent of `1.00 USD`
- fiat conversion for non-USD minimum checks is delegated to an explicit converter abstraction

Where the OpenAPI spec and practical docs differ, the SDK prefers the safer business rule.

## Installation

```bash
pip install kryptoexpress-sdk
```

## Quickstart

```python
from kryptoexpress import KryptoExpressClient
from kryptoexpress.models.common import CryptoCurrency, FiatCurrency
from kryptoexpress.models.payments import PaymentCreateRequest

client = KryptoExpressClient(api_key="your-api-key")

payment = client.payments.create(
    PaymentCreateRequest.for_payment(
        crypto_currency=CryptoCurrency.BTC,
        fiat_currency=FiatCurrency.USD,
        fiat_amount=12.34,
        callback_url="https://example.com/callback",
    )
)

payment_shortcut = client.payments.create_payment(
    crypto_currency=CryptoCurrency.BTC,
    fiat_currency=FiatCurrency.USD,
    fiat_amount=12.34,
    callback_url="https://example.com/callback",
)

wallet = client.wallet.get()
prices = client.currencies.get_prices(
    crypto_currencies=[CryptoCurrency.BTC, CryptoCurrency.ETH],
    fiat_currency=FiatCurrency.USD,
)
fiat = client.fiat.list()
client.close()
```

## Public API

```python
from kryptoexpress import AsyncKryptoExpressClient, KryptoExpressClient
```

Available resource methods:

- `client.payments.create(...)`
- `client.payments.create_payment(...)`
- `client.payments.create_deposit(...)`
- `client.payments.get_by_hash(...)`
- `client.wallet.get()`
- `client.wallet.withdraw(...)`
- `client.wallet.calculate(...)`
- `client.wallet.withdraw_all(...)`
- `client.wallet.withdraw_single(...)`
- `client.wallet.calculate_all(...)`
- `client.wallet.calculate_single(...)`
- `client.currencies.list_all()`
- `client.currencies.list_native()`
- `client.currencies.list_stable()`
- `client.currencies.get_prices(...)`
- `client.fiat.list()`

## Configuration

Both clients support:

- `api_key`
- `base_url`
- `timeout`
- `max_retries`
- `minimum_amount_policy`
- `fiat_converter` for sync clients
- `async_fiat_converter` for async clients

Authentication is sent via the `X-Api-Key` header.

## Payment Types

`PAYMENT`

- requires `fiatAmount`
- the server converts fiat amount into expected `cryptoAmount`
- supports exact payment
- supports overpayment
- supports split or aggregated partial payment

`DEPOSIT`

- does not send `fiatAmount`
- accepts the first incoming on-chain transaction to the generated address
- determines fiat value after funds arrive
- should be used when the exact incoming crypto amount is not known ahead of time

Example:

```python
deposit = client.payments.create(
    PaymentCreateRequest.for_deposit(
        crypto_currency=CryptoCurrency.BTC,
        fiat_currency=FiatCurrency.USD,
        callback_url="https://example.com/callback",
    )
)

deposit_shortcut = client.payments.create_deposit(
    crypto_currency=CryptoCurrency.BTC,
    fiat_currency=FiatCurrency.USD,
    callback_url="https://example.com/callback",
)
```

For `DEPOSIT`, `fiatAmount` and `cryptoAmount` may remain `None` until funds arrive.

## Stablecoin Rules

Supported stablecoins in the practical docs:

- `USDT_ERC20`
- `USDC_ERC20`
- `USDT_BEP20`
- `USDC_BEP20`
- `USDT_SOL`
- `USDC_SOL`

Restrictions enforced by the SDK before HTTP:

- stablecoins support only `paymentType=PAYMENT`
- stablecoins support only exact payment behavior
- stablecoins do not support overpayment or split-payment semantics

Example:

```python
stablecoin_payment = client.payments.create(
    PaymentCreateRequest.for_payment(
        crypto_currency=CryptoCurrency.USDT_ERC20,
        fiat_currency=FiatCurrency.USD,
        fiat_amount=15.0,
        callback_url="https://example.com/callback",
    )
)

stablecoin_shortcut = client.payments.create_payment(
    crypto_currency=CryptoCurrency.USDT_ERC20,
    fiat_currency=FiatCurrency.USD,
    fiat_amount=15.0,
    callback_url="https://example.com/callback",
)
```

## Minimum Fiat Amount Policy

KryptoExpress service fee is `0.8%`, but not less than `1 USD`, so the SDK enforces a minimum
payment amount equivalent to `1.00 USD`.

- for `USD`, `fiatAmount` must be at least `1.00`
- for other fiat currencies, the SDK converts `1.00 USD` into the target currency before request
  submission
- if no reliable converter is configured for non-USD validation, the SDK raises
  `CurrencyConversionError`

### Custom Fiat Converter

Pass a callable or adapter that converts fiat amounts:

```python
from kryptoexpress import KryptoExpressClient
from kryptoexpress.models.common import FiatCurrency


def fiat_converter(amount: float, from_currency: FiatCurrency, to_currency: FiatCurrency) -> float:
    if from_currency is FiatCurrency.USD and to_currency is FiatCurrency.EUR:
        return 0.91
    raise RuntimeError("unsupported conversion")


client = KryptoExpressClient(
    api_key="your-api-key",
    fiat_converter=fiat_converter,
)
```

Example non-USD payment:

```python
payment = client.payments.create(
    PaymentCreateRequest.for_payment(
        crypto_currency=CryptoCurrency.BTC,
        fiat_currency=FiatCurrency.EUR,
        fiat_amount=0.91,
        callback_url="https://example.com/callback",
    )
)
```

## Withdrawals And Dry Runs

Use typed requests for `ALL` and `SINGLE` withdrawals:

```python
from kryptoexpress.models.wallet import WithdrawalAllRequest, WithdrawalSingleRequest

dry_run = client.wallet.calculate(
    WithdrawalSingleRequest(
        payment_id=123,
        crypto_currency=CryptoCurrency.BTC,
        to_address="bc1destination",
        only_calculate=False,
    )
)

dry_run_shortcut = client.wallet.calculate_single(
    payment_id=123,
    crypto_currency=CryptoCurrency.BTC,
    to_address="bc1destination",
)

withdraw_all = client.wallet.withdraw(
    WithdrawalAllRequest(
        crypto_currency=CryptoCurrency.BTC,
        to_address="bc1destination",
        only_calculate=False,
    )
)

withdraw_all_shortcut = client.wallet.withdraw_all(
    crypto_currency=CryptoCurrency.BTC,
    to_address="bc1destination",
)
```

`client.wallet.calculate(...)` always forces `onlyCalculate=true` and acts as an explicit dry-run.

## Callback Signature Verification

KryptoExpress signs callbacks using:

- header: `X-Signature`
- algorithm: `HMAC-SHA512`
- message: compact raw JSON body
- key: `callbackSecret`

Helper example:

```python
from kryptoexpress import verify_callback_signature


def handle_callback(raw_body: bytes, x_signature: str) -> bool:
    return verify_callback_signature(
        raw_body=raw_body,
        callback_secret="my_super_secret_1234567890",
        signature=x_signature,
    )
```

This helper is suitable for FastAPI, Flask, or Django handlers where you already have the raw body
and the `X-Signature` header.

## Notes On Spec Differences

The current practical docs clarify several areas where the OpenAPI schema is incomplete:

- `GET /payment` is public
- `GET /cryptocurrency/price` returns a list in practice
- native, stable, and all-cryptocurrency lists differ in the practical docs
- wallet balances may omit or add currency keys relative to the broader enum list
