baluni-api
Version:
Api for baluni-cli
176 lines (175 loc) • 10 kB
JavaScript
;
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;