A Complete Example
Below is a complete example using `hardhat.js for onchain interaction, and node-fetch for the pathfinder API query.
require("@nomiclabs/hardhat-ethers");
const { assert } = require("console");
const fs = require("fs")
const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));
async function main() {
const ONE_ETH = ethers.constants.WeiPerEther;
// First, we query the BrainDex Pathfinder service for a route.
// Construct pathfinder query data
const data =
{
"chain_id": 1284,
"amount_in": ONE_ETH._hex,
"token_in": "0xAcc15dC74880C9944775448304B263D191c6077F",
"token_out": "0x818ec0a7fe18ff94269904fced6ae3dae6d6dc0b",
"max_hops": 3,
"min_splits": 0,
"max_splits": 3,
"count": 5
}
// Make the route request
const response = await fetch('https://api.braindex.io/app/myAppId', {
method: 'post',
body: JSON.stringify(data),
headers: { 'Content-Type': 'application/json' }
});
// Parse our response
const res = await response.json(); // parses JSON response into native JavaScript objects
console.log(res.amount_out);
// Now that we have our route response, we can query the chain to confirm our price.
// Load the contract ABI interface
const bdexAbiFile = fs.readFileSync('./abi/brainDexRouterAbi.json', "utf-8")
const bdexAbi = JSON.parse(bdexAbiFile);
// Get onchain signer
const [signer] = await ethers.getSigners();
// Initialize the router contract
const BrainDexRouter = "0xe2eA8cb03481B83402e6159cf95A63A934255C6b";
const router = new ethers.Contract(BrainDexRouter, bdexAbi, signer);
const amtOutQuote = ethers.BigNumber.from(res.amount_out);
// Confirm our price quote by passing the swap_paths
// field of the pathfinder response to the contract.
const priceConfirm = await router.getMultiSwapAmountOut(res.swap_paths);
// Note that there may be some small differences due to price movements
// between query and confirmation times.
assert(amtOutQuote.eq(priceConfirm), "Price mismatch!");
// We have found that the gas estimate can be underneath of what is expected,
// so we buffer by 1.2x
const gasEstimate = await router.estimateGas.multiSwapTokensForTokens(
data.token_in,
data.token_out,
signer.address,
ONE_ETH,
ethers.BigNumber.from(1), // Must be at least 1.
ethers.BigNumber.from(1775120065),
res.swap_paths,
)
const bufferedGasEstimate = gasEstimate.mul(12).div(10);
// Perform a swap. Note that this requires that the signer have approved
// the contract beforehand.
const tx = await router.multiSwapTokensForTokens(
data.token_in,
data.token_out,
signer.address,
ONE_ETH,
ethers.BigNumber.from(1), // In production, this value should be propagated by user slippage settings. Must be at least 1.
ethers.BigNumber.from(1775120065),
res.swap_paths,
{
gasLimit: bufferedGasEstimate,
}
)
console.log(tx.hash);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Last updated