Skip to content

Instantly share code, notes, and snippets.

@stephancill
Created January 25, 2024 14:40
Show Gist options
  • Save stephancill/d12d1cdcf46b5d86e0c8ce7b11f73b6a to your computer and use it in GitHub Desktop.
Save stephancill/d12d1cdcf46b5d86e0c8ce7b11f73b6a to your computer and use it in GitHub Desktop.
A script which generates swap calldata using the uniswap smart order router
import { Protocol } from "@uniswap/router-sdk";
import { Percent, Token, TradeType } from "@uniswap/sdk-core";
import {
AlphaRouter,
AlphaRouterConfig,
CurrencyAmount,
SwapOptions,
SwapType,
nativeOnChain,
} from "@uniswap/smart-order-router";
import { ethers } from "ethers";
import JSBI from "jsbi";
import * as chains from "viem2/chains";
import { createPublicClient, http } from "viem2";
import { publicActionReverseMirage } from "reverse-mirage";
const ethAmount = "0.05";
const recipientAddress = "0x8d25687829D6b85d9e0020B8c89e3Ca24dE20a89";
const feeRecipientAddress = "0xdcC59cF0Adf4175973D4abc8c0715f83f90d2f1d";
const feePercentage = "5";
const outTokenCaip19 =
"eip155:8453/erc20:0x4ed4e862860bed51a9570b96d89af5e1b0efefed";
// eip155:1/erc20:0xd7c1eb0fe4a30d3b2a846c04aa6300888f087a5f
// eip155:8453/erc20:0x4ed4e862860bed51a9570b96d89af5e1b0efefed
async function main() {
try {
const { chain, token: tokenOut } = await caip19UrlToToken(outTokenCaip19);
const provider = new ethers.providers.JsonRpcProvider(
chain.rpcUrls.default.http[0]
);
const router = new AlphaRouter({
chainId: chain.id,
provider,
});
const tokenIn = nativeOnChain(chain.id);
const amountIn = CurrencyAmount.fromRawAmount(
tokenIn,
JSBI.BigInt(ethers.utils.parseUnits(ethAmount, tokenIn.decimals))
);
let swapOptions: SwapOptions = {
type: SwapType.UNIVERSAL_ROUTER,
recipient: recipientAddress,
slippageTolerance: new Percent(5, 100),
deadlineOrPreviousBlockhash: parseDeadline("360"),
fee: {
fee: new Percent(parseInt(feePercentage), 100),
recipient: feeRecipientAddress,
},
};
const partialRoutingConfig: Partial<AlphaRouterConfig> = {
protocols: [Protocol.V2, Protocol.V3, Protocol.MIXED],
};
const quote = await router.route(
amountIn,
tokenOut,
TradeType.EXACT_INPUT,
swapOptions,
partialRoutingConfig
);
console.log(quote);
if (!quote) return;
return quote;
} catch (err: any) {
console.log(err);
}
}
function parseDeadline(deadline: string): number {
return Math.floor(Date.now() / 1000) + parseInt(deadline);
}
async function caip19UrlToToken(
url: string
): Promise<{ token: Token; chain: chains.Chain }> {
// e.g. eip155:1/erc20:0xd7c1eb0fe4a30d3b2a846c04aa6300888f087a5f
const [chainPart, tokenPart] = url.split("/");
const chainId = parseInt(chainPart.split(":")[1]);
const address = tokenPart.split(":")[1];
const chain = chainById[chainId];
const client = createPublicClient({
transport: http(),
chain,
}).extend(publicActionReverseMirage);
const token = await client.getERC20({
erc20: {
address: address as `0x${string}`,
chainID: chain.id,
},
});
const uniswapToken = new Token(
chainId,
address,
token.decimals,
token.symbol,
token.name
);
return { token: uniswapToken, chain };
}
const chainById: { [key: string]: chains.Chain } = Object.entries(
chains
).reduce((acc: { [key: string]: chains.Chain }, [key, chain]) => {
acc[chain.id] = chain;
return acc;
}, {});
main().finally(() => process.exit(0));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment