UNPKG

baluni-api

Version:
176 lines (175 loc) 10 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildSwap = void 0; const ethers_1 = require("ethers"); const ERC20_json_1 = __importDefault(require("../../abis/common/ERC20.json")); const SwapRouter_json_1 = __importDefault(require("../../abis/uniswap/SwapRouter.json")); const Router_json_1 = __importDefault(require("../../abis/infra/Router.json")); const Quoter_json_1 = __importDefault(require("../../abis/uniswap/Quoter.json")); const Factory_json_1 = __importDefault(require("../../abis/uniswap/Factory.json")); const constants_1 = require("../../constants"); const dotenv_1 = __importDefault(require("dotenv")); const bestQuote_1 = require("../../utils/uniswap/bestQuote"); dotenv_1.default.config(); function buildSwap(wallet, address, token0, token1, reverse, protocol, chainId, amount, slippage) { return __awaiter(this, void 0, void 0, function* () { console.log('BUILD SWAP'); const quoter = String(constants_1.PROTOCOLS[chainId][protocol].QUOTER); const factory = String(constants_1.PROTOCOLS[chainId][protocol].FACTORY); const uniRouter = String(constants_1.PROTOCOLS[chainId][protocol].ROUTER); const swapRouterContract = new ethers_1.Contract(uniRouter, SwapRouter_json_1.default, wallet); const infraRouter = String(constants_1.INFRA[chainId].ROUTER); const InfraRouterContract = new ethers_1.Contract(infraRouter, Router_json_1.default, wallet); const agentAddress = yield InfraRouterContract.getAgentAddress(address); const tokenAAddress = reverse == true ? token1 : token0; const tokenBAddress = reverse == true ? token0 : token1; const tokenAContract = new ethers_1.Contract(tokenAAddress, ERC20_json_1.default, wallet); const tokenADecimals = yield tokenAContract.decimals(); const tokenABalance = yield tokenAContract.balanceOf(address); console.log('::API::UNISWAP::BUILDSWAP TOKEN_A_BALANCE ', Number(tokenABalance)); console.log('::API::UNISWAP::BUILDSWAP TOKEN_A_ADDRESS ', tokenAAddress); // const tokenBContract = new Contract(tokenBAddress, erc20Abi, provider); // const tokenBDecimals = await tokenBContract.decimals(); // const gasLimit: Number = 30000000; // const gasPrice: BigNumberish = await wallet.provider.getGasPrice(); // const gas: BigNumberish = gasPrice; let Approvals = []; let Calldatas = []; let adjAmount = ethers_1.ethers.BigNumber.from(0); console.log('::API::UNISWAP::BUILDSWAP TOKEN_DECIMAL ', Number(tokenADecimals)); if (tokenADecimals == 0) { throw new Error('Invalid Token Decimals'); } adjAmount = (0, bestQuote_1.getAdjAmount)(amount, tokenADecimals); console.log('::API::UNISWAP::BUILDSWAP AMOUNT ', Number(amount)); console.log('::API::UNISWAP::BUILDSWAP ADJ_AMOUNT ', Number(adjAmount)); if (tokenABalance.lt(adjAmount)) { console.log('::API::UNISWAP:: BUILDSWAP INSUFFICIENT_BALANCE'); } else { if (adjAmount == 0) { throw new Error('Invalid Token Decimals'); } const quoterContract = new ethers_1.Contract(quoter, Quoter_json_1.default, wallet); const factoryContract = new ethers_1.Contract(factory, Factory_json_1.default, wallet); // const quote = await quotePair( // tokenAAddress, // tokenBAddress, // Number(chainId) // ); const allowanceAgent = yield (tokenAContract === null || tokenAContract === void 0 ? void 0 : tokenAContract.allowance(address, agentAddress)); const allowanceAgentToRouter = yield (tokenAContract === null || tokenAContract === void 0 ? void 0 : tokenAContract.allowance(agentAddress, uniRouter)); const slippageTolerance = slippage; console.log('::API::UNISWAP::BUILDSWAP ALLOWANCE_AGENT_SENDER_AMOUNT', Number(allowanceAgent)); console.log('::API::UNISWAP::BUILDSWAP ALLOWANCE_AGENT_UNIROUTER_AMOUNT', Number(allowanceAgentToRouter)); console.log('::API::UNISWAP::BUILDSWAP ROUTER_ADDRESS', infraRouter); console.log('::API::UNISWAP::BUILDSWAP UNI_ROUTER_ADDRESS', uniRouter); console.log('::API::UNISWAP::BUILDSWAP AGENT_ADDRESS', agentAddress); // Allowance for Sender to Agent // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- if (allowanceAgent.lt(adjAmount)) { console.log('::API::UNISWAP::BUILDSWAP MISSING_ALLOWANCE_SENDER_FOR_AGENT '); const dataApproveToAgent = tokenAContract.interface.encodeFunctionData('approve', [agentAddress, ethers_1.ethers.constants.MaxUint256]); const tx = { to: tokenAAddress, value: 0, data: dataApproveToAgent, }; Approvals.push(tx); } else { console.log('::API::UNISWAP::BUILDSWAP FOUND_SENDER_ALLOWANCE_FOR_AGENT'); } // Allowance for Agent to Univ3 // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- if (allowanceAgentToRouter.lt(adjAmount)) { console.log('::API::UNISWAP::BUILDSWAP MISSING_AGENT_ALLOWANCE_FOR_UNIROUTER '); const calldataApproveAgentToRouter = tokenAContract.interface.encodeFunctionData('approve', [ uniRouter, ethers_1.ethers.constants.MaxUint256, ]); const tx = { to: tokenAAddress, value: 0, data: calldataApproveAgentToRouter, }; Calldatas.push(tx); } else { console.log('::API::UNISWAP::BUILDSWAP FOUND_AGENT_ALLOWANCE_FOR_UNIROUTER'); } // Transfer tokens from Sender to Agent // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- const dataTransferFromSenderToAgent = tokenAContract.interface.encodeFunctionData('transferFrom', [ address, agentAddress, adjAmount, ]); const tx = { to: tokenAAddress, value: 0, data: dataTransferFromSenderToAgent, }; if (tx) console.log('::API::UNISWAP::BUILDSWAP BUILD_TRANSFER_FROM_SENDER_TO_AGENT'); Calldatas.push(tx); // Encode Swap tx to Uni Router // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- const bestQuote = yield (0, bestQuote_1.getBestQuoteForSwapPath)(factoryContract, quoterContract, tokenAAddress, tokenBAddress, adjAmount, slippageTolerance, chainId); console.log('::API:: BEST QUOTE FOUND!', bestQuote); let swapDeadline = Math.floor(Date.now() / 1000 + 60 * 60); // 1 hour from now let path; if (bestQuote.amountOut !== ethers_1.BigNumber.from(0) && bestQuote.poolFees.length != 1) { path = ethers_1.ethers.utils.solidityPack(['address', 'uint24', 'address', 'uint24', 'address'], [ bestQuote.path[0], bestQuote.poolFees[0], bestQuote.path[1], bestQuote.poolFees[1], bestQuote.path[2], ]); } else if (bestQuote.amountOut !== ethers_1.BigNumber.from(0)) { path = ethers_1.ethers.utils.solidityPack(['address', 'uint24', 'address'], [bestQuote.path[0], bestQuote.poolFees[0], bestQuote.path[1]]); } let swapTxInputs = [path, agentAddress, swapDeadline, adjAmount, 0]; const calldataSwapAgentToRouter = swapRouterContract.interface.encodeFunctionData('exactInputSingle', [ swapTxInputs, ]); const tx2 = { to: uniRouter, value: 0, data: calldataSwapAgentToRouter, }; if (tx2) console.log('::API::UNISWAP::BUILDSWAP BUILD_AGENT_EXACT_INPUT_TO_UNIROUTER'); Calldatas.push(tx2); } const TokensReturn = [tokenBAddress]; console.log('::API::UNISWAP::BUILDSWAP Approvals', Approvals.length); console.log('::API::UNISWAP::BUILDSWAP Calldatas', Calldatas.length); console.log('::API::UNISWAP::BUILDSWAP TokensReturn', TokensReturn.length); return { Approvals, Calldatas, TokensReturn, }; }); } exports.buildSwap = buildSwap;