LI.FI is a bridge and DEX aggregation protocol that offers the most efficient cross-chain swaps by routing through the best liquidity pools and bridges.
This guide provides step-by-step instructions for integrating the LI.FI plugin with BuildBear Sandboxes. The plugin enables developers to test and simulate cross-chain swaps using multiple bridges and DEXs for optimal routing. This integration facilitates efficient liquidity aggregation, seamless asset exchanges, and enhanced cross-chain development in a controlled sandbox environment.
Cross-Chain Testing : Simulate multi-chain interactions without real assets.
Seamless Integration : Works effortlessly within BuildBear’s sandbox.
Support for LI.FI SDK : Simulate bridging and swapping transactions.
Comprehensive Testing Logs : Access transaction details and validation reports.
Sandboxed Liquidity Access : Controlled liquidity aggregation testing.
How to install and configure the LI.FI Plugin in your BuildBear Sandbox
How to retrieve quotes for swapping for DAI to USDC on Polygon
How to extract and populate transactions using quote results
How to execute a transaction to Swap DAI to USDC, using LiFi DEX Aggregator
Log in to your BuildBear account.
Navigate to the Plugin Marketplace in both the source and destination sandboxes.
Search for LI.FI Plugin and click Install .
Create two new sandboxes or use existing ones.
Open the LI.FI Plugin.
Link the sandboxes to configure cross-chain interaction.
Install dependencies listed in package.json
Add your private key to your .env
file
// BuildBear API Configuration
const RPC_URL = "https://rpc.buildbear.io/{from-sandbox-id}" ;
Replace sandbox-id
with actual sandbox id of source chain sandbox
const API_URL =
"https://api.buildbear.io/{from-sandbox-id}/plugin/lifi/{to-sandbox-id}" ;
Replace {from-sandbox-id}
and {to-sandbox-id}
with your actual BuildBear sandbox IDs.
The /quote
endpoint takes these parameters:
fromChain
: Source chain ID
toChain
: Destination chain ID
fromToken
: ERC20 token on source chain
toToken
: ERC20 token on destination chain
fromAmount
: Amount of tokens to bridge/swap
fromAddress
: Sender's address
// Get a quote for your desired transfer
const getQuote = async (
fromChain : string | number ,
toChain : string | number ,
fromToken : string ,
toToken : string ,
fromAmount : string ,
fromAddress : string
) => {
try {
const result = await axios. get ( `${ API_URL }/quote` , {
params: {
fromChain,
toChain,
fromToken,
toToken,
fromAmount,
fromAddress,
},
});
console. log ( "=============LIFI QUOTE===============" );
console. log (result.data);
console. log ( "====================================" );
return result.data;
} catch ( error : any ) {
console. error (
"LI.FI API Error Details:" ,
error.response?.data || error.message
);
throw error;
}
};
The result of the API call will contain the information about the tokens to bridge/swap, networks involved, gas estimates, transaction request object, etc.
In our case the result will include information about the token swap.
For example:
estimates
:
estimate : {
tool : 'sushiswap' ,
approvalAddress : '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE' ,
toAmountMin : '994994' ,
toAmount : '999994' ,
fromAmount : '1000000000000000000' ,
feeCosts : [],
gasCosts : [ [Object] ],
executionDuration : 30 ,
fromAmountUSD : '1.0000' ,
toAmountUSD : '0.9999'
},
transactionRequest
Object:
transactionRequest : {
value : '0x0' ,
to : '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE' ,
data : '0x4666fc80a1e8a494d935dd33d76357c13a27826546f60f9933288faa50d660a46c338ea300000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000001308ca04d6e6243f65d73101b5a23bb6fb58723300000000000000000000000000000000000000000000000000000000000f2eb2000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000086c6966692d617069000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3078303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000000000000000000000000000000000000000000000000000085cd07ea01423b1e937929b44e4ad8c40bbb5e7100000000000000000000000085cd07ea01423b1e937929b44e4ad8c40bbb5e710000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a0630000000000000000000000003c499c542cef5e3811e1192ce70d8cc03d5c33590000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000184dd9c5f960000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a0630000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000003c499c542cef5e3811e1192ce70d8cc03d5c335900000000000000000000000000000000000000000000000000000000000f423a00000000000000000000000000000000000000000000000000000000000f2eb20000000000000000000000001231deb6f5749ef6ce6943a275a1d3e7486f4eae000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043028f3cf7ad23cd3cadbd9735aff958023239c6a06301ffff01f369277650ad6654f25412ea8bfbd5942733babc0085cd07ea01423b1e937929b44e4ad8c40bbb5e7100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' ,
chainId : 137 ,
gasPrice : '0xcc829accd' ,
gasLimit : '0x68c8a' ,
from : '0x1308cA04d6E6243F65D73101B5a23BB6Fb587233'
}
We need a helper function to get the approval call data, as well as a helper function to send transaction using the transaction request object received as a result of LI.FI quote
// Encode ERC20 Approval Transaction
const encodeApprovalCallData = ( spender : string , amount : string ) => {
const iface = new Interface ([
"function approve(address spender, uint256 amount)" ,
]);
return iface. encodeFunctionData ( "approve" , [spender, amount]);
};
// Send and confirm transactions
const sendTransaction = async (
provider : ethers . JsonRpcProvider ,
signer : ethers . Wallet ,
transactionRequest : { to : string ; data : string ; gasLimit ?: `0x${ string }` },
isApproval = false
) => {
try {
signer. connect (provider);
const tx = await signer. sendTransaction (
transactionRequest.gasLimit
? {
to: transactionRequest.to,
data: transactionRequest.data,
gasLimit: parseInt (transactionRequest.gasLimit, 16 ). toString (),
}
: { to: transactionRequest.to, data: transactionRequest.data }
);
await tx. wait ();
console. log (
`${
isApproval ? "Approval" : "LiFi Aggregator/Bridging"
} Transaction Sent! Hash: ${ tx . hash }`
);
console. log ( "Waiting for confirmation..." );
const receipt = await provider. getTransactionReceipt (tx.hash);
console. log ( "Transaction Confirmed!" );
return receipt;
} catch (error) {
console. error ( "Transaction Error:" , error);
throw error;
}
};
We will need to define the parameters to receive quotes from BuildBear LI.FI endpoint, as mentioned in Step 2. Once we have the quote, we approve the spending amount to the smart contract address in transaction request that will execute the swap transaction. After the approval, we use the transaction request object to send the actual transaction to the same smart contract address to initiate a LI.FI transfer
// Main Execution Flow
const run = async () => {
const provider = new ethers. JsonRpcProvider ( RPC_URL );
const signer = new ethers. Wallet (process.env. PRIVATE_KEY ! , provider);
// ----------- WETH Bridge Polygon to Ethereum -----------
// # Note: Uncomment the below params to fetch and execute bridging tx
// const fromChain = 137;
// const fromToken = "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619";
// const toChain = 1;
// const toToken = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
// const fromAmount = parseUnits("1", 18).toString();
// const fromAddress = signer.address;
// ----------- Lifi aggregator swap DAI to USDC on Polygon -----------
const fromChain = "POL" ;
const fromToken = "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063" ;
const toChain = "POL" ;
const toToken = "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359" ;
const fromAmount = parseUnits ( "1" , 18 ). toString ();
const fromAddress = signer.address;
const quote = await getQuote (
fromChain,
toChain,
fromToken,
toToken,
fromAmount,
fromAddress
);
const approvalTxRequest = {
to: quote.action.fromToken.address,
data: encodeApprovalCallData (
quote.transactionRequest.to,
maxUint256. toString ()
),
};
// Execute Approval Transaction
await sendTransaction (provider, signer, approvalTxRequest, true );
// Execute the Transaction
await sendTransaction (provider, signer, quote.transactionRequest, false );
};
run (). then (() => console. log ( "✅ DONE!" ));
The output similar to the following can be observed if the plugin is setup correctly.
=============LIFI QUOTE===============
{
type : 'lifi',
id: '8d1171b7-ffb6-49a2-a716-51cda8dfc29b:0',
tool: 'sushiswap',
toolDetails: {
key: 'sushiswap',
name: 'SushiSwap Aggregator',
logoURI: 'https://raw.githubusercontent.com/lifinance/types/main/src/assets/icons/exchanges/sushi.png'
},
action: {
fromToken: {
address: '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063',
chainId: 137,
symbol: 'DAI',
decimals: 18,
name: '(PoS) DAI Stablecoin',
coinKey: 'DAI',
logoURI: 'https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x6B175474E89094C44Da98b954EedeAC495271d0F/logo.png',
priceUSD: '1'
},
fromAmount: '1000000000000000000',
toToken: {
address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
chainId: 137,
symbol: 'USDC',
decimals: 6,
name: 'USD Coin',
coinKey: 'USDC',
logoURI: 'https://static.debank.com/image/coin/logo_url/usdc/e87790bfe0b3f2ea855dc29069b38818.png',
priceUSD: '0.9999000099990001'
},
fromChainId: 137,
toChainId: 137,
slippage: 0.005,
fromAddress: '0x1308cA04d6E6243F65D73101B5a23BB6Fb587233',
toAddress: '0x1308cA04d6E6243F65D73101B5a23BB6Fb587233'
},
estimate: {
tool: 'sushiswap',
approvalAddress: '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE',
toAmountMin: '994994',
toAmount: '999994',
fromAmount: '1000000000000000000',
feeCosts: [],
gasCosts: [ [Object] ],
executionDuration: 30,
fromAmountUSD: '1.0000',
toAmountUSD: '0.9999'
},
includedSteps: [
{
id: '0b124c28-3a1c-46f9-9aa7-deb4e04efea0',
type : 'swap',
action: [Object],
estimate: [Object],
tool: 'sushiswap',
toolDetails: [Object]
}
],
integrator: 'lifi-api',
transactionRequest: {
value: '0x0',
to: '0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE',
data: '0x4666fc80a1e8a494d935dd33d76357c13a27826546f60f9933288faa50d660a46c338ea300000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000001308ca04d6e6243f65d73101b5a23bb6fb58723300000000000000000000000000000000000000000000000000000000000f2eb2000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000086c6966692d617069000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3078303030303030303030303030303030303030303030303030303030303030303030303030303030300000000000000000000000000000000000000000000000000000000000000000000085cd07ea01423b1e937929b44e4ad8c40bbb5e7100000000000000000000000085cd07ea01423b1e937929b44e4ad8c40bbb5e710000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a0630000000000000000000000003c499c542cef5e3811e1192ce70d8cc03d5c33590000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000184dd9c5f960000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a0630000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000003c499c542cef5e3811e1192ce70d8cc03d5c335900000000000000000000000000000000000000000000000000000000000f423a00000000000000000000000000000000000000000000000000000000000f2eb20000000000000000000000001231deb6f5749ef6ce6943a275a1d3e7486f4eae000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043028f3cf7ad23cd3cadbd9735aff958023239c6a06301ffff01f369277650ad6654f25412ea8bfbd5942733babc0085cd07ea01423b1e937929b44e4ad8c40bbb5e7100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
chainId: 137,
gasPrice: '0xcc829accd',
gasLimit: '0x68c8a',
from: '0x1308cA04d6E6243F65D73101B5a23BB6Fb587233'
}
}
====================================
Approval Transaction Sent! Hash: 0x5a1650475682ec03498b5c8ac4b0c04f3941f5eb92f8310c12444733cc4dc98b
Waiting for confirmation...
Transaction Confirmed!
LiFi Aggregator/Bridging Transaction Sent! Hash: 0x7dc6cfb80b2e83970f925dbb118c27c1f1528cdbe2e96c082b8bbede4f935d70
Waiting for confirmation...
Transaction Confirmed!
✅ DONE!
View the transaction on the BuildBear Explorer or the BlockScout Explorer
Clicking on "View on Sentio" opens the debugger for:
This guide walked you through integrating the LI.FI Plugin with BuildBear Sandboxes. You learned how to fetch a swap quote, use it to populate and send a swapping transaction.
For the full tutorial and source code, check out the GitHub repository .