Python SDK for interacting with the PropAMM contracts
Project description
PropAMM Python SDK
An async Python SDK for the PropAMMRouter contract, built on
web3.py.
Features:
- Typed router bindings: quote and swap across all whitelisted venues, a single venue, or a chosen subset, plus the router's views and ERC-20 approvals.
- Accurate quotes: quotes automatically apply fresh pAMM state overrides, so they price live off-chain liquidity rather than stale on-chain state.
- Helpers: amount/unit conversion, slippage, deadlines, and well-known token and venue addresses.
- A typed error hierarchy: contract reverts surface as human-readable
errors (e.g.
InsufficientOutput(...)).
Method names drop the on-chain V1 suffix (router.swap(...) calls swapV1).
A client is read-only by default; pass an account to send transactions.
Setup
Using uv (installs the exact pinned versions from uv.lock):
uv sync --extra dev
uv run pytest # incl. ABI selector & overrides regression tests
uv run ruff check .
Using pip (resolves the dependency ranges in pyproject.toml):
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
ruff check .
Getting started
Quote and swap 1 ETH for USDC through the best venue:
import asyncio
from propamm import ContractClient, PropAmmRouter, SwapParams
from propamm.common.accounts import account_from_key
from propamm.common.helpers import apply_slippage, deadline_in, parse_ether
from propamm.common.tokens import ETH_SENTINEL, USDC
PRIVATE_KEY = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" # anvil rich account
RPC_URL = "http://localhost:8545" # local anvil instance
ROUTER_ADDRESS = "0x4DdF368080CD7946db5b459aD591c350158175e1" # mainnet router deployment
async def main():
account = account_from_key(PRIVATE_KEY)
client = ContractClient(RPC_URL, account=account)
router = PropAmmRouter(client, ROUTER_ADDRESS)
amount_in = parse_ether("1")
quote = await router.quote(ETH_SENTINEL, USDC, amount_in)
result = await router.swap_and_wait(
SwapParams(
token_in=ETH_SENTINEL,
token_out=USDC,
amount_in=amount_in,
amount_out_min=apply_slippage(quote.amount_out, 50), # quote - 0.5%
recipient=account.address,
deadline=deadline_in(300), # now + 5 min
)
)
print(f"received {result.amount_out} USDC via {result.executed_venue}")
asyncio.run(main())
A runnable version lives in examples/getting_started.py.
python3 examples/getting_started.py
It defaults to a local anvil mainnet fork (anvil --fork-url <mainnet rpc>)
with anvil's default funded account and the mainnet router deployment. Override
with RPC_URL / PRIVATE_KEY / ROUTER_ADDRESS / SLIPPAGE_BPS.
Layout
| Module | Purpose |
|---|---|
propamm.client |
ContractClient: AsyncWeb3 wrapper (contract / call_with_overrides / send / wait_for_transaction). |
propamm.router |
PropAmmRouter bindings: quotes, swaps, ERC-20, views. |
propamm.router.abi |
Vendored router ABI and custom-error naming. |
propamm.overrides |
pAMM state-override sources (OverridesRpcSource, OverridesWsSource). |
propamm.common |
tokens, pamms, helpers, accounts. |
Quotes & state overrides
Quote functions are nonpayable on-chain (not view), so they run through
eth_call simulation. By default each quote attaches the latest pAMM state
overrides (streamed from Titan via OverridesWsSource) plus the snapshot's
block number/timestamp, so venues price fresh off-chain liquidity. Pass
QuoteOptions(overrides=None) to quote without overrides, or supply your own
OverridesSource / OverridesSnapshot.
Note: quotes apply fresh overrides, but a fork still executes swaps against its frozen state — if a swap reverts with
InsufficientOutputon a fork, raise the slippage. Live chains fill at the quoted state normally.
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 propamm-1.0.0.tar.gz.
File metadata
- Download URL: propamm-1.0.0.tar.gz
- Upload date:
- Size: 168.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.22 {"installer":{"name":"uv","version":"0.11.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3699224716d34378e21d3af77483de2d393434e3ddd0c5560633aad9d6ba52ce
|
|
| MD5 |
afe2ed16db83a98949d7c7ecc66196f9
|
|
| BLAKE2b-256 |
a62ddf75d6a3102e1e3cfb3f03c830c7493ac8eab0febf6b8075be558023c06d
|
File details
Details for the file propamm-1.0.0-py3-none-any.whl.
File metadata
- Download URL: propamm-1.0.0-py3-none-any.whl
- Upload date:
- Size: 25.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.22 {"installer":{"name":"uv","version":"0.11.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
635216daaa5f78cd2d28831703fa7e41136446d73954febe80d9e131da76c011
|
|
| MD5 |
2ca45f650957a2605808d447e84d27e3
|
|
| BLAKE2b-256 |
1cc16e7d7b91cca9565136eb542e622b6c906b9e3ab999370e6736df69381496
|