SwapExactAmountIn vs SwapExactAmountOut in Osmosis Agent Toolkit: Key Differences Explained
SwapExactAmountIn transactions specify an exact input amount and guarantee a minimum output, while SwapExactAmountOut transactions specify an exact output amount and cap the maximum input consumed.
The Osmosis Agent Toolkit provides two distinct swap transaction types that map directly to Osmosis Pool Manager messages. Understanding the directional difference between SwapExactAmountIn and SwapExactAmountOut is critical for implementing precise token exchange logic, slippage protection, and capital-efficient trading strategies in your DeFi applications.
Core Behavioral Differences
The fundamental distinction lies in which side of the trade is fixed and which side is bounded by slippage tolerance.
SwapExactAmountIn: Fixed Input, Variable Output
When using SwapExactAmountIn, you specify the exact input token amount (tokenIn) you are willing to spend. The protocol guarantees you receive at least a minimum amount of the output token (tokenOutMinAmount), calculated based on your slippage tolerance.
The toolkit computes the minimum output in makeSwapExactAmountInEncodeObject within packages/core/src/tx/swap.ts using:
tokenOutMinAmount = floor(quote.amount_out * (1 - slippage/100))
This approach is ideal when you have a fixed budget—for example, spending exactly 100 OSMO—and want to receive the best possible rate of the target token without receiving less than a specified floor.
SwapExactAmountOut: Variable Input, Fixed Output
Conversely, SwapExactAmountOut allows you to specify the exact output token amount (tokenOut) you want to receive. The protocol ensures you spend no more than a maximum amount of the input token (tokenInMaxAmount).
The slippage-adjusted maximum is computed in makeSwapExactAmountOutEncodeObject:
tokenInMaxAmount = ceil(quote.amount_in * (1 + slippage/100))
Use this method when you must obtain a precise quantity of the target token—such as exactly 50 ATOM—and are willing to spend up to a known ceiling of the source token.
Architectural Flow in the Toolkit
Both transaction types follow a consistent three-phase pipeline implemented in packages/core/src/tx/swap.ts and packages/core/src/tx/msg.ts.
1. Quote Retrieval
The toolkit queries Osmosis Sidecar services to obtain routing and pricing data:
- SwapExactAmountIn uses
SidecarOutGivenInQuoteResponseto determine expected output given a fixed input. - SwapExactAmountOut uses
SidecarInGivenOutQuoteResponseto calculate required input for a fixed output.
2. Message Encoding
The high-level helpers transform quotes into Cosmos SDK messages:
makeSwapExactAmountInEncodeObjectbuilds either aswapExactAmountInmessage or asplitRouteSwapExactAmountInfor multi-pool routes.makeSwapExactAmountOutEncodeObjectbuilds either aswapExactAmountOutmessage or asplitRouteSwapExactAmountOut.
These functions delegate to low-level constructors in packages/core/src/tx/msg.ts—specifically makeSwapExactAmountInMsg, makeSwapExactAmountOutMsg, and their split-route variants—which utilize osmosis.poolmanager.v1beta1.MessageComposer.withTypeUrl to generate protobuf-compatible messages.
3. Transaction Broadcast
The resulting encode object is passed to a signing client (e.g., SigningStargateClient from @cosmjs/stargate) and broadcast to the chain. The Osmosis Pool Manager enforces the min/max constraints at the protocol level, guaranteeing the bounds specified in your slippage calculations.
Implementation Examples
SwapExactAmountIn with Single Route
import { core } from '@osmosis/agent-toolkit';
// Quote from Sidecar API for swapping 1 OSMO
const quote = {
amount_in: { denom: 'uosmo', amount: '1000000' },
amount_out: '2500000', // Expected 2.5 ATOM
route: [{ pools: [{ id: 1, token_out_denom: 'uatom' }] }],
};
const slippage = 0.5; // 0.5% tolerance
const swapMsg = core.tx.swap.makeSwapExactAmountInEncodeObject(
'osmo1useraddress...',
quote,
slippage,
);
// Returns encode object ready for signing
This invokes makeSwapExactAmountInEncodeObject in packages/core/src/tx/swap.ts, which automatically sets your minimum output threshold based on the 0.5% slippage parameter.
SwapExactAmountOut with Split Routes
import { core } from '@osmosis/agent-toolkit';
// Quote for receiving exactly 5 ATOM across multiple pools
const quote = {
amount_in: '1200000', // Estimated input (will be capped)
amount_out: { denom: 'uatom', amount: '5000000' },
route: [
{
pools: [
{ id: 2, token_in_denom: 'uosmo' },
{ id: 3, token_in_denom: 'uosmo' },
],
out_amount: '3000000',
},
{
pools: [{ id: 4, token_in_denom: 'uosmo' }],
out_amount: '2000000',
},
],
};
const slippage = 1.0; // 1% tolerance
const swapMsg = core.tx.swap.makeSwapExactAmountOutEncodeObject(
'osmo1useraddress...',
quote,
slippage,
);
The toolkit abstracts the complexity of multi-route swaps; makeSwapExactAmountOutEncodeObject handles both single-pool and split-route scenarios transparently.
Summary
- SwapExactAmountIn locks the input amount and guarantees a minimum output using
floor(quote.amount_out * (1 - slippage/100)), ideal for fixed-budget scenarios. - SwapExactAmountOut locks the output amount and caps the maximum input using
ceil(quote.amount_in * (1 + slippage/100)), ideal for target-precision requirements. - Both transaction types support single-route and split-route swaps automatically via the routing abstraction in
packages/core/src/tx/swap.ts. - The toolkit handles message construction through
makeSwapExactAmountInEncodeObjectandmakeSwapExactAmountOutEncodeObject, delegating toosmosis.poolmanager.v1beta1.MessageComposerfor protobuf generation.
Frequently Asked Questions
When should I use SwapExactAmountIn versus SwapExactAmountOut?
Use SwapExactAmountIn when you want to spend a specific amount of tokens and accept whatever output the market provides (e.g., "Sell exactly 100 OSMO"). Use SwapExactAmountOut when you need to acquire a specific quantity of a token (e.g., "Buy exactly 50 ATOM") regardless of the variable input cost. The choice depends on whether your financial logic requires budget certainty or target token certainty.
How does the Osmosis Agent Toolkit calculate slippage bounds?
For SwapExactAmountIn, the toolkit calculates tokenOutMinAmount by flooring the quoted output multiplied by (1 - slippage/100). For SwapExactAmountOut, it calculates tokenInMaxAmount by ceiling the quoted input multiplied by (1 + slippage/100). These calculations occur in makeSwapExactAmountInEncodeObject and makeSwapExactAmountOutEncodeObject respectively, ensuring the blockchain enforces your tolerance at the protocol level.
Do both transaction types support multi-pool routing?
Yes. Both makeSwapExactAmountInEncodeObject and makeSwapExactAmountOutEncodeObject automatically detect multi-pool routes from the Sidecar quote and generate either simple swap messages or split-route variants (splitRouteSwapExactAmountIn and splitRouteSwapExactAmountOut). The abstraction handles the complexity of multi-hop routing without requiring manual message construction by the developer.
Where are the core swap transaction functions defined?
The high-level encoding logic resides in packages/core/src/tx/swap.ts, while the low-level Osmosis Pool Manager message constructors live in packages/core/src/tx/msg.ts. The public-facing tool that orchestrates quoting, encoding, and broadcasting is located in packages/core/src/tools/swap.ts, providing a complete workflow from price discovery to on-chain execution.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →