import {
createComposeSdk,
guards,
materialisers,
resources,
} from '@lifi/composer-sdk';
// Ethereum mainnet (chainId 1).
const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
const WETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2';
const UNISWAP_V2_ROUTER = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D';
const UNISWAP_V2_FACTORY = '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f';
const USDC_WETH_PAIR = '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc';
const SIGNER = '0xYourSignerAddress';
const sdk = createComposeSdk({
baseUrl: 'https://composer.li.quest',
apiKey: process.env.LIFI_API_KEY!,
});
const builder = sdk.flow(1, {
name: 'uniswap-v2-add-liquidity-usdc-weth',
inputs: {
usdcIn: resources.erc20(USDC, 1),
},
});
// Halve the USDC: `a` is deposited as is, `b` is swapped to WETH.
const { a: usdcHalf, b: usdcToSwap } = builder.core.split('split', {
bind: { source: builder.inputs.usdcIn },
config: { bps: 5000 },
});
const swap = builder.lifi.swap('swap', {
bind: { amountIn: usdcToSwap },
config: {
resourceOut: resources.erc20(WETH, 1),
slippage: 0.03, // the swap may deliver up to 3% less WETH than quoted
},
});
builder.uniswapV2.addLiquidity('add-liquidity', {
bind: {
tokenA: usdcHalf,
tokenB: swap.amountOut,
},
config: {
router: UNISWAP_V2_ROUTER,
factory: UNISWAP_V2_FACTORY,
pair: USDC_WETH_PAIR,
},
guards: [
// Revert unless the pool price is within ±50 bps of the simulated price.
guards.band({ port: 'poolPrice', bps: 50 }),
// Must cover the swap's 3% tolerance plus the 50 bps band.
guards.slippage({ port: 'liquidity', bps: 350 }),
],
});
const result = await builder.compile({
signer: SIGNER,
inputs: {
usdcIn: materialisers.directDeposit({ amount: '2000000000' }), // 2,000 USDC
},
// Sends the UNI-V2 LP token and any unused USDC or WETH to the signer.
sweepTo: builder.context.sender,
// The default price-impact check rejects this deposit; the guards protect it.
maxPriceImpactBps: 0,
});
for (const key of ['add-liquidity.liquidity', 'add-liquidity.residualA', 'add-liquidity.residualB']) {
const output = result.outputs[key];
console.log(key, output?.amount.estimate?.value, output?.amount.minimum?.value);
}