wormhole-nativeswap-example/misc/scripts/swap-with-vaa.ts

386 lines
11 KiB
TypeScript
Raw Permalink Normal View History

2022-01-27 09:35:52 -08:00
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";
2022-01-28 08:23:49 -08:00
import {
ETH_TOKEN_INFO,
MATIC_TOKEN_INFO,
AVAX_TOKEN_INFO,
BNB_TOKEN_INFO,
UST_TOKEN_INFO,
} from "../src/utils/consts";
2022-01-27 09:35:52 -08:00
import { makeProvider } from "./src/provider";
require("dotenv").config({ path: ".env" });
// swap related parameters (configurable in UI)
2022-01-28 08:23:49 -08:00
const SWAP_AMOUNT_IN_MATIC = "0.0069";
const SWAP_AMOUNT_IN_ETH = "0.000907";
const SWAP_AMOUNT_IN_AVAX = "0.0075";
const SWAP_AMOUNT_IN_BNB = "0.015";
const SWAP_AMOUNT_IN_UST = "3.40";
2022-01-27 09:35:52 -08:00
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 {
2022-01-28 08:23:49 -08:00
switch (tokenAddress) {
case ETH_TOKEN_INFO.address: {
return SWAP_AMOUNT_IN_ETH;
}
case MATIC_TOKEN_INFO.address: {
return SWAP_AMOUNT_IN_MATIC;
}
case AVAX_TOKEN_INFO.address: {
return SWAP_AMOUNT_IN_AVAX;
}
case BNB_TOKEN_INFO.address: {
return SWAP_AMOUNT_IN_BNB;
}
case UST_TOKEN_INFO.address: {
return SWAP_AMOUNT_IN_UST;
}
default: {
throw Error("you suck");
}
2022-01-27 09:35:52 -08:00
}
}
function logExactInParameters(
quoter: UniswapToUniswapQuoter,
params: ExactInCrossParameters
): void {
2022-01-28 08:23:49 -08:00
console.info(`amountIn: ${params.amountIn}`);
console.info(`minAmountOut: ${params.minAmountOut}`);
2022-01-27 09:35:52 -08:00
const src = params.src;
2022-01-28 08:23:49 -08:00
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}`);
}
2022-01-27 09:35:52 -08:00
const dst = params.dst;
console.info(`dst`);
2022-01-28 08:23:49 -08:00
if (dst === undefined) {
console.warn(` dst is undefined (ust?)`);
} else {
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)}`
);
}
2022-01-27 09:35:52 -08:00
return;
}
async function swapEverythingExactIn(
swapper: UniswapToUniswapExecutor,
tokenInAddress: string,
tokenOutAddress: string,
isNative: boolean,
amountIn: string
): Promise<void> {
// 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`);
// 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<void> {
// 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`);
// 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());
2022-01-28 08:23:49 -08:00
const tokenIn = ETH_TOKEN_INFO;
const tokenOut = AVAX_TOKEN_INFO;
2022-01-27 09:35:52 -08:00
if (testExactIn) {
console.info(`testing exact in. native=${isNative}`);
2022-01-28 08:23:49 -08:00
console.info(`${tokenIn.name} -> ${tokenOut.name}`);
2022-01-27 09:35:52 -08:00
await swapEverythingExactIn(
swapper,
2022-01-28 08:23:49 -08:00
tokenIn.address,
tokenOut.address,
2022-01-27 09:35:52 -08:00
isNative,
2022-01-28 08:23:49 -08:00
determineAmountFromToken(tokenIn.address)
2022-01-27 09:35:52 -08:00
);
2022-01-28 08:23:49 -08:00
console.info(`${tokenOut.name} -> ${tokenIn.name}`);
2022-01-27 09:35:52 -08:00
await swapEverythingExactIn(
swapper,
2022-01-28 08:23:49 -08:00
tokenOut.address,
tokenIn.address,
2022-01-27 09:35:52 -08:00
isNative,
2022-01-28 08:23:49 -08:00
determineAmountFromToken(tokenOut.address)
2022-01-27 09:35:52 -08:00
);
} else {
console.info(`testing exact out. native=${isNative}`);
2022-01-28 08:23:49 -08:00
console.info(`${tokenIn.name} -> ${tokenOut.name}`);
2022-01-27 09:35:52 -08:00
await swapEverythingExactOut(
swapper,
2022-01-28 08:23:49 -08:00
tokenIn.address,
tokenOut.address,
2022-01-27 09:35:52 -08:00
isNative,
2022-01-28 08:23:49 -08:00
determineAmountFromToken(tokenOut.address)
2022-01-27 09:35:52 -08:00
);
2022-01-28 08:23:49 -08:00
console.info(`${tokenOut.name} -> ${tokenIn.name}`);
2022-01-27 09:35:52 -08:00
await swapEverythingExactOut(
swapper,
2022-01-28 08:23:49 -08:00
tokenOut.address,
tokenIn.address,
2022-01-27 09:35:52 -08:00
isNative,
2022-01-28 08:23:49 -08:00
determineAmountFromToken(tokenIn.address)
2022-01-27 09:35:52 -08:00
);
}
return;
}
main();