@ardier16/q-js-sdk
Version:
Typescript Library to interact with Q System Contracts
346 lines • 14.8 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.QVaultInstance = void 0;
const web3_utils_1 = require("web3-utils");
const unit_converter_1 = require("../../utils/unit-converter");
const bn_js_1 = __importDefault(require("bn.js"));
const SystemContractInstance_1 = require("../SystemContractInstance");
const CompoundRateKeeperInstance_1 = require("../common/CompoundRateKeeperInstance");
const TimeLockHelperInstance_1 = require("../TimeLockHelperInstance");
const ERC20HelperInstance_1 = require("../ERC20HelperInstance");
const AbiImporter_1 = require("../../abi/AbiImporter");
/**
* QVault instance to interact with QVault contract.
* See [onchain documentation](@system-contracts-repo/@network/QVault/) for more details.
* An instance of this class for a deployed network can be obtained via {@link ContractRegistryInstance.qVault}
*/
class QVaultInstance extends SystemContractInstance_1.SystemContractInstance {
constructor(web3, address) {
super(web3, QVaultInstance.abi, address);
this.c = new unit_converter_1.UnitConverter();
const abi = (0, AbiImporter_1.getAbi)(QVaultInstance.abi);
this.timeLockHelper = new TimeLockHelperInstance_1.TimeLockHelperInstance(web3, QVaultInstance.abi, address);
this.erc20 = new ERC20HelperInstance_1.ERC20HelperInstance(web3, abi, address);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#aggregatednormalizedbalance)
*/
async aggregatedNormalizedBalance() {
return this.instance.methods.aggregatedNormalizedBalance().call();
}
/** @deprecated use getCompoundRateKeeper */
async compoundRateKeeper() {
return this.instance.methods.compoundRateKeeper().call();
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#getcompoundratekeeper)
*/
async getCompoundRateKeeper() {
const compoundRateKeeperAddress = await this.instance.methods.compoundRateKeeper().call();
return new CompoundRateKeeperInstance_1.CompoundRateKeeperInstance(this.adapter.web3, compoundRateKeeperAddress);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#deposit)
*/
async deposit(txOptions) {
return this.submitTransaction(this.instance.methods.deposit(), txOptions);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#lock)
*/
async lock(amount, txOptions) {
return this.submitTransaction(this.instance.methods.lock(amount), txOptions);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#announceunlock)
*/
async announceUnlock(amount, txOptions) {
return this.submitTransaction(this.instance.methods.announceUnlock(amount), txOptions);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#unlock)
*/
async unlock(amount, txOptions) {
return this.submitTransaction(this.instance.methods.unlock(amount), txOptions);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#withdraw)
*/
async withdraw(amount, txOptions) {
return this.submitTransaction(this.instance.methods.withdraw(amount), txOptions);
}
/**
* Withdraw all available amount.
* Use {@link QVaultInstance.getReadyToWithdrawBalance}
* @param user account.
* @returns Transaction receipt.
*/
async withdrawEntireBalance(user) {
return this.withdraw(await this.getReadyToWithdrawBalance(user), { from: user });
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#updatecompoundrate)
*/
async updateCompoundRate(txOptions) {
return this.submitTransaction(this.instance.methods.updateCompoundRate(), txOptions);
}
/** @deprecated compound rate has to be updated via ValidationRewardPoolsInstance */
async updateValidatorsCompoundRate(_validator, _txOptions) {
throw new Error('This has to be set via ValidationRewardPoolsInstance');
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#delegatestake)
*/
async delegateStake(delegatedTo, stakes, txOptions) {
return this.submitTransaction(this.instance.methods.delegateStake(delegatedTo, stakes), txOptions);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#name)
*/
async name() {
return this.erc20.name();
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#symbol)
*/
async symbol() {
return this.erc20.symbol();
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#decimals)
*/
async decimals() {
return this.erc20.decimals();
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#totalsupply)
*/
async totalSupply() {
return this.erc20.totalSupply();
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#balanceof)
*/
async balanceOf(userAddress) {
return this.erc20.balanceOf(userAddress);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#transfer)
*/
async transfer(receiver, amount, txOptions) {
return this.erc20.transfer(receiver, amount, txOptions);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#approve)
*/
async approve(spender, amount, txOptions) {
return this.erc20.approve(spender, amount, txOptions);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#transferfrom)
*/
async transferFrom(owner, receiver, amount, txOptions) {
return this.erc20.transferFrom(owner, receiver, amount, txOptions);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#allowance)
*/
async allowance(tokenOwner, spender) {
return this.erc20.allowance(tokenOwner, spender);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#increaseallowance)
*/
async increaseAllowance(spender, addedValue, txOptions) {
return this.erc20.increaseAllowance(spender, addedValue, txOptions);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#decreaseallowance)
*/
async decreaseAllowance(spender, subtractedValue, txOptions) {
return this.erc20.decreaseAllowance(spender, subtractedValue, txOptions);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#transferandcall)
*/
async transferAndCall(to, value, data, txOptions) {
return this.submitTransaction(this.instance.methods.transferAndCall(to, value, data), txOptions);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#withdrawto)
*/
async withdrawTo(recipient, amount, txOptions) {
return this.submitTransaction(this.instance.methods.withdrawTo(recipient, amount), txOptions);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#depositto)
*/
async depositTo(recipient, txOptions) {
return this.submitTransaction(this.instance.methods.depositTo(recipient), txOptions);
}
/**
* Token amount that can be withdrawn at current moment.
* This method takes into account all locks of QVault
* @param user account
* @returns Withdrawable amount
*/
async getReadyToWithdrawBalance(user) {
const currentTime = (0, web3_utils_1.toBN)((await this.adapter.web3.eth.getBlock('latest')).timestamp);
const votingWeightInfo = await this.votingWeightProxy.getBaseVotingWeightInfo(user, currentTime.toString());
const votingAgentLockUntil = (0, web3_utils_1.toBN)(votingWeightInfo.lockedUntil);
const lockInfo = await this.getLockInfo(user);
const currentBalance = (0, web3_utils_1.toBN)(await this.balanceOf(user));
const nonLockedAmount = currentBalance.sub((0, web3_utils_1.toBN)(lockInfo.lockedAmount)).sub((0, web3_utils_1.toBN)(lockInfo.pendingUnlockAmount));
const minimumFromTimeLocks = (0, web3_utils_1.toBN)(await this.getMinimumBalance(user, currentTime));
const minimumFromStakeDelegation = (0, web3_utils_1.toBN)(await this.getTotalDelegatedStake(user));
const minimumBalance = bn_js_1.default.max(minimumFromStakeDelegation, minimumFromTimeLocks);
let readyToWithdrawBalance = currentBalance.sub(minimumBalance);
if (currentBalance.toString() == '0') {
return '0';
}
if (readyToWithdrawBalance.lte(nonLockedAmount)) {
return readyToWithdrawBalance.toString();
}
const amountToUnlock = readyToWithdrawBalance.sub(nonLockedAmount);
if (currentTime.gte((0, web3_utils_1.toBN)(lockInfo.pendingUnlockTime))) {
const pendingUnlockAmount = (0, web3_utils_1.toBN)(lockInfo.pendingUnlockAmount);
if (amountToUnlock.lte(pendingUnlockAmount)) {
return readyToWithdrawBalance.toString();
}
if (currentTime.gte((0, web3_utils_1.toBN)(lockInfo.lockedUntil)) && currentTime.gte(votingAgentLockUntil)) {
return readyToWithdrawBalance.toString();
}
readyToWithdrawBalance = readyToWithdrawBalance.add(pendingUnlockAmount);
}
readyToWithdrawBalance = readyToWithdrawBalance.sub(amountToUnlock);
return readyToWithdrawBalance.toString();
}
/**
* Calculate total delegation stake for chosen account.
* @param user account.
* @returns total delegated stake.
*/
async getTotalDelegatedStake(user) {
const validatorInfos = await this.instance.methods.getDelegationsList(user).call();
let totalDelegatedStake = (0, web3_utils_1.toBN)(0);
for (let i = 0; i < validatorInfos.length; i++) {
totalDelegatedStake = totalDelegatedStake.add((0, web3_utils_1.toBN)(validatorInfos[i][1]));
}
return totalDelegatedStake.toString();
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#getdelegationslist)
*/
async getDelegationsList(user) {
const validatorInfos = await this.instance.methods.getDelegationsList(user).call();
const resultArr = [];
for (let i = 0; i < validatorInfos.length; i++) {
const currentValuesArr = validatorInfos[i];
resultArr.push({
validator: currentValuesArr[0],
actualStake: currentValuesArr[1],
normalizedStake: currentValuesArr[2],
compoundRate: currentValuesArr[3],
latestUpdateOfCompoundRate: currentValuesArr[4],
idealStake: currentValuesArr[5],
claimableReward: currentValuesArr[6]
});
}
return resultArr;
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#getnormalizedbalance)
*/
async getNormalizedBalance(userAddress) {
return this.instance.methods.getNormalizedBalance(userAddress).call();
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#claimstakedelegatorreward)
*/
async claimStakeDelegatorReward(txOptions) {
return this.submitTransaction(this.instance.methods.claimStakeDelegatorReward(), txOptions);
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#depositfrompool)
*/
async depositFromPool(txOptions) {
return this.submitTransaction(this.instance.methods.depositFromPool(), txOptions);
}
/** @deprecated user balance has to be received via balanceOf */
async getUserBalance(user) {
return this.instance.methods.balanceOf(user).call();
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#getbalancedetails)
*/
async getBalanceDetails(user) {
return (await this.instance.methods.getBalanceDetails().call({ from: user }));
}
/**
* [External documentation](@system-contracts-repo/@network/QVault/#getlockinfo)
*/
async getLockInfo(user) {
const result = await this.instance.methods.getLockInfo().call({ from: user });
const lockInfo = {
lockedAmount: result[0],
lockedUntil: result[1],
pendingUnlockAmount: result[2],
pendingUnlockTime: result[3]
};
return lockInfo;
}
/**
* Calculate available to delegate amount
* @param user account
* @returns delegatable amount
*/
async getDelegatableAmount(user) {
const balance = await this.balanceOf(user);
const alreadyDelegated = this.c.toBigNumber(await this.getTotalDelegatedStake(user));
const delegatableAmount = this.c.toBigNumber(balance).minus(alreadyDelegated);
return this.c.fromBigNumber(delegatableAmount);
}
/**
* Calculate available to lock amount
* @param user account
* @returns lockable amount
*/
async getLockableAmount(user) {
const balance = await this.balanceOf(user);
const lockInfo = await this.getLockInfo(user);
const alreadyLocked = this.c.toBigNumber(lockInfo.lockedAmount).plus(this.c.toBigNumber(lockInfo.pendingUnlockAmount));
const lockableAmount = this.c.toBigNumber(balance).minus(alreadyLocked);
return this.c.fromBigNumber(lockableAmount);
}
/**
* {@link TimeLockHelperInstance.depositOnBehalfOf | Internal documentation}
*/
async depositOnBehalfOf(account, start, end, txOptions) {
return this.timeLockHelper.depositOnBehalfOf(account, start, end, txOptions);
}
/**
* {@link TimeLockHelperInstance.getTimeLocks | Internal documentation}
*/
async getTimeLocks(account) {
return this.timeLockHelper.getTimeLocks(account);
}
/**
* {@link TimeLockHelperInstance.getMinimumBalance | Internal documentation}
*/
async getMinimumBalance(account, timestamp) {
return this.timeLockHelper.getMinimumBalance(account, timestamp);
}
/**
* {@link TimeLockHelperInstance.purgeTimeLocks | Internal documentation}
*/
async purgeTimeLocks(account, txOptions) {
return this.timeLockHelper.purgeTimeLocks(account, txOptions);
}
}
exports.QVaultInstance = QVaultInstance;
QVaultInstance.registryKey = 'tokeneconomics.qVault';
QVaultInstance.abi = 'QVault.json';
//# sourceMappingURL=QVaultInstance.js.map