Little John

Developers

Quotes, approvals and trade execution

Prepare Little John V10 buys and sells with ethers v6, including slippage, deadlines, approvals and Uniswap V4 quote differences.

Use eth_call for quotes

quoteBuy and quoteSell are not declared view. With ethers v6, use .staticCall(...) explicitly so that quoting does not send a transaction. Quote from the intended sender at a consistent recent block. The returned out is the expected output, and fee is the reported total trading fee; do not subtract it from out a second time.

StateBuy quoteSell quote
Bonding curvequoteBuy.staticCall(grossEth, overrides)quoteSell.staticCall(tokensIn, overrides)
Graduated V4quoteV4Buy.staticCall({from, value: grossEth, blockTag})quoteSell.staticCall(tokensIn, overrides)

Prepare a buy

import {parseEther} from 'ethers';
import {prepareBuy} from './littlejohn-v10-example.mjs';

const owner = await signer.getAddress();
const plan = await prepareBuy(rpc, {
  factoryIndex: 0n, owner, value: parseEther('0.001'), slippageBps: 50
});
// Display token address, input, out, minOut, fee, deadline and network.
// Only AFTER the user authorizes this exact transaction:
// const gas = await signer.estimateGas(plan.request);
// const tx = await signer.sendTransaction(plan.request);
// const receipt = await tx.wait(confirmations);

Bonding limits and graduation races

Before graduation, respect publicBuyOpensAt() and remainingBondGross(). Oversized buys revert; the example does not silently split them or alter the amount. Graduation is based on actual curve reserve and can occur inside the last curve buy. If market state changes after quoting, obtain a fresh quote and approval from the user when its terms change. A minimum-output check limits execution output, but does not freeze the market stage.

Prepare a sell and approval

import {parseUnits} from 'ethers';
import {prepareSell} from './littlejohn-v10-example.mjs';

const input = {factoryIndex: 0n, owner: await signer.getAddress(),
  amount: parseUnits('1000', 18), slippageBps: 50};
let plan = await prepareSell(rpc, input);
if (plan.approval) {
  // Ask separately before sending the exact-amount token approval.
  // const approvalTx = await signer.sendTransaction(plan.approval);
  // await approvalTx.wait(confirmations);
  // Then call prepareSell(rpc, input) again for a fresh sell quote.
} else {
  // Present the sell review, then authorize/send plan.request.
}

What your application must supply

  • An authenticated, authorized signer on chain 4663; matching the owner used in the quote. Never select a backend signing account from an untrusted chat message alone.
  • Gas estimation, sufficient native ETH for gas, and a clear transaction review.
  • A confirmation policy, replacement/cancellation handling and canonical receipt verification.
  • Nonce coordination for concurrent sends, persistent pending-transaction records, and bounded retries. Never blindly resend after an HTTP timeout.
  • Fresh quotes after approvals or expired deadlines. The example uses 120 seconds from the quoted block timestamp and a configurable minimum output; it is not a guaranteed execution price.

After Uniswap V4 graduation

The curve buy/sell entrypoints continue to route through its V4 integration. V4 buy quoting requires payable eth_call simulation; provider capability must be tested. Direct external pool routing is a separate integration with the Little John hook. Do not assume generic V4 support includes that hook. See the graduation explanation and reference.