What you’ll build: A USDC to WETH
swapWithAllowance transaction against BopAMM, quoted and simulated mid-block, then submitted through a block builder.Time required: 15-20 minutesPrerequisites: Basic EVM knowledge and web3.py, a BopAMM API key, a funded signing key, and the ability to submit transactions through a supported builder RPC.Setup
Installweb3, eth-account, and httpx, then define the constants and contract handles used throughout. This quickstart uses BopAmm.quote() to quote the swap and BopAmmRouter.swapWithAllowance() to execute it.
Keep
API_KEY and PRIVATE_KEY out of source. Load them from environment variables (for example with os.environ and python-dotenv) rather than hardcoding them.1. Approve the BopAMM router
Before swapping ERC-20 input, the router needs permission to pull your USDC. ApproveBopAmmRouter for the scope of this demo (10 USDC). This is the standard check-and-approve pattern. See Token Approvals for the canonical helper and the max-vs-exact tradeoffs.
- The approval target is the BopAmmRouter contract (
BOPAMM_ROUTER_ADDRESS). The core pool does not pull taker funds on the router path. - Native ETH in needs no approval. Send
msg.value == amountInand pass the sentinel address0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeEastokenIn. - Cross-pair swaps (for example WETH to WBTC) don’t require a USDC approval. Intermediate USDC stays inside the contracts.
2. Fetch the live state
You can get the current snapshot two ways: a call toGET /state, or the streaming WebSocket, which pushes a fresh snapshot whenever a new aggregated book is available. Both carry the same data: the snapshot block, the aggregated books, and the state_overrides you need to quote against the live book before the on-chain update lands. Use REST for a single swap and the stream for continuous quoting.
- Polling over REST
- Streaming over WebSocket
The operator exposes the current aggregated book at Example response (abridged):
GET /state.3. Get a quote
quote() is a view function on the core pool that walks the book and returns the expected output for a given input. To quote against the latest book at any point in the block, apply the state_overrides as a stateDiff against the contract from the snapshot.
For native ETH at the router boundary, quote the core pool with WETH. The router normalizes the native ETH sentinel to WETH before calling
BopAmm.4. Add a fee (optional)
To charge an integrator fee on the BopAMM leg, setFEE_BPS and FEE_RECIPIENT before building the router calldata:
minAmountOut is checked, so quote and simulate with amount_after_router_fee(...) as shown above. A configured percentage of the fee goes to the protocol; the rest goes to FEE_RECIPIENT.
5. Simulate and size gas
Before broadcasting, run the router swap as aneth_call against the same override to catch reverts without spending gas, then estimate gas with the override to set a real gas limit.
Pass the same
state_override to estimate_gas. A plain estimate_gas at the chain head can revert before the current book has landed on-chain.6. Submit through a block builder
This is the step that differs from RFQ and Aggregation. A plain BopAMM swap settles reliably when a builder that supports BopAMM includes it in the same block as the matching book update. Current supported builders are:- Titan
- BuilderNet
- Quasar
- Bombora
confidence (the chance of inclusion in the next block) with the fees that buy it. Higher confidence costs more:
result is your transaction hash. Track it on a block explorer to confirm it landed in the target block.
Next steps
Fees
Add optional integrator fees to router calldata or
/quote.Direct pool integration
Use push-payment
swap or callback settlement directly against BopAmm.Falling back to RFQ
Get ready
swapWithFallback calldata from the /quote endpoint.