β¨Create & execute a swap using Stellaswap pools to obtain xcTokens
How to add a post-hook leveraging xcTokens liquidity pools available on Moonbeam parachain to a route request after a cross-chain swap from an EVM chain using Squid SDK
Uniswap V2 Pool ABI
const stellaSwapABI = [
{
inputs: [],
name: "WETH",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "pure",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "tokenA", type: "address" },
{ internalType: "address", name: "tokenB", type: "address" },
{ internalType: "uint256", name: "amountADesired", type: "uint256" },
{ internalType: "uint256", name: "amountBDesired", type: "uint256" },
{ internalType: "uint256", name: "amountAMin", type: "uint256" },
{ internalType: "uint256", name: "amountBMin", type: "uint256" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "addLiquidity",
outputs: [
{ internalType: "uint256", name: "amountA", type: "uint256" },
{ internalType: "uint256", name: "amountB", type: "uint256" },
{ internalType: "uint256", name: "liquidity", type: "uint256" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "amountTokenDesired", type: "uint256" },
{ internalType: "uint256", name: "amountTokenMin", type: "uint256" },
{ internalType: "uint256", name: "amountETHMin", type: "uint256" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "addLiquidityETH",
outputs: [
{ internalType: "uint256", name: "amountToken", type: "uint256" },
{ internalType: "uint256", name: "amountETH", type: "uint256" },
{ internalType: "uint256", name: "liquidity", type: "uint256" },
],
stateMutability: "payable",
type: "function",
},
{
inputs: [],
name: "factory",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "pure",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountOut", type: "uint256" },
{ internalType: "uint256", name: "reserveIn", type: "uint256" },
{ internalType: "uint256", name: "reserveOut", type: "uint256" },
],
name: "getAmountIn",
outputs: [{ internalType: "uint256", name: "amountIn", type: "uint256" }],
stateMutability: "pure",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{ internalType: "uint256", name: "reserveIn", type: "uint256" },
{ internalType: "uint256", name: "reserveOut", type: "uint256" },
],
name: "getAmountOut",
outputs: [{ internalType: "uint256", name: "amountOut", type: "uint256" }],
stateMutability: "pure",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountOut", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
],
name: "getAmountsIn",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
],
name: "getAmountsOut",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountA", type: "uint256" },
{ internalType: "uint256", name: "reserveA", type: "uint256" },
{ internalType: "uint256", name: "reserveB", type: "uint256" },
],
name: "quote",
outputs: [{ internalType: "uint256", name: "amountB", type: "uint256" }],
stateMutability: "pure",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "tokenA", type: "address" },
{ internalType: "address", name: "tokenB", type: "address" },
{ internalType: "uint256", name: "liquidity", type: "uint256" },
{ internalType: "uint256", name: "amountAMin", type: "uint256" },
{ internalType: "uint256", name: "amountBMin", type: "uint256" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "removeLiquidity",
outputs: [
{ internalType: "uint256", name: "amountA", type: "uint256" },
{ internalType: "uint256", name: "amountB", type: "uint256" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "liquidity", type: "uint256" },
{ internalType: "uint256", name: "amountTokenMin", type: "uint256" },
{ internalType: "uint256", name: "amountETHMin", type: "uint256" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "removeLiquidityETH",
outputs: [
{ internalType: "uint256", name: "amountToken", type: "uint256" },
{ internalType: "uint256", name: "amountETH", type: "uint256" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "liquidity", type: "uint256" },
{ internalType: "uint256", name: "amountTokenMin", type: "uint256" },
{ internalType: "uint256", name: "amountETHMin", type: "uint256" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
{ internalType: "bool", name: "approveMax", type: "bool" },
{ internalType: "uint8", name: "v", type: "uint8" },
{ internalType: "bytes32", name: "r", type: "bytes32" },
{ internalType: "bytes32", name: "s", type: "bytes32" },
],
name: "removeLiquidityETHWithPermit",
outputs: [
{ internalType: "uint256", name: "amountToken", type: "uint256" },
{ internalType: "uint256", name: "amountETH", type: "uint256" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "address", name: "tokenA", type: "address" },
{ internalType: "address", name: "tokenB", type: "address" },
{ internalType: "uint256", name: "liquidity", type: "uint256" },
{ internalType: "uint256", name: "amountAMin", type: "uint256" },
{ internalType: "uint256", name: "amountBMin", type: "uint256" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
{ internalType: "bool", name: "approveMax", type: "bool" },
{ internalType: "uint8", name: "v", type: "uint8" },
{ internalType: "bytes32", name: "r", type: "bytes32" },
{ internalType: "bytes32", name: "s", type: "bytes32" },
],
name: "removeLiquidityWithPermit",
outputs: [
{ internalType: "uint256", name: "amountA", type: "uint256" },
{ internalType: "uint256", name: "amountB", type: "uint256" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountOut", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "swapETHForExactTokens",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountOutMin", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "swapExactETHForTokens",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "payable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{ internalType: "uint256", name: "amountOutMin", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "swapExactTokensForETH",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{ internalType: "uint256", name: "amountOutMin", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "swapExactTokensForTokens",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountOut", type: "uint256" },
{ internalType: "uint256", name: "amountInMax", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "swapTokensForExactETH",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{ internalType: "uint256", name: "amountOut", type: "uint256" },
{ internalType: "uint256", name: "amountInMax", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "uint256", name: "deadline", type: "uint256" },
],
name: "swapTokensForExactTokens",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "nonpayable",
type: "function",
},
];
const stellaInterface = new ethers.utils.Interface(stellaSwapABI);
const swapEncodedData = stellaInterface.encodeFunctionData(
"swapExactETHForTokens",
[
ethers.BigNumber.from("0"), // not usable in production
[
tokenInputAddress,
tokenOutputAddress,
],
squidAddress,
deadline,
]
);
We are here encoding a valid Uniswap V2 pool swap data to be included in the post-hook on Moonbeam chain.
Last updated