Python client for the LI.FI API: bridge + DEX aggregator for any-to-any cross-chain swaps.
Project description
lifi-py
A typed Python client for the LI.FI API — the bridge + DEX aggregator for any-to-any cross-chain swaps and bridges across 74 chains.
The killer feature: get_quote() returns a ready-to-sign transactionRequest
directly — one call, no separate assemble step.
- Sync (
LifiClient) and async (AsyncLifiClient) clients on top ofhttpx. - All responses parsed into
pydanticv2 models with full type hints (py.typed). - Built-in rate-limit awareness: reads the
ratelimit-*headers, throttles proactively, and retries429s with backoff. - Optional
web3.pyintegration for signing/sending the returned transaction.
Install
pip install lifi-py
# with web3 signing helpers:
pip install 'lifi-py[exec]'
Quickstart — cross-chain quote with a ready-to-sign tx (keyless, <5 lines)
from lifi_py import LifiClient
quote = LifiClient().get_quote(
from_chain=42161, to_chain=8453, # Arbitrum -> Base
from_token="0xaf88d065e77c8cC2239327C5EDb3A432268e5831", # USDC (Arbitrum)
to_token="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", # USDC (Base)
from_amount="1000000", from_address="0x47E2D28169738039755586743E2dfCF3bd643f86",
)
print(quote.estimate.to_amount, quote.transaction_request.to) # ~995000, 0x1231DEB6...
quote.transaction_request is an EVM transaction ready to sign and broadcast.
Signing & sending (optional, [exec] extra)
tx = quote.transaction_request.as_web3_tx() # hex fields decoded to ints, web3-shaped
signed = account.sign_transaction({**tx, "nonce": w3.eth.get_transaction_count(account.address)})
tx_hash = w3.eth.send_raw_transaction(signed.raw_transaction)
Tracking a bridge to completion
client = LifiClient()
status = client.poll_status(tx_hash="0x...", bridge=quote.tool) # polls until DONE/FAILED
print(status.status, status.is_done)
get_status() does a single check; poll_status() polls with exponential backoff
until the transfer reaches a terminal state (or raises TimeoutError).
Async
import asyncio
from lifi_py import AsyncLifiClient
async def main():
async with AsyncLifiClient() as client:
quote = await client.get_quote(...)
asyncio.run(main())
Endpoints
| Method | API endpoint |
|---|---|
get_quote(...) |
GET /quote — best single-step route + transactionRequest |
get_status(...) / poll_status(...) |
GET /status — track a transfer |
get_routes(...) |
POST /advanced/routes — multiple candidate routes |
get_step_transaction(step) |
POST /advanced/stepTransaction — calldata for one step |
get_chains() |
GET /chains |
get_tokens() |
GET /tokens |
get_tools() |
GET /tools — bridges + exchanges |
get_connections(...) |
GET /connections |
Authentication & rate limits
An API key is optional — every endpoint above works keyless. A key only raises your rate limits:
client = LifiClient(api_key="your-key") # sent as `x-lifi-api-key`
client = LifiClient(api_key="k", api_key_header="x-custom-key") # configurable header
client = LifiClient(base_url="https://staging.li.quest/v1") # configurable base URL
The client reads the API's ratelimit-limit / ratelimit-remaining / ratelimit-reset
response headers (exposed via client.rate_limit). When the quota is exhausted it
pauses before the next request; on a 429 it retries with backoff respecting the
reset window, raising LifiRateLimitError once retries are exhausted.
Configuration
| Argument | Default | Description |
|---|---|---|
api_key |
None |
Optional; raises rate limits. |
base_url |
https://li.quest/v1 |
API base URL. |
api_key_header |
x-lifi-api-key |
Header name for the key. |
timeout |
30.0 |
Per-request timeout (seconds). |
max_retries |
3 |
Max 429 retries before raising. |
http_client |
None |
Inject your own httpx.Client / AsyncClient. |
Development
pip install -e '.[dev,exec]'
ruff check .
mypy
pytest # unit tests (mocked HTTP, no network)
pytest -m integration # live smoke tests against the keyless API
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lifi_py-0.1.1.tar.gz.
File metadata
- Download URL: lifi_py-0.1.1.tar.gz
- Upload date:
- Size: 26.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a0b373fa8dc7c2e801eb8d9bb2b99f63ceb9eb0cbc1d33e5a1f28413d1d92f18
|
|
| MD5 |
88bd52f8b0553a5fcb0c54cef29492da
|
|
| BLAKE2b-256 |
392c7b82b4c0ecda41e8d261dfd2db36095126291e6e5ba3ca0c2067764f70a6
|
File details
Details for the file lifi_py-0.1.1-py3-none-any.whl.
File metadata
- Download URL: lifi_py-0.1.1-py3-none-any.whl
- Upload date:
- Size: 18.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b640d6d46fa2a0a993a7eff3db7be8107719045b796d0af16a327105e7f91582
|
|
| MD5 |
2fa3393fab20538294e05c15ac94ea51
|
|
| BLAKE2b-256 |
04e143c63182fafd6471339635f99744b00c8af583f0a3dd4a986a60d76bed25
|