zic-tron-sdk
Version:
An sdk for interacting with tron zebec card sdk
226 lines (225 loc) • 12.3 kB
JavaScript
"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;