Skip to main content

layerhop (Python SDK)

PyPI Python license docs

Best-price cross-chain and same-chain swaps through one non-custodial API. Sync and async clients on top of httpx, mirroring the TypeScript @layerhop/sdk.

The SDK never holds keys. It returns unsigned transactions. Your own wallet library (web3.py, eth-account, solders, a KMS, a hardware wallet…) signs and broadcasts them.

Install

pip install layerhop

Python 3.9+. The only runtime dependency is httpx.

Quickstart

Amounts are integer strings in base units (100 USDC = "100000000"), never floats.

from layerhop import LayerHop

lh = LayerHop(api_key="lh_live_...")  # api_key is optional

# 1. Quote: every provider is asked; `best` pays the user the most.
q = lh.quote("base", "USDC", "100000000", "solana", "SOL",
             sender="0xYourEvmAddress", recipient="YourSolanaAddress")
best = q["best"]
print(best["provider"], best["dstAmount"], best["estimatedSeconds"])

# 2. Build the unsigned transaction.
tx = lh.build_tx(best["quoteId"])

# 3. Sign and send with YOUR wallet library (example: web3.py on Base).
if tx["vm"] == "evm":
    # if tx.get("approval"): send ERC-20 approve(spender, amount) on approval["token"] first
    tx_hash = w3.eth.send_transaction({
        "to": tx["to"], "data": tx["data"], "value": int(tx["value"]), "chainId": tx["chainId"],
    }).hex()
else:
    # Solana: tx["serializedTx"] is a base64 VersionedTransaction; sign it with solders.
    # When tx.get("submitViaApi") is true, only sign, then: tx_hash = lh.submit(best["quoteId"], signed_b64)
    ...

# 4. Tell LayerHop you broadcast it (enables tracking, history and webhooks).
lh.report_submitted(best["quoteId"], tx_hash)

# 5. Track until filled / refunded / failed.
for s in lh.watch(best["provider"], tx_hash):
    print(s["state"], s.get("dstTxHash"))

Async

from layerhop import AsyncLayerHop

async with AsyncLayerHop() as lh:
    q = await lh.quote("base", "USDC", "100000000", "solana", "SOL", sender=s, recipient=r)
    async for st in lh.watch("relay", tx_hash):
        print(st["state"])

API

Method Endpoint
health() GET /v1/health
chains() GET /v1/chains
tokens(chain) GET /v1/tokens?chain=
quote(src_chain, src_token, amount, dst_chain, dst_token, *, sender, recipient, slippage_bps=50) GET /v1/quote
build_tx(quote_id) POST /v1/orders → the tx
simulate(quote_id) POST /v1/simulate (dry-run, records nothing)
submit(quote_id, signed_transaction) POST /v1/orders/submit (Solana submitViaApi only)
report_submitted(quote_id, tx_hash) POST /v1/orders/{quoteId}/submitted
status(provider, id) GET /v1/orders/{provider}/{id}
watch(provider, id, *, interval=3.0, timeout=1800) polls status, yields on change, stops when final
list_orders(*, address, status, cursor, limit) GET /v1/orders

Client options: base_url (default https://api.layerhop.com), api_key (sent as x-api-key), channel (default "api"), integrator, integrator_fee_bps, timeout, and http_client / transport for custom httpx setups or tests.

Responses are plain dicts typed with TypedDict (keys keep the API's camelCase), so new fields never break you.

Errors

Every non-2xx response raises LayerHopApiError with a stable code (QUOTE_EXPIRED, NO_ROUTE, …), status, message and request_id. See https://docs.layerhop.com/errors/<code>.

from layerhop import LayerHopApiError
try:
    lh.build_tx(quote_id)
except LayerHopApiError as e:
    if e.code == "QUOTE_EXPIRED":
        ...  # re-quote

Webhooks

from layerhop import verify_webhook_signature, construct_webhook_event

# Flask example — use the RAW body
ok = verify_webhook_signature(secret, request.get_data(), request.headers.get("LayerHop-Signature"))
event = construct_webhook_event(secret, request.get_data(), request.headers.get("LayerHop-Signature"))

The header is t=<unix>,v1=<hex HMAC-SHA256(secret, "<t>.<body>")>. Signatures older or newer than 300 s (tolerance) are rejected; comparison is constant-time.

Development

python3 -m venv .venv && .venv/bin/pip install -e '.[dev]'
.venv/bin/python -m pytest

MIT licensed.

Metadata

Release files for layerhop 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for layerhop 0.1.0
File Size Uploaded Provenance
layerhop-0.1.0.tar.gz 12.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for layerhop 0.1.0
File Interpreter ABI Platform
layerhop-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 23.9 kB

Release files / layerhop-0.1.0.tar.gz

Download URL layerhop-0.1.0.tar.gz
Size 12.3 kB
Tags Source
SHA-256 checksum
How to use checksums
a9b3100f35aea38c6f3d8bfdfb5e378dc7f6b3b1bdaac5b1acf9f806dfe16555
BLAKE2b-256 checksum
How to use checksums
a7ea52685c7c9a362b128e06235fe4cf881705c52a598a69bfa0090417f8039c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.2

Release files / layerhop-0.1.0-py3-none-any.whl

Download URL layerhop-0.1.0-py3-none-any.whl
Size 11.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
328e53bc175025b028a7a22b10df28579c5de9b8612b0ebad46e94030a4a2e8a
BLAKE2b-256 checksum
How to use checksums
60389da79a0181dec2eda0a75cf63293e4d4ff196c7d3f63c8b288a0c2053a4b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.2

Security for layerhop 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page