Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,20 @@ else:
```

See `examples/error_handling.py` for comprehensive error handling patterns.

### Order History

```python
result = await client.get_order_history(
pair="ALOT/USDC",
status="FILLED",
limit=50,
)
if result.success:
for order in result.data:
print(f"{order['pair']} {order['side']} {order['quantity']} @ {order['price']}")
```

## Dependencies

- `web3>=6.0.0`: Multi-chain blockchain interactions (AsyncWeb3 for async operations)
Expand Down Expand Up @@ -300,12 +314,15 @@ client.invalidate_cache(level="balance") # Options: static, semi_static, balanc
**Static Data (1 hour):**
- `get_environments()`
- `get_chains()`
- `get_deployment()`
- `get_deployment()` (also caches per `(env, contract_type, return_abi)` filter combination)
- `get_token_price_history(token, *, from_ts=None, to_ts=None)`
- `get_token_hourly_price_history(token, *, from_ts=None, to_ts=None)`

**Semi-Static Data (15 minutes):**
- `get_tokens()`
- `get_clob_pairs()`
- `get_swap_pairs(chain_identifier)`
- `get_token_usd_prices(env=None)`

**Balance Data (10 seconds):**
- `get_portfolio_balance(token, address=None)`
Expand All @@ -314,6 +331,8 @@ client.invalidate_cache(level="balance") # Options: static, semi_static, balanc
- `get_chain_wallet_balances(chain, address=None)`
- `get_chain_token_balances(chain, address=None, tokens=...)`
- `get_all_chain_wallet_balances(address=None)`
- `get_order_history(account=None, *, pair=None, status=None, limit=100, offset=0)`
- `get_combined_transfers(*, kind=None, from_ts=None, to_ts=None, limit=100, offset=0)`

**Orderbook Data (1 second):**
- `get_orderbook(pair)`
Expand Down Expand Up @@ -787,6 +806,17 @@ Error messages are automatically sanitized to prevent information leakage:
- Stack traces are removed
- User-friendly messages are provided

### Backend reason codes

Errors from the Dexalot REST API include structured `reasonCode` (e.g. `FQ-015`, `P-AFNE-02`, `T-TMDQ-01`, `RF-IMV-01`) and human `reason` fields. These are preserved verbatim in `Result.fail()` messages — you'll see `"FQ-015: insufficient liquidity"` rather than the generic `"Request failed with status code 400"`. Pattern-match on the code prefix to react programmatically:

```python
result = await client.get_swap_firm_quote("USDC", "AVAX", 100)
if not result.success and result.error.startswith("FQ-"):
# RFQ backend rejected the quote — see the reason code prefix for why
...
```

### Best Practices

1. **Always check `result.success`** before accessing `result.data`
Expand Down Expand Up @@ -988,6 +1018,20 @@ Orders are normalized into one canonical SDK shape regardless of whether the sou
**Deployment API:**
- `env`, `address`, `abi` (handles variations like `Env`, `Address`, `Abi`)

**Price History API (`get_token_price_history`, `get_token_hourly_price_history`):**
- Returns `list[PricePoint]` with `timestamp` (unix seconds, UTC) and `price` (`float`).
- `timestamp` is normalized from `date` ISO-8601, `ts`, `timestamp`, or `time` aliases — millisecond magnitudes are auto-detected and divided down to seconds.
- `price` is coerced from a string decimal to `float`; scientific notation is supported.
- Rows are returned sorted ascending by `timestamp`.

**Combined Transfers API (`get_combined_transfers`):**
- Returns `list[Transfer]` — a frozen dataclass with snake_case fields normalized from the backend's `DBTransfer` shape: `action_type`, `status`, `symbol`, `quantity`, `fee`, `trader_address`, `bridge`, `bridge_url`, `nonce`, `source_env`, `source_chain_id`, `source_tx`, `source_ts`, `target_env`, `target_chain_id`, `target_tx`, `target_ts`.
- Numeric enums are mapped to string `Literal` labels: `status` (`COMPLETED`/`INFLIGHT`/`DELAYED`), `action_type` (10 labels including `WITHDRAWN`/`DEPOSITED`/`SENT`/`RECEIVED`/`RECOVERED`/`ADD_GAS`/`REMOVE_GAS`/`AUTO_FILL`/`WITHDRAW_PENDING`/`DEPOSIT_PENDING`), `bridge` (`NATIVE`/`LAYER0`/`CELER`/`ICM`).
- `quantity` and `fee` arrive as display-decimal strings — no wei→human conversion is needed (parsed via `float()`).

**Order History API (`get_order_history`):**
- Same canonical order dict and field aliases as `get_open_orders` — see the "Orders API" entry above.

### Benefits

- **Consistent interface**: Field names are exposed in snake_case in Python consistently.
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.5.15
0.5.16
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ license = "MIT"
license-files = [
"LICENSE.txt"
]
version = "0.5.15"
version = "0.5.16"
description = "Dexalot Python SDK - Core library for Dexalot interaction"
readme = "README.md"
requires-python = ">=3.12,<3.15"
Expand Down
2 changes: 1 addition & 1 deletion src/dexalot_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
secrets_vault_set,
)

__version__ = "0.5.15"
__version__ = "0.5.16"


def get_version() -> str:
Expand Down
29 changes: 29 additions & 0 deletions src/dexalot_sdk/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ def ws_api_url_for_rest_base(rest_api_base_url: str | None) -> str:
ENDPOINT_TRADING_TOKENS = "/privapi/trading/tokens"
ENDPOINT_TRADING_DEPLOYMENT = "/privapi/trading/deployment"
ENDPOINT_SIGNED_ORDERS = "/privapi/signed/orders"
# Paginated per-account order history (any status) under the
# `/api/trading/signed/` mountpoint. Requires the `x-signature` header.
# Distinct from `ENDPOINT_SIGNED_ORDERS` above — `/privapi/signed/orders`
# returns the currently-open orders for the connected wallet (used by
# `get_open_orders`), while `/api/trading/signed/orders` returns the
# full historical order list (any status, paginated, supports
# `pair` / `status` / `limit` / `offset` filters and an explicit
# `traderaddress`). The trade-kit's `clob_get_orders_by_account` tool
# hits this path via its `signedGet("orders", ...)` helper which mounts
# at `${baseUrl}/trading/signed/<path>`.
ENDPOINT_TRADING_SIGNED_ORDERS_HISTORY = "/api/trading/signed/orders"
ENDPOINT_RFQ_PAIRS = "/api/rfq/pairs"
ENDPOINT_RFQ_FIRM_QUOTE = "/api/rfq/firmQuote"
ENDPOINT_RFQ_PAIR_PRICE = "/api/rfq/pairprice"
Expand All @@ -47,6 +58,24 @@ def ws_api_url_for_rest_base(rest_api_base_url: str | None) -> str:
# /api/ tree on the backend (not duplicated under /privapi/).
ENDPOINT_TRADING_CANDLE_CHUNK = "/api/trading/candle-chunk"
ENDPOINT_STATS_MARKET_SNAPSHOT = "/api/stats/market-snapshot"
# Public info tree (no auth, no `env` query at the backend — the host
# determines the network — but the SDK still forwards `env` for parity
# with the TypeScript SDK and cache-key namespacing on the client).
ENDPOINT_INFO_USD_PRICES = "/api/info/usd-prices"
# Daily and hourly USD price history per token. Backend ignores
# `from`/`to`/`env` query params today (host determines network, range
# is fixed window) but the SDK forwards them for forward-compat and
# cache-key namespacing; if a caller supplies `from_ts`/`to_ts` the
# response is additionally filtered client-side so the contract remains
# useful when the backend gains range support.
ENDPOINT_INFO_PRICE_HISTORY = "/api/info/token-usd-price-history"
ENDPOINT_INFO_HOURLY_PRICE_HISTORY = "/api/info/token-usd-price-history-hourly"
# Unified transfer history (deposits + withdrawals + p2p + gas) under the
# `/api/trading/signed/` mountpoint. Requires the `x-signature` header.
# The backend route does not exist under `/privapi/...` — confirmed
# empirically (404 on /privapi/trading/signed/transferscombined,
# 204 OPTIONS on /api/trading/signed/transferscombined).
ENDPOINT_TRADING_COMBINED_TRANSFERS = "/api/trading/signed/transferscombined"

# Default Values
DEFAULT_DECIMALS = 18
Expand Down
Loading
Loading