Build single-hop calldata
Once you have the quote, build calldata ready for on-chain execution.
Endpoint:
POST /public/emigroswap/buildTransaction
Use this when your quote has multihop: null and a 2-token path.
Endpoint
POST /public/emigroswap/buildTransaction
Request
Required:
fromTokenAddress,toTokenAddress,chainId,userWallet,amountOut(from quote),minAmountIn(from quote),routerType(from quote)Optional (router-specific):
feeTierfor Uniswap V3-style routes.
Sample request (single-hop, Uniswap V3-style)
{
"fromTokenAddress": "0x833589fCD6EdB6E08F4c7C32D4f71B54bDa02913",
"toTokenAddress": "0x0b3e328455c4059EEb9e3f84b5543F74E24e7E1b",
"chainId": 8453,
"userWallet": "0x000000000000000000000000000000000000dEaD",
"amountOut": "100000000",
"minAmountIn": "64813995948785878300",
"routerType": "uniswapv3",
"feeTier": 500
}import axios from "axios";
import { ethers } from "ethers";
// ---- Config ----
const API_KEY = "esk_live.***";
const BASE_URL = "https://api.emigro.co";
const CHAIN_ID = 8453;
const USER_WALLET = "0x000000000000000000000000000000000000dEaD"; // recipient
type Quote = {
fromTokenAddress: string;
toTokenAddress: string;
chainId: number;
amountOut: string; // RAW input (from quote)
minAmountIn: string; // RAW min out (from quote)
routerType: string; // e.g. "uniswapv3" or "aerodrome-slipstream"
feeTier?: number; // may be present for v3
multihop: null; // single-hop
path: [string, string];
};
type BuildTx = {
success: boolean;
chainId: number;
routerAddress: string;
abiFunctionSignature: string;
abiParameters: any[];
routerType: string;
adapterAddress: string;
adapterData: string;
};
// 1) Get a single-hop quote
async function getSingleHopQuote() {
const { data } = await axios.post<Quote>(
`${BASE_URL}/public/emigroswap/quote`,
{
fromTokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC
toTokenAddress: "0xE9185Ee218cae427aF7B9764A011bb89FeA761B4", // BRZ
amount: "100.00", // HUMAN
chainId: CHAIN_ID,
slippage: 0.5,
},
{ headers: { "x-api-key": API_KEY, "Content-Type": "application/json" } }
);
if (Array.isArray((data as any).multihop)) {
throw new Error("Expected single-hop; quote returned multihop.");
}
return data;
}
// 2) Build calldata (single-hop)
async function buildSingleHopCalldata(q: Quote) {
const body: any = {
fromTokenAddress: q.fromTokenAddress,
toTokenAddress: q.toTokenAddress,
chainId: q.chainId,
userWallet: USER_WALLET,
amountOut: q.amountOut,
minAmountIn: q.minAmountIn,
routerType: q.routerType,
};
if (q.routerType.toLowerCase().includes("uniswapv3") && typeof q.feeTier === "number") {
body.feeTier = q.feeTier;
}
const { data } = await axios.post<BuildTx>(
`${BASE_URL}/public/emigroswap/buildTransaction`,
body,
{ headers: { "x-api-key": API_KEY, "Content-Type": "application/json" } }
);
return data;
}
// 3) (Optional) Encode & send using ethers v6
async function encodeCall(build: BuildTx) {
const iface = new ethers.Interface([`function ${build.abiFunctionSignature}`]);
const data = iface.encodeFunctionData(
build.abiFunctionSignature.split("(")[0],
build.abiParameters
);
return { to: build.routerAddress, data };
// To broadcast on your infra:
// const provider = new ethers.JsonRpcProvider(process.env.BASE_RPC_URL);
// const signer = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
// const tx = await signer.sendTransaction({ to: build.routerAddress, data });
// await tx.wait();
}
(async () => {
const quote = await getSingleHopQuote();
const build = await buildSingleHopCalldata(quote);
console.log("build:", build);
const tx = await encodeCall(build);
console.log("tx payload:", tx);
})();
Response (shape)
Send the transaction exactly with the returned routerAddress, abiFunctionSignature, and abiParameters.
Last updated

