swap
Swap through the best-quoting venue; falls back to Uniswap V3 if the chosen venue fails to fill. Returns the transaction hash — pair with wait_for_swap, or use swap_and_wait to do both in one call.
async def swap(self, params: SwapParams, opts: SwapOptions | None = None) -> str
async def swap_and_wait(self, params: SwapParams, opts: SwapOptions | None = None) -> SwapResultUsage
from propamm import SwapParams
from propamm.common.helpers import apply_slippage, deadline_in, parse_ether
from propamm.common.tokens import ETH_SENTINEL, USDC
from config import account, router
amount_in = parse_ether("1")
quote = await router.quote(ETH_SENTINEL, USDC, amount_in)
tx_hash = await router.swap(
SwapParams(
token_in=ETH_SENTINEL,
token_out=USDC,
amount_in=amount_in,
amount_out_min=apply_slippage(quote.amount_out, 50),
recipient=account.address,
deadline=deadline_in(300),
)
)from propamm import ContractClient, PropAmmRouter
from propamm.common.accounts import account_from_key
account = account_from_key("0x...")
client = ContractClient("https://...", account=account)
router = PropAmmRouter(client, "0x...")Returns
str
The transaction hash. Gas is estimated before sending, so reverts surface as errors without spending gas.
swap_and_wait
Same parameters; additionally waits for the receipt and decodes the outcome. Returns SwapResult.
result = await router.swap_and_wait(SwapParams(...))Parameters
params
- Type:
SwapParams
The parameters shared by every swap entrypoint — see the type for field-by-field docs. Derive amount_out_min from a quote with apply_slippage, and deadline with deadline_in.
tx_hash = await router.swap(
SwapParams(
# ...
amount_out_min=apply_slippage(quote.amount_out, 50), # quote - 0.5%
)
)opts (optional)
- Type:
SwapOptions
Per-swap options: restrict the venues and/or charge a frontend fee.
venues restricts the swap: a single entry executes through that venue directly (raising UnknownVenue on a non-venue address), several re-quote on-chain and fill via the best of them. Must be non-empty when present; omit to swap through the best-quoting venue overall.
from propamm import SwapOptions
from propamm.common.pamms import BEBOP, FERMI, KIPSELI
# exactly this venue
tx_hash = await router.swap(params, SwapOptions(venues=[KIPSELI]))
# best of a subset
tx_hash2 = await router.swap(params, SwapOptions(venues=[FERMI, BEBOP]))frontend_fee skims a fee from the output token, paid to its recipient. bps must be an integer in [1, MAX_FEE_BPS] (100 = 1%) — validated before sending. With a fee, amount_out_min is the net minimum the recipient must receive after the fee, and the decoded result's fee field (via wait_for_swap) carries the charged amount and recipient.
from propamm import FrontendFee, SwapOptions
tx_hash = await router.swap(
params,
SwapOptions(frontend_fee=FrontendFee(bps=25, recipient="0x...")), # 0.25%
)gas_limit sets an explicit transaction gas limit, overriding the per-function default described below.
tx_hash = await router.swap(params, SwapOptions(gas_limit=800_000))Gas limits
Swaps attach a hardcoded per-function gas limit and skip node gas estimation. Estimation runs against the current state, but the swap can take a heavier branch when it executes, so an estimate can under-shoot and the transaction runs out of gas. The hardcoded limits sit above the worst observed branch (plus headroom), and are tiered by how much quoting each entrypoint does on-chain (a single named venue is cheapest; the all-venues requote is highest).
Pass SwapOptions.gas_limit to override the default for a call.