Skip to main content

Python SDK for trading on Silhouette - the shield exchange on Hyperliquid

Project description

silhouette-python-sdk

Dependencies Status Code style: ruff Pre-commit Semantic Versions License

Python SDK for trading on Silhouette - the shielded exchange on Hyperliquid.

Overview

This package provides:

  • Drop-in replacement for the official Hyperliquid Python SDK with enhanced convenience methods
  • Silhouette API integration for trading on the shielded exchange
  • Type-safe interfaces with Pydantic models generated from OpenAPI specifications
  • Clean dict-based API for easy usage without model imports
  • Enhanced functionality including balance checking, deposit automation, and withdrawal polling

IMPORTANT: This package replaces hyperliquid-python-sdk. Do not install both packages together. The official Hyperliquid SDK is included as a dependency.

Installation

pip install silhouette-python-sdk

Quick Start

Using Enhanced Hyperliquid SDK

# IMPORTANT: Always import silhouette FIRST
import silhouette

# Then use standard hyperliquid imports to get enhanced versions
from hyperliquid.info import Info
from hyperliquid.exchange import Exchange
from hyperliquid.utils.constants import TESTNET_API_URL

# Enhanced Info client with get_balance() and await_withdrawal_completion()
info = Info(base_url=TESTNET_API_URL, skip_ws=True)

# Check spot balances
spot_state = info.spot_user_state("0x1615330FAee0776a643CC0075AD2008418e067Db")
print(spot_state)

# Get specific token balance (convenience method)
usdc_balance = info.get_balance("0x1615330FAee0776a643CC0075AD2008418e067Db", "USDC")
print(f"USDC Balance: {usdc_balance}")

Using Silhouette API

from silhouette import SilhouetteApiClient

# Initialize client with auto-authentication
client = SilhouetteApiClient(
    base_url="https://api.silhouette.exchange",
    private_key="your_private_key_here",
    auto_auth=True,
)

# Check balances (returns plain dict with camelCase keys)
balances_response = client.user.get_balances()
print(f"Balances: {balances_response['balances']}")

# Place an order (returns dict, no need to import models)
order = client.order.create_order(
    side="buy",
    order_type="limit",
    base_token="HYPE",
    quote_token="USDC",
    amount="1.0",
    price="0.001",
)
print(f"Order placed: {order['orderId']}")

# Initiate a withdrawal
withdrawal = client.user.initiate_withdrawal("USDC", "100.0")
print(f"Withdrawal initiated: {withdrawal['withdrawalId']}")

Enhanced Features

Hyperliquid SDK Enhancements

The enhanced Hyperliquid SDK includes these convenience methods:

Info class:

  • get_balance(wallet_address: str, token_symbol: str) -> float - Get user's balance for a specific token
  • await_withdrawal_completion(wallet_address: str, pre_withdrawal_balance: float, token_symbol: str, timeout: int) -> bool - Poll balance until withdrawal completes

Exchange class:

  • deposit_to_silhouette(contract_address: str, token_symbol: str, amount: str, converter: TokenConverter) -> dict - Deposit tokens from Hyperliquid to Silhouette contract

All other Hyperliquid SDK methods work exactly as documented in the official Hyperliquid SDK.

Silhouette API Client

The SilhouetteApiClient provides access to the Silhouette shielded exchange:

  • Dict-based API: All methods return plain Python dicts with camelCase keys matching the API
  • No model imports needed: Pydantic models are used internally for validation, but you work with simple dicts
  • User operations: Balances, withdrawal initiation
  • Order management: Create, cancel, query orders
  • Delegated orders: List, get, and batch retrieve delegated orders
  • Trade execution: Privacy-preserving order execution
  • Automatic authentication: SIWE-based session management with automatic token refresh

API response structure:

# All responses are dicts with camelCase keys
response = client.user.get_balances()
# {
#   "responseMetadata": {"timestamp": 1234567890, "requestId": "..."},
#   "balances": [{"token": "USDC", "available": "1000.0", ...}]
# }

Delegated orders

Delegated orders are orders placed on Hyperliquid by Silhouette on behalf of a trader. Query them using the delegated_order operations:

# List delegated orders with optional filters
orders = client.delegated_order.list_delegated_orders(
    status="open",
    limit=50,
)
print(f"Found {len(orders['orders'])} orders")

# Get a single order by ID
order = client.delegated_order.get_delegated_order("order-id-here")
print(f"Order status: {order['order']['status']}")

# Batch retrieve multiple orders
batch = client.delegated_order.batch_get_delegated_orders(
    ["order-1", "order-2", "order-3"]
)
print(f"Found: {len(batch['orders'])}, Not found: {batch['notFound']}")

API Design

Why Dicts Instead of Models?

The SDK uses a hybrid approach for optimal developer experience:

Internal (validation):

  • Pydantic models auto-generated from OpenAPI spec
  • Runtime type validation of all requests and responses
  • Models stay in sync with API via regeneration

External (your code):

  • Plain Python dicts with camelCase keys
  • No need to import generated models
  • Simple dict access: response["withdrawalId"]
  • Clean, Pythonic API

Regenerating models

Models are generated from the OpenAPI specification. When the Silhouette API changes, regenerate the models to stay in sync:

# Fetch spec from local Heimdall and regenerate models
./scripts/regenerate-models.sh

# Or specify a custom URL
./scripts/regenerate-models.sh https://api.silhouette.exchange

# Then run tests to catch any breaking changes
make test

Requires curl, jq, and openapi-generator-cli to be installed.

Configuration

Create examples/config.json from the example template:

cp examples/config.json.example examples/config.json

Then configure:

  • account_address: Your wallet's public address
  • secret_key: Your wallet's private key (or use keystore_path for a keystore file)
  • use_testnet: Set to true for testnet, false for mainnet

[Optional] Using an API Wallet

Generate and authorise a new API private key on https://app.hyperliquid.xyz/API, and set the API wallet's private key as the secret_key in examples/config.json. Note that you must still set the public key of the main wallet (not the API wallet) as the account_address.

Usage Examples

See examples/ for complete examples:

Run any example after configuring your credentials:

python examples/silhouette_full_workflow.py

Development

Prerequisites

  • Python 3.10 or higher
  • Poetry for dependency management

Setup

# Install Poetry (if not already installed)
curl -sSL https://install.python-poetry.org | python3 -

# Install dependencies
make install

Development Workflow

Code Quality and Linting

This project uses ruff for linting and formatting, with pre-commit hooks for automated checks.

Normal development workflow:

  1. Make your changes
  2. Run git add . to stage changes
  3. Run git commit - pre-commit hooks will run automatically

If pre-commit hooks fail:

  1. make check - See all linting issues
  2. make fix - Auto-fix safe issues
  3. make format - Format code
  4. make test - Run tests
  5. Stage changes and commit again

Available Make Commands

make build                 # Builds as a tarball and a wheel
make check                 # Run ruff check without fixes
make check-safety          # Run safety checks on dependencies
make cleanup               # Cleanup project
make fix                   # Run ruff check with fixes
make fix-unsafe            # Run ruff check with unsafe fixes
make format                # Run ruff format
make install               # Install dependencies from poetry.lock
make install-types         # Find and install additional types for mypy
make lockfile-update       # Update poetry.lock
make lockfile-update-full  # Fully regenerate poetry.lock
make poetry-download       # Download and install poetry
make pre-commit            # Run all pre-commit hooks
make publish               # Publish the package to PyPI
make test                  # Run tests with pytest
make update-dev-deps       # Update development dependencies to latest versions

Run make without arguments to see this list of commands.

Running Tests

# Run all tests
make test

# Run specific test file
poetry run pytest tests/hyperliquid/info_test.py -v

# Run with coverage report
poetry run pytest --cov=silhouette --cov-report=html

Project Structure

silhouette-python-sdk/
├── silhouette/
│   ├── api/              # Silhouette API client
│   │   ├── client.py     # Main API client (dict-based API)
│   │   ├── auth.py       # SIWE authentication
│   │   └── generated/    # Generated Pydantic models from OpenAPI spec
│   │       └── models/   # Request/response models (internal use only)
│   ├── hyperliquid/      # Enhanced Hyperliquid SDK wrappers
│   │   ├── info.py       # Enhanced Info class
│   │   ├── exchange.py   # Enhanced Exchange class
│   │   └── utils/        # Re-exported utilities
│   └── utils/
│       └── conversions.py # Token conversion utilities
├── tests/                # Test suite
│   ├── api/              # API client tests
│   ├── hyperliquid/      # Hyperliquid wrapper tests
│   └── utils/            # Utility tests
└── examples/             # Usage examples

Note: The generated/models/ directory contains Pydantic models auto-generated from the OpenAPI specification. These are used internally for validation but you don't need to import them - the API client returns plain dicts.

Releases

See GitHub Releases for available versions.

We follow Semantic Versioning and use Release Drafter for automated release notes.

Building and Releasing

  1. Bump version: poetry version <major|minor|patch>
  2. Commit changes: git commit -am "Bump version to X.Y.Z"
  3. Create GitHub release
  4. Publish: make publish

Licence

This project is licensed under the terms of the MIT licence. See LICENSE for more details.

@misc{silhouette-python-sdk,
  author = {Silhouette},
  title = {Python SDK for trading on Silhouette - the shielded exchange on Hyperliquid},
  year = {2025},
  publisher = {GitHub},
  journal = {GitHub repository},
  howpublished = {\url{https://github.com/silhouette-exchange/silhouette-python-sdk}}
}

Credits

This project was generated with python-package-template.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

silhouette_python_sdk-0.2.1.tar.gz (92.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

silhouette_python_sdk-0.2.1-py3-none-any.whl (220.7 kB view details)

Uploaded Python 3

File details

Details for the file silhouette_python_sdk-0.2.1.tar.gz.

File metadata

  • Download URL: silhouette_python_sdk-0.2.1.tar.gz
  • Upload date:
  • Size: 92.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.4 CPython/3.13.3 Darwin/24.6.0

File hashes

Hashes for silhouette_python_sdk-0.2.1.tar.gz
Algorithm Hash digest
SHA256 c394eea2f6faf2a28fc5bab31b21adde2b9cd198162f5d4fab9e2427e9b3495e
MD5 67766cae8011689388af305d1d7c1803
BLAKE2b-256 93534ba1936b0d494a99a4427cc2e0fb8d71ae9fbedee7d002e14c3059c88016

See more details on using hashes here.

File details

Details for the file silhouette_python_sdk-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for silhouette_python_sdk-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9e424714fd917a147908584ce4d2364d3e1d54ac5279c9e894f528d2744dc447
MD5 f11f580bfc5de4f8961feb100a55d8c2
BLAKE2b-256 e6c7be325b41353f1af4204938eaf48c6316b122c3c5f8c3337ad075913a0ce7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page