Created
January 25, 2024 14:40
-
-
Save stephancill/d12d1cdcf46b5d86e0c8ce7b11f73b6a to your computer and use it in GitHub Desktop.
A script which generates swap calldata using the uniswap smart order router
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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