UNPKG

zic-tron-sdk

Version:
226 lines (225 loc) 12.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TronZebecCardService = exports.TronNetwork = void 0; const assert_1 = __importDefault(require("assert")); const tronweb_1 = require("tronweb"); const artifacts_1 = require("./artifacts"); const constants_1 = require("./constants"); const payload_1 = require("./payload"); const utils_1 = require("./utils"); var TronNetwork; (function (TronNetwork) { TronNetwork[TronNetwork["Mainnet"] = 0] = "Mainnet"; TronNetwork[TronNetwork["Nile"] = 1] = "Nile"; })(TronNetwork || (exports.TronNetwork = TronNetwork = {})); class TronZebecCardService { constructor(tronWeb, network, walletInterface) { this.tronWeb = tronWeb; (0, assert_1.default)(tronWeb instanceof tronweb_1.TronWeb, "Invalid TronWeb instance."); this.network = network ? network : TronNetwork.Mainnet; const cardContractAddress = (0, utils_1.toHex)(constants_1.TRON_ZEBEC_CARD_CONTRACT_ADDRESS[this.network]); this.cardContract = new tronweb_1.Contract(tronWeb, artifacts_1.TRON_ZEBEC_CARD_ABI, cardContractAddress); const usdtContractAddress = (0, utils_1.toHex)(constants_1.TRON_USDT_ADDRESS[this.network]); this.usdtContract = new tronweb_1.Contract(tronWeb, artifacts_1.TRON_USDT_ABI, usdtContractAddress); if (!tronWeb.defaultPrivateKey) { if (walletInterface?.address) { tronWeb.setAddress((0, utils_1.toHex)(walletInterface.address)); } else { throw new Error("Either provide private key in tronweb or provide address in walletInterface."); } } this._signTransaction = walletInterface?.signTransaction; } get cardContractAddress() { const address = this.cardContract.address; (0, assert_1.default)(typeof address === "string"); return (0, utils_1.fromHex)(address); } get usdtAddress() { const address = this.usdtContract.address; (0, assert_1.default)(typeof address === "string"); return (0, utils_1.fromHex)(address); } get signerAddress() { const signer = this.tronWeb.defaultAddress.base58; (0, assert_1.default)(typeof signer === "string"); return signer; } async getCardConfig(callOptions) { const cardConfig = await this.cardContract.cardConfig().call(callOptions); return { nativeFeePercent: (0, utils_1.bpsToPercent)(cardConfig[0].toString()), nonNativeFeePercent: (0, utils_1.bpsToPercent)(cardConfig[1].toString()), revenueFeePercent: (0, utils_1.bpsToPercent)(cardConfig[2].toString()), totalCardSold: cardConfig[3], cardVault: tronweb_1.utils.address.fromHex(cardConfig[4]), revenueVault: tronweb_1.utils.address.fromHex(cardConfig[5]), usdcAddress: tronweb_1.utils.address.fromHex(cardConfig[6]), minCardAmount: (0, tronweb_1.BigNumber)(cardConfig[7].toString()).div(constants_1.UNITS_PER_TRON_USDT).toFixed(), maxCardAmount: (0, tronweb_1.BigNumber)(cardConfig[8].toString()).div(constants_1.UNITS_PER_TRON_USDT).toFixed(), dailyCardPurchaseLimit: (0, tronweb_1.BigNumber)(cardConfig[9].toString()) .div(constants_1.UNITS_PER_TRON_USDT) .toFixed(), }; } async getFeeTiers(callOptions) { const feeTiers = await this.cardContract.getFeeTiers().call(callOptions); (0, assert_1.default)(Array.isArray(feeTiers)); return feeTiers.map((tier) => { const minRange = (0, tronweb_1.BigNumber)(tier[0].toString()).div(constants_1.UNITS_PER_TRON_USDT).toFixed(); const maxRange = (0, tronweb_1.BigNumber)(tier[1].toString()).div(constants_1.UNITS_PER_TRON_USDT).toFixed(); const fee = (0, utils_1.bpsToPercent)(tier[2].toString()); return { fee, maxRange, minRange, }; }); } async getUserVaultBalance(params) { const userAddress = tronweb_1.utils.address.toHex(params.userAddress); const userBalance = await this.cardContract.cardBalances(userAddress).call(); const formatted = (0, tronweb_1.BigNumber)(userBalance.toString()).div(constants_1.UNITS_PER_TRON_USDT).toFixed(); return formatted; } async getCardPurchcaseOfDay(params) { const cardPurchase = await this.cardContract.cardPurchases(params.userAddress).call(); const totalCardPurchased = (0, tronweb_1.BigNumber)(cardPurchase.totalCardBoughtPerDay) .div(constants_1.UNITS_PER_TRON_USDT) .toFixed(); const cardPurchasedTimestamp = Number(cardPurchase.unixInRecord.toString()); return { cardPurchasedTimestamp, totalCardPurchased }; } async depositUsdt(params) { const amount = (0, tronweb_1.BigNumber)(params.amount).times(constants_1.UNITS_PER_TRON_USDT).toFixed(0); const userUsdcBalance = await this.usdtContract.balanceOf(this.signerAddress).call(); if ((0, tronweb_1.BigNumber)(userUsdcBalance.toString()).isLessThan(amount)) { throw new Error("Not Enough Balance: token: " + this.usdtAddress + ", required: " + params.amount + ", current: " + (0, tronweb_1.BigNumber)(userUsdcBalance.toString()).div(constants_1.UNITS_PER_TRON_USDT).toFixed()); } const functionName = "depositUsdc"; const args = [BigInt(amount)]; return this._createTransactionPayload(this.cardContract, functionName, args); } async swapAndDeposit(params) { const inToken = params.swapData.tokens[0]; const outToken = params.swapData.tokens[params.swapData.tokens.length - 1]; const inTokenDecimals = await (0, utils_1.getTokenDecimals)(this.tronWeb, inToken); const slippage = params.swapData.slippagePercent; if (outToken !== this.usdtAddress) { throw new Error("Invalid usdt token: " + outToken); } const unitsPerInToken = constants_1.TEN_BIGNUM.pow(inTokenDecimals); const amountIn = (0, tronweb_1.BigNumber)(params.swapData.amountIn).times(unitsPerInToken).toFixed(0); const amountOut = (0, tronweb_1.BigNumber)(params.swapData.amountOut).times(constants_1.UNITS_PER_TRON_USDT); const amountOutMin = amountOut.minus(amountOut.times(slippage / 100)).toFixed(0); const isNative = inToken === constants_1.TRON_TRX_ADDRESS[this.network]; if (isNative) { const userInTokenBalance = BigInt(await this.tronWeb.trx.getBalance(this.signerAddress)); if ((0, tronweb_1.BigNumber)(userInTokenBalance.toString()).isLessThan(amountIn)) { throw new Error("Not Enough Balance: token: " + inToken + ", required: " + params.swapData.amountIn + ", current: " + (0, tronweb_1.BigNumber)(userInTokenBalance.toString()).div(unitsPerInToken).toFixed()); } } else { const inTokenContract = new tronweb_1.Contract(this.tronWeb, artifacts_1.TRC20_ABI, (0, utils_1.toHex)(inToken)); const userInTokenBalance = await inTokenContract.balanceOf(this.signerAddress).call(); if ((0, tronweb_1.BigNumber)(userInTokenBalance.toString()).isLessThan(amountIn)) { throw new Error("Not Enough Balance: token: " + inToken + ", required: " + params.swapData.amountIn + ", current: " + (0, tronweb_1.BigNumber)(userInTokenBalance.toString()).div(unitsPerInToken).toFixed()); } const allowance = BigInt(await inTokenContract.allowance(this.signerAddress, this.cardContractAddress).call()); if ((0, tronweb_1.BigNumber)(allowance.toString()).isLessThan(amountIn)) { throw new Error("Not Enough Allowance: token: " + inToken + ", spender: " + this.cardContractAddress + ", required allowance: " + params.swapData.amountIn + ", current allowance: " + (0, tronweb_1.BigNumber)(allowance.toString()).div(unitsPerInToken).toFixed()); } } const path = params.swapData.tokens; const poolVersions = params.swapData.poolVersions; const versionLen = params.swapData.versionLen; // todo find out how to find out the value of this part const fees = params.swapData.poolFees.map((fee) => BigInt(fee)); const to = this.cardContractAddress; const deadline = Math.floor(Date.now() / 1000) + 120; // 2 min from now const functionName = "swapAndDeposit"; const args = [ path, poolVersions, versionLen, fees, [BigInt(amountIn), BigInt(amountOutMin), to, BigInt(deadline)], ]; const callValue = isNative ? Number(amountIn) : 0; return this._createTransactionPayload(this.cardContract, functionName, args, callValue); } async withdraw(params) { const amount = (0, tronweb_1.BigNumber)(params.amount).times(constants_1.UNITS_PER_TRON_USDT).toFixed(0); const functionName = "withdraw"; const args = [BigInt(amount)]; return this._createTransactionPayload(this.cardContract, functionName, args); } async buyCard(params) { const amount = (0, tronweb_1.BigNumber)(params.amount).times(constants_1.UNITS_PER_TRON_USDT).toFixed(0); const userVaultBalance = await this.getUserVaultBalance({ userAddress: this.signerAddress }); if ((0, tronweb_1.BigNumber)(userVaultBalance).isLessThan(params.amount)) { throw new Error("Not Enough Vault Balance: required: " + params.amount + ", current: " + userVaultBalance); } const email = params.email.toLowerCase(); if (!(0, utils_1.isEmailValid)(email)) { throw new Error("Invalid email"); } const emailHash = tronweb_1.utils.ethersUtils.sha256(new TextEncoder().encode(email)); const functionName = "buyCard"; const args = [BigInt(amount), emailHash]; return this._createTransactionPayload(this.cardContract, functionName, args); } async approve(params) { const trc20 = typeof params.token === "string" ? new tronweb_1.Contract(this.tronWeb, artifacts_1.TRC20_ABI, params.token) : params.token; (0, assert_1.default)("approve" in trc20, "Contract does not have approve method"); (0, assert_1.default)("decimals" in trc20, "Contract does not have decimals method"); (0, assert_1.default)("allowance" in trc20, "Contract does not have allowance method"); const tokenAddress = trc20.address; (0, assert_1.default)(typeof tokenAddress === "string", "address is missing trc20 contract"); const spender = (0, utils_1.fromHex)(params.spender); const approver = this.signerAddress; const decimals = await trc20.decimals().call(); const parsedAmount = (0, tronweb_1.BigNumber)(params.amount) .times(constants_1.TEN_BIGNUM.pow(decimals.toString())) .toFixed(0); const allowance = await trc20.allowance(approver, spender).call(); if ((0, tronweb_1.BigNumber)(allowance.toString()).isLessThan(parsedAmount)) { const functionName = "approve"; const args = [spender, BigInt(parsedAmount)]; return this._createTransactionPayload(trc20, functionName, args); } return null; } async _createTransactionPayload(contract, functionName, args, callValue) { const signerAddress = (0, utils_1.toHex)(this.signerAddress); return new payload_1.TransactionPayload(this.tronWeb, contract, functionName, args, { from: signerAddress, callValue }, this._signTransaction); } } exports.TronZebecCardService = TronZebecCardService;