From caa9a40f1e17722e2ede948dd305a3990f40c0be Mon Sep 17 00:00:00 2001 From: Karl Kempe Date: Thu, 27 Jan 2022 17:35:52 +0000 Subject: [PATCH] Add misc scripts --- misc/.gitignore | 5 + misc/package.json | 40 ++++ misc/scripts/check-ust-quotes.ts | 394 +++++++++++++++++++++++++++++++ misc/scripts/src/custom.d.ts | 4 + misc/scripts/src/provider.ts | 21 ++ misc/scripts/swap-with-vaa.ts | 390 ++++++++++++++++++++++++++++++ misc/tsconfig.json | 13 + 7 files changed, 867 insertions(+) create mode 100644 misc/.gitignore create mode 100644 misc/package.json create mode 100644 misc/scripts/check-ust-quotes.ts create mode 100644 misc/scripts/src/custom.d.ts create mode 100644 misc/scripts/src/provider.ts create mode 100644 misc/scripts/swap-with-vaa.ts create mode 100644 misc/tsconfig.json diff --git a/misc/.gitignore b/misc/.gitignore new file mode 100644 index 0000000..72b3ff2 --- /dev/null +++ b/misc/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +scripts/*.js +scripts/src/*.js +./src +package-lock.json diff --git a/misc/package.json b/misc/package.json new file mode 100644 index 0000000..26bb5f5 --- /dev/null +++ b/misc/package.json @@ -0,0 +1,40 @@ +{ + "homepage": "https://certusone.github.io/wormhole-nativeswap-example", + "name": "NativeSwap", + "version": "0.1.0", + "private": true, + "scripts": { + "build": "tsc" + }, + "dependencies": { + "@certusone/wormhole-sdk": "^0.1.6", + "@improbable-eng/grpc-web-node-http-transport": "^0.15.0", + "@material-ui/core": "^4.12.2", + "@material-ui/icons": "^4.11.2", + "@material-ui/lab": "^4.0.0-alpha.60", + "@metamask/detect-provider": "^1.2.0", + "@terra-money/terra.js": "^2.0.14", + "@terra-money/wallet-provider": "^2.2.0", + "@types/node": "^16.11.19", + "@types/react": "^17.0.38", + "@types/react-dom": "^17.0.11", + "@uniswap/smart-order-router": "^2.1.1", + "@uniswap/v2-core": "^1.0.1", + "@uniswap/v2-sdk": "^3.0.1", + "@uniswap/v3-periphery": "1.3", + "@uniswap/v3-sdk": "^3.8.1", + "ethers": "^5.5.3", + "jsbi": "^3.2.5", + "notistack": "^1.0.10", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-scripts": "4.0.3", + "typescript": "^4.4.2", + "use-debounce": "^7.0.1" + }, + "devDependencies": { + "@craco/craco": "^6.3.0", + "gh-pages": "^3.2.3", + "wasm-loader": "^1.3.0" + } +} diff --git a/misc/scripts/check-ust-quotes.ts b/misc/scripts/check-ust-quotes.ts new file mode 100644 index 0000000..0a9b2fc --- /dev/null +++ b/misc/scripts/check-ust-quotes.ts @@ -0,0 +1,394 @@ +import { ethers } from "ethers"; + +import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport"; + +import { + ExactInCrossParameters, + ExactOutCrossParameters, + UniswapToUniswapQuoter, +} from "../src/route/cross-quote"; + +import { UniswapToUniswapExecutor } from "../src/swapper/swapper"; + +import { makeProvider } from "./src/provider"; +import { + ETH_TOKEN_INFO, + MATIC_TOKEN_INFO, + UST_TOKEN_INFO, +} from "../src/utils/consts"; + +require("dotenv").config({ path: ".env" }); + +// swap related parameters (configurable in UI) +const SWAP_AMOUNT_IN_WMATIC = "0.0069"; +const SWAP_AMOUNT_IN_WETH = "0.000907"; +const SWAP_AMOUNT_IN_UST = "3.40"; + +const SWAP_DEADLINE = "1800"; +const SWAP_SLIPPAGE = "0.01"; + +// token bridge things +const BRIDGE_RELAYER_FEE_UST = "0.25"; + +export function makeEvmWallet( + provider: ethers.providers.Provider +): ethers.Wallet { + return new ethers.Wallet(process.env.ETH_PRIVATE_KEY, provider); +} + +/* +async function fetchTokenBalance(signer, contract) { + const decimals = await contract.decimals(); + const balanceBeforeDecimals = (await contract.balanceOf(signer.address)).toString(); + const balance = ethers.utils.formatUnits(balanceBeforeDecimals, decimals); + return balance; +} +*/ + +// only exist as placeholder for actual wallet connection +function determineWalletFromToken(tokenAddress: string): ethers.Wallet { + if (tokenAddress === UST_TOKEN_INFO.address) { + return undefined; + } + return makeEvmWallet(makeProvider(tokenAddress)); +} + +function determineAmountFromToken(tokenAddress: string): string { + switch (tokenAddress) { + case ETH_TOKEN_INFO.address: { + return SWAP_AMOUNT_IN_WETH; + } + case MATIC_TOKEN_INFO.address: { + return SWAP_AMOUNT_IN_WMATIC; + } + case UST_TOKEN_INFO.address: { + return SWAP_AMOUNT_IN_UST; + } + default: { + throw Error("you suck"); + } + } +} + +function logExactInParameters( + quoter: UniswapToUniswapQuoter, + params: ExactInCrossParameters +): void { + console.info(`amountIn: ${params.amountIn}`); + console.info(`minAmountOut: ${params.minAmountOut}`); + + const src = params.src; + if (src === undefined) { + console.warn(` src is undefined (ust?)`); + } else { + console.info(`src`); + console.info(` protocol: ${src.protocol}`); + //console.info(` amountIn: ${quoter.srcTokenIn.formatAmount(src.amountIn)}`); + console.info( + ` amountIn: ${quoter.srcRouter.formatAmountIn( + src.amountIn.toString() + )}` + ); + console.info( + // ` minAmountOut: ${quoter.srcTokenOut.formatAmount(src.minAmountOut)}` + ` minAmountOut: ${quoter.srcRouter.formatAmountOut( + src.minAmountOut.toString() + )}` + ); + console.info(` poolFee: ${src.poolFee}`); + console.info(` deadline: ${src.deadline.toString()}`); + console.info(` path: ${src.path}`); + } + + const dst = params.dst; + if (dst === undefined) { + console.warn(` dst is undefined (ust?)`); + } else { + console.info(`dst`); + console.info(` protocol: ${dst.protocol}`); + //console.info(` amountIn: ${quoter.dstTokenIn.formatAmount(dst.amountIn)}`); + console.info( + ` amountIn: ${quoter.dstRouter.formatAmountIn( + dst.amountIn.toString() + )}` + ); + console.info( + // ` minAmountOut: ${quoter.dstTokenOut.formatAmount(dst.minAmountOut)}` + ` minAmountOut: ${quoter.dstRouter.formatAmountOut( + dst.minAmountOut.toString() + )}` + ); + console.info(` poolFee: ${dst.poolFee}`); + console.info(` deadline: ${dst.deadline.toString()}`); + console.info(` path: ${dst.path}`); + + const relayerFee = params.relayerFee; + console.info(`relayerFee`); + console.info(` tokenAddress: ${relayerFee.tokenAddress}`); + console.info( + ` amount: ${quoter.dstRouter.formatAmountIn(relayerFee.amount)}` + ); + } + + return; +} + +async function swapEverythingExactIn( + swapper: UniswapToUniswapExecutor, + tokenInAddress: string, + tokenOutAddress: string, + isNative: boolean, + amountIn: string +): Promise { + // connect src wallet + //const srcWallet = determineWalletFromToken(tokenInAddress); + //console.info(`wallet pubkey: ${await srcWallet.getAddress()}`); + + // tokens selected, let's initialize + await swapper.initialize(tokenInAddress, tokenOutAddress, isNative); + console.info(`quoter initialized`); + + /* + const tokens = swapper.getTokens(); + + // display tokens on front-end? + console.info( + `srcTokenIn: ${tokens.srcIn.getAddress()} (${tokens.srcIn.getDecimals()})` + ); + console.info( + `srcTokenOut: ${tokens.srcOut.getAddress()} (${tokens.srcOut.getDecimals()})` + ); + console.info( + `dstTokenIn: ${tokens.dstIn.getAddress()} (${tokens.dstIn.getDecimals()})` + ); + console.info( + `dstTokenOut: ${tokens.dstOut.getAddress()} (${tokens.dstOut.getDecimals()})` + ); + */ + + // verify pool address on src and dst + await swapper + .computeAndVerifySrcPoolAddress() + .then((address) => { + console.info(`srcPool: ${address}`); + return address; + }) + .catch((response) => { + console.error( + `failed to find a pool address for src. how to handle in the front-end?` + ); + process.exit(1); + }); + + await swapper + .computeAndVerifyDstPoolAddress() + .then((address) => { + console.info(`dstPool: ${address}`); + return address; + }) + .catch((response) => { + console.error( + `failed to find a pool address for dst. how to handle in the front-end?` + ); + process.exit(1); + }); + + // set deadline + swapper.setDeadlines(SWAP_DEADLINE); + swapper.setSlippage(SWAP_SLIPPAGE); + swapper.setRelayerFee(BRIDGE_RELAYER_FEE_UST); + + const exactInParameters: ExactInCrossParameters = + await swapper.computeQuoteExactIn(amountIn); + + console.info("exactInParameters"); + logExactInParameters(swapper.quoter, exactInParameters); + + return; +} + +function logExactOutParameters( + quoter: UniswapToUniswapQuoter, + params: ExactOutCrossParameters +): void { + console.info(`amountIn: ${params.amountOut}`); + console.info(`minAmountOut: ${params.maxAmountIn}`); + + const src = params.src; + console.info(`src`); + if (src === undefined) { + } else { + } + console.info(` protocol: ${src.protocol}`); + console.info( + ` amountOut: ${quoter.srcRouter.formatAmountOut( + src.amountOut.toString() + )}` + ); + console.info( + ` maxAmountIn: ${quoter.srcRouter.formatAmountIn( + src.maxAmountIn.toString() + )}` + ); + console.info(` poolFee: ${src.poolFee}`); + console.info(` deadline: ${src.deadline.toString()}`); + console.info(` path: ${src.path}`); + + const dst = params.dst; + console.info(`dst`); + console.info(` protocol: ${dst.protocol}`); + console.info( + ` amountOut: ${quoter.dstRouter.formatAmountOut( + dst.amountOut.toString() + )}` + ); + console.info( + ` maxAmountIn: ${quoter.dstRouter.formatAmountIn( + dst.maxAmountIn.toString() + )}` + ); + console.info(` poolFee: ${dst.poolFee}`); + console.info(` deadline: ${dst.deadline.toString()}`); + console.info(` path: ${dst.path}`); + + const relayerFee = params.relayerFee; + console.info(`relayerFee`); + console.info(` tokenAddress: ${relayerFee.tokenAddress}`); + console.info( + ` amount: ${quoter.dstRouter.formatAmountIn( + relayerFee.amount.toString() + )}` + ); + return; +} + +async function swapEverythingExactOut( + swapper: UniswapToUniswapExecutor, + tokenInAddress: string, + tokenOutAddress: string, + isNative: boolean, + amountOut: string +): Promise { + // connect src wallet + //const srcWallet = determineWalletFromToken(tokenInAddress); + //console.info(`wallet pubkey: ${await srcWallet.getAddress()}`); + + // tokens selected, let's initialize + await swapper.initialize(tokenInAddress, tokenOutAddress, isNative); + console.info(`quoter initialized`); + + /* + const tokens = swapper.getTokens(); + + // display tokens on front-end? + console.info( + `srcTokenIn: ${tokens.srcIn.getAddress()} (${tokens.srcIn.getDecimals()})` + ); + console.info( + `srcTokenOut: ${tokens.srcOut.getAddress()} (${tokens.srcOut.getDecimals()})` + ); + console.info( + `dstTokenIn: ${tokens.dstIn.getAddress()} (${tokens.dstIn.getDecimals()})` + ); + console.info( + `dstTokenOut: ${tokens.dstOut.getAddress()} (${tokens.dstOut.getDecimals()})` + ); + */ + + // verify pool address on src and dst + await swapper + .computeAndVerifySrcPoolAddress() + .then((address) => { + console.info(`srcPool: ${address}`); + return address; + }) + .catch((response) => { + console.error( + `failed to find a pool address for src. how to handle in the front-end?` + ); + process.exit(1); + }); + + await swapper + .computeAndVerifyDstPoolAddress() + .then((address) => { + console.info(`dstPool: ${address}`); + return address; + }) + .catch((response) => { + console.error( + `failed to find a pool address for dst. how to handle in the front-end?` + ); + process.exit(1); + }); + + // set deadline + swapper.setDeadlines(SWAP_DEADLINE); + swapper.setSlippage(SWAP_SLIPPAGE); + swapper.setRelayerFee(BRIDGE_RELAYER_FEE_UST); + + const exactOutParameters: ExactOutCrossParameters = + await swapper.computeQuoteExactOut(amountOut); + + console.info("exactOutParameters"); + logExactOutParameters(swapper.quoter, exactOutParameters); + + return; +} + +async function main() { + const testExactIn = true; + const isNative = true; + + const swapper = new UniswapToUniswapExecutor(); + swapper.setTransport(NodeHttpTransport()); + + //const tokenInAddress = MATIC_TOKEN_INFO.address; + const tokenInAddress = UST_TOKEN_INFO.address; + const tokenOutAddress = ETH_TOKEN_INFO.address; + + if (testExactIn) { + console.info(`testing exact in. native=${isNative}`); + + console.info("wmatic -> weth"); + await swapEverythingExactIn( + swapper, + tokenInAddress, + tokenOutAddress, + isNative, + determineAmountFromToken(tokenInAddress) + ); + + console.info("weth -> wmatic"); + await swapEverythingExactIn( + swapper, + tokenOutAddress, + tokenInAddress, + isNative, + determineAmountFromToken(tokenOutAddress) + ); + } else { + console.info(`testing exact out. native=${isNative}`); + + console.info("wmatic -> weth"); + await swapEverythingExactOut( + swapper, + tokenInAddress, + tokenOutAddress, + isNative, + determineAmountFromToken(tokenOutAddress) + ); + + console.info("weth -> wmatic"); + await swapEverythingExactOut( + swapper, + tokenOutAddress, + tokenInAddress, + isNative, + determineAmountFromToken(tokenInAddress) + ); + } + + return; +} +main(); diff --git a/misc/scripts/src/custom.d.ts b/misc/scripts/src/custom.d.ts new file mode 100644 index 0000000..1a3dd3c --- /dev/null +++ b/misc/scripts/src/custom.d.ts @@ -0,0 +1,4 @@ +declare module "*.svg" { + const content: any; + export default content; +} diff --git a/misc/scripts/src/provider.ts b/misc/scripts/src/provider.ts new file mode 100644 index 0000000..65937fc --- /dev/null +++ b/misc/scripts/src/provider.ts @@ -0,0 +1,21 @@ +import { ethers } from "ethers"; + +import { ETH_TOKEN_INFO, MATIC_TOKEN_INFO } from "../../src/utils/consts"; + +export function makeProvider(tokenAddress: string) { + switch (tokenAddress) { + case ETH_TOKEN_INFO.address: { + return new ethers.providers.StaticJsonRpcProvider( + process.env.GOERLI_PROVIDER + ); + } + case MATIC_TOKEN_INFO.address: { + return new ethers.providers.StaticJsonRpcProvider( + process.env.MUMBAI_PROVIDER + ); + } + default: { + throw Error("unrecognized token address"); + } + } +} diff --git a/misc/scripts/swap-with-vaa.ts b/misc/scripts/swap-with-vaa.ts new file mode 100644 index 0000000..31f6065 --- /dev/null +++ b/misc/scripts/swap-with-vaa.ts @@ -0,0 +1,390 @@ +import { ethers } from "ethers"; + +import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport"; + +import { + ExactInCrossParameters, + ExactOutCrossParameters, + UniswapToUniswapQuoter, +} from "../src/route/cross-quote"; + +import { UniswapToUniswapExecutor } from "../src/swapper/swapper"; + +import { makeProvider } from "./src/provider"; + +require("dotenv").config({ path: ".env" }); + +// quote using these +const POLYGON_TOKEN_WMATIC = "0x9c3c9283d3e44854697cd22d3faa240cfb032889"; +const ETHEREUM_TOKEN_WETH = "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6"; + +// swap related parameters (configurable in UI) +const SWAP_AMOUNT_IN_WMATIC = "0.0069"; +const SWAP_AMOUNT_IN_WETH = "0.000123"; +const SWAP_DEADLINE = "1800"; +const SWAP_SLIPPAGE = "0.01"; + +// token bridge things +const BRIDGE_RELAYER_FEE_UST = "0.25"; + +export function makeEvmWallet( + provider: ethers.providers.Provider +): ethers.Wallet { + return new ethers.Wallet(process.env.ETH_PRIVATE_KEY, provider); +} + +/* +async function fetchTokenBalance(signer, contract) { + const decimals = await contract.decimals(); + const balanceBeforeDecimals = (await contract.balanceOf(signer.address)).toString(); + const balance = ethers.utils.formatUnits(balanceBeforeDecimals, decimals); + return balance; +} +*/ + +// only exist as placeholder for actual wallet connection +function determineWalletFromToken(tokenAddress: string): ethers.Wallet { + return makeEvmWallet(makeProvider(tokenAddress)); +} + +function determineAmountFromToken(tokenAddress: string): string { + if (tokenAddress === ETHEREUM_TOKEN_WETH) { + return SWAP_AMOUNT_IN_WETH; + } else if (tokenAddress === POLYGON_TOKEN_WMATIC) { + return SWAP_AMOUNT_IN_WMATIC; + } else { + throw Error("you suck"); + } +} + +function logExactInParameters( + quoter: UniswapToUniswapQuoter, + params: ExactInCrossParameters +): void { + const src = params.src; + console.info(`src`); + console.info(` protocol: ${src.protocol}`); + //console.info(` amountIn: ${quoter.srcTokenIn.formatAmount(src.amountIn)}`); + console.info( + ` amountIn: ${quoter.srcRouter.formatAmountIn( + src.amountIn.toString() + )}` + ); + console.info( + // ` minAmountOut: ${quoter.srcTokenOut.formatAmount(src.minAmountOut)}` + ` minAmountOut: ${quoter.srcRouter.formatAmountOut( + src.minAmountOut.toString() + )}` + ); + console.info(` poolFee: ${src.poolFee}`); + console.info(` deadline: ${src.deadline.toString()}`); + console.info(` path: ${src.path}`); + + const dst = params.dst; + console.info(`dst`); + console.info(` protocol: ${dst.protocol}`); + //console.info(` amountIn: ${quoter.dstTokenIn.formatAmount(dst.amountIn)}`); + console.info( + ` amountIn: ${quoter.dstRouter.formatAmountIn( + dst.amountIn.toString() + )}` + ); + console.info( + // ` minAmountOut: ${quoter.dstTokenOut.formatAmount(dst.minAmountOut)}` + ` minAmountOut: ${quoter.dstRouter.formatAmountOut( + dst.minAmountOut.toString() + )}` + ); + console.info(` poolFee: ${dst.poolFee}`); + console.info(` deadline: ${dst.deadline.toString()}`); + console.info(` path: ${dst.path}`); + + const relayerFee = params.relayerFee; + console.info(`relayerFee`); + console.info(` tokenAddress: ${relayerFee.tokenAddress}`); + console.info( + ` amount: ${quoter.dstRouter.formatAmountIn(relayerFee.amount)}` + ); + return; +} + +async function swapEverythingExactIn( + swapper: UniswapToUniswapExecutor, + tokenInAddress: string, + tokenOutAddress: string, + isNative: boolean, + amountIn: string +): Promise { + // connect src wallet + const srcWallet = determineWalletFromToken(tokenInAddress); + console.info(`wallet pubkey: ${await srcWallet.getAddress()}`); + + // tokens selected, let's initialize + await swapper.initialize(tokenInAddress, tokenOutAddress, isNative); + console.info(`quoter initialized`); + + /* + const tokens = swapper.getTokens(); + + // display tokens on front-end? + console.info( + `srcTokenIn: ${tokens.srcIn.getAddress()} (${tokens.srcIn.getDecimals()})` + ); + console.info( + `srcTokenOut: ${tokens.srcOut.getAddress()} (${tokens.srcOut.getDecimals()})` + ); + console.info( + `dstTokenIn: ${tokens.dstIn.getAddress()} (${tokens.dstIn.getDecimals()})` + ); + console.info( + `dstTokenOut: ${tokens.dstOut.getAddress()} (${tokens.dstOut.getDecimals()})` + ); + */ + + // verify pool address on src and dst + await swapper + .computeAndVerifySrcPoolAddress() + .then((address) => { + console.info(`srcPool: ${address}`); + return address; + }) + .catch((response) => { + console.error( + `failed to find a pool address for src. how to handle in the front-end?` + ); + process.exit(1); + }); + + await swapper + .computeAndVerifyDstPoolAddress() + .then((address) => { + console.info(`dstPool: ${address}`); + return address; + }) + .catch((response) => { + console.error( + `failed to find a pool address for dst. how to handle in the front-end?` + ); + process.exit(1); + }); + + // set deadline + swapper.setDeadlines(SWAP_DEADLINE); + swapper.setSlippage(SWAP_SLIPPAGE); + swapper.setRelayerFee(BRIDGE_RELAYER_FEE_UST); + + const exactInParameters: ExactInCrossParameters = + await swapper.computeQuoteExactIn(amountIn); + + console.info("exactInParameters"); + logExactInParameters(swapper.quoter, exactInParameters); + + // do the src swap + console.info("approveAndSwap"); + const srcSwapReceipt = await swapper.evmApproveAndSwap(srcWallet); + console.info(`src transaction: ${srcSwapReceipt.transactionHash}`); + + // do the dst swap after fetching vaa + // connect dst wallet + const dstWallet = determineWalletFromToken(tokenOutAddress); + + console.info("fetchVaaAndSwap"); + //const dstSwapReceipt = await swapper.fetchVaaAndSwap(dstWallet); + //console.info(`dst transaction: ${dstSwapReceipt.transactionHash}`); + console.warn("jk"); + + return; +} + +function logExactOutParameters( + quoter: UniswapToUniswapQuoter, + params: ExactOutCrossParameters +): void { + const src = params.src; + console.info(`src`); + console.info(` protocol: ${src.protocol}`); + console.info( + ` amountOut: ${quoter.srcRouter.formatAmountOut( + src.amountOut.toString() + )}` + ); + console.info( + ` maxAmountIn: ${quoter.srcRouter.formatAmountIn( + src.maxAmountIn.toString() + )}` + ); + console.info(` poolFee: ${src.poolFee}`); + console.info(` deadline: ${src.deadline.toString()}`); + console.info(` path: ${src.path}`); + + const dst = params.dst; + console.info(`dst`); + console.info(` protocol: ${dst.protocol}`); + console.info( + ` amountOut: ${quoter.dstRouter.formatAmountOut( + dst.amountOut.toString() + )}` + ); + console.info( + ` maxAmountIn: ${quoter.dstRouter.formatAmountIn( + dst.maxAmountIn.toString() + )}` + ); + console.info(` poolFee: ${dst.poolFee}`); + console.info(` deadline: ${dst.deadline.toString()}`); + console.info(` path: ${dst.path}`); + + const relayerFee = params.relayerFee; + console.info(`relayerFee`); + console.info(` tokenAddress: ${relayerFee.tokenAddress}`); + console.info( + ` amount: ${quoter.dstRouter.formatAmountIn( + relayerFee.amount.toString() + )}` + ); + return; +} + +async function swapEverythingExactOut( + swapper: UniswapToUniswapExecutor, + tokenInAddress: string, + tokenOutAddress: string, + isNative: boolean, + amountOut: string +): Promise { + // connect src wallet + const srcWallet = determineWalletFromToken(tokenInAddress); + console.info(`wallet pubkey: ${await srcWallet.getAddress()}`); + + // tokens selected, let's initialize + await swapper.initialize(tokenInAddress, tokenOutAddress, isNative); + console.info(`quoter initialized`); + + /* + const tokens = swapper.getTokens(); + + // display tokens on front-end? + console.info( + `srcTokenIn: ${tokens.srcIn.getAddress()} (${tokens.srcIn.getDecimals()})` + ); + console.info( + `srcTokenOut: ${tokens.srcOut.getAddress()} (${tokens.srcOut.getDecimals()})` + ); + console.info( + `dstTokenIn: ${tokens.dstIn.getAddress()} (${tokens.dstIn.getDecimals()})` + ); + console.info( + `dstTokenOut: ${tokens.dstOut.getAddress()} (${tokens.dstOut.getDecimals()})` + ); + */ + + // verify pool address on src and dst + await swapper + .computeAndVerifySrcPoolAddress() + .then((address) => { + console.info(`srcPool: ${address}`); + return address; + }) + .catch((response) => { + console.error( + `failed to find a pool address for src. how to handle in the front-end?` + ); + process.exit(1); + }); + + await swapper + .computeAndVerifyDstPoolAddress() + .then((address) => { + console.info(`dstPool: ${address}`); + return address; + }) + .catch((response) => { + console.error( + `failed to find a pool address for dst. how to handle in the front-end?` + ); + process.exit(1); + }); + + // set deadline + swapper.setDeadlines(SWAP_DEADLINE); + swapper.setSlippage(SWAP_SLIPPAGE); + swapper.setRelayerFee(BRIDGE_RELAYER_FEE_UST); + + const exactOutParameters: ExactOutCrossParameters = + await swapper.computeQuoteExactOut(amountOut); + + console.info("exactOutParameters"); + logExactOutParameters(swapper.quoter, exactOutParameters); + + // do the src swap + console.info("approveAndSwap"); + const srcSwapReceipt = await swapper.evmApproveAndSwap(srcWallet); + console.info(`src transaction: ${srcSwapReceipt.transactionHash}`); + + // do the dst swap after fetching vaa + // connect dst wallet + const dstWallet = determineWalletFromToken(tokenOutAddress); + + console.info("fetchVaaAndSwap"); + //const dstSwapReceipt = await swapper.fetchVaaAndSwap(dstWallet); + //console.info(`dst transaction: ${dstSwapReceipt.transactionHash}`); + console.warn("jk"); + + return; +} + +async function main() { + const testExactIn = true; + const isNative = true; + + const swapper = new UniswapToUniswapExecutor(); + swapper.setTransport(NodeHttpTransport()); + + const tokenInAddress = POLYGON_TOKEN_WMATIC; + const tokenOutAddress = ETHEREUM_TOKEN_WETH; + + if (testExactIn) { + console.info(`testing exact in. native=${isNative}`); + + console.info("wmatic -> weth"); + await swapEverythingExactIn( + swapper, + tokenInAddress, + tokenOutAddress, + isNative, + determineAmountFromToken(tokenInAddress) + ); + + console.info("weth -> wmatic"); + await swapEverythingExactIn( + swapper, + tokenOutAddress, + tokenInAddress, + isNative, + determineAmountFromToken(tokenOutAddress) + ); + } else { + console.info(`testing exact out. native=${isNative}`); + + console.info("wmatic -> weth"); + await swapEverythingExactOut( + swapper, + tokenInAddress, + tokenOutAddress, + isNative, + determineAmountFromToken(tokenOutAddress) + ); + + console.info("weth -> wmatic"); + await swapEverythingExactOut( + swapper, + tokenOutAddress, + tokenInAddress, + isNative, + determineAmountFromToken(tokenInAddress) + ); + } + + return; +} +main(); diff --git a/misc/tsconfig.json b/misc/tsconfig.json new file mode 100644 index 0000000..fc2e218 --- /dev/null +++ b/misc/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "resolveJsonModule": true, + "esModuleInterop": true + }, + "include": [ + "scripts/src/custom.d.ts" + ], + "files": [ + "scripts/swap-with-vaa.ts", + "scripts/check-ust-quotes.ts" + ] +}