Some checks failed
morphit-release / Build + publish release tarball (push) Has been cancelled
190 lines
8.6 KiB
JavaScript
190 lines
8.6 KiB
JavaScript
"use strict";
|
|
/**
|
|
* @file Account helpers.
|
|
* @author BeBlurt <https://beblurt.com/@beblurt>
|
|
* @description Special account functions
|
|
* @license
|
|
* Copyright (c) 2022 BeBlurt. All Rights Reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
* are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistribution of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistribution in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* You acknowledge that this software is not designed, licensed or intended for use
|
|
* in the design, construction, operation or maintenance of any military facility.
|
|
*/
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.Tools = void 0;
|
|
const asset_1 = require("../chain/asset");
|
|
const serializer_1 = require("../chain/serializer");
|
|
const ByteBuffer = require('bytebuffer/dist/bytebuffer');
|
|
const BLURT_VOTING_MANA_REGENERATION_SECONDS = (5 * 60 * 60 * 24); // 5 day (432000 seconds)
|
|
const BLURT_100_PERCENT = 10000;
|
|
const BLURT_UPVOTE_LOCKOUT_SECONDS = (60 * 60 * 12); // 12 hours (43200 seconds)
|
|
class Tools {
|
|
constructor(client) {
|
|
this.client = client;
|
|
}
|
|
/** Convenience for calling `condenser_api`. */
|
|
call(method, params) {
|
|
return this.client.call('condenser_api', method, params);
|
|
}
|
|
/**
|
|
* Get voting mana for an account.
|
|
*
|
|
* @param name Account name.
|
|
* @returns Current and maximum voting mana calculated from account vesting state.
|
|
*/
|
|
async getAccountMana(name) {
|
|
try {
|
|
/** get Account */
|
|
const accounts = await this.call('get_accounts', [[name]]);
|
|
if (accounts.length > 0) {
|
|
const account = accounts[0];
|
|
/** Vesting */
|
|
let net_vesting_shares = asset_1.Asset.from(account.vesting_shares);
|
|
net_vesting_shares = net_vesting_shares.subtract(account.delegated_vesting_shares);
|
|
net_vesting_shares = net_vesting_shares.add(account.received_vesting_shares);
|
|
/** Vesting withdraw rate */
|
|
const vesting_withdraw_rate = asset_1.Asset.from(account.vesting_withdraw_rate);
|
|
/** Mana Calculation */
|
|
let current_mana = parseInt(account.voting_manabar.current_mana, 10);
|
|
const now = Math.round(Date.now() / 1000);
|
|
const elapsed = now - account.voting_manabar.last_update_time;
|
|
const max_mana = (net_vesting_shares.amount - vesting_withdraw_rate.amount) * 1000000;
|
|
const regenerated_mana = (elapsed * max_mana) / BLURT_VOTING_MANA_REGENERATION_SECONDS;
|
|
current_mana += regenerated_mana;
|
|
if (current_mana >= max_mana) {
|
|
current_mana = max_mana;
|
|
}
|
|
return { current_mana, max_mana };
|
|
}
|
|
else {
|
|
throw new Error('invalid account name');
|
|
}
|
|
}
|
|
catch (e) {
|
|
throw e;
|
|
}
|
|
}
|
|
/**
|
|
* Estimate the vote value for a post from mana, reward fund and chain properties.
|
|
*
|
|
* @param voteWeight Vote weight percentage.
|
|
* @param mana Current and maximum voting mana for the account.
|
|
* @param net_rshares Net rshares of the post.
|
|
* @param cashout_time Cashout time of the post in milliseconds.
|
|
* @param DGP Dynamic global properties.
|
|
* @param REWARD_FUND Reward fund data.
|
|
* @returns Estimated vote value rounded to three decimals.
|
|
*/
|
|
getAccountVoteValue(voteWeight, mana, net_rshares, cashout_time, DGP, REWARD_FUND) {
|
|
try {
|
|
const postRshares = typeof net_rshares === 'string' ? parseInt(net_rshares, 10) : net_rshares;
|
|
const cashoutDelta = (cashout_time - Date.now()) / 1000;
|
|
if (cashoutDelta <= 0) {
|
|
return 0;
|
|
}
|
|
/** Dynamic Global Properties */
|
|
const vote_power_reserve_rate = DGP.vote_power_reserve_rate;
|
|
const vestedBlurt = asset_1.Asset.from(DGP.total_vesting_fund_blurt);
|
|
const currentSupply = asset_1.Asset.from(DGP.current_supply);
|
|
const ratio = vestedBlurt.amount / currentSupply.amount;
|
|
let usedMana = (mana.current_mana * (voteWeight * 100) * 60 * 60 * 24) / BLURT_100_PERCENT;
|
|
const maxVoteDenom = vote_power_reserve_rate * BLURT_VOTING_MANA_REGENERATION_SECONDS;
|
|
usedMana = (usedMana + maxVoteDenom - 1) / maxVoteDenom;
|
|
let rshares = usedMana;
|
|
if (cashoutDelta < BLURT_UPVOTE_LOCKOUT_SECONDS) {
|
|
rshares = (rshares * cashoutDelta) / BLURT_UPVOTE_LOCKOUT_SECONDS;
|
|
}
|
|
const totalRshares = rshares + postRshares;
|
|
const S = parseInt(REWARD_FUND.content_constant, 10);
|
|
const claims = (totalRshares * (totalRshares + 2 * S)) / (totalRshares + 4 * S);
|
|
const rewardBalance = asset_1.Asset.from(REWARD_FUND.reward_balance).amount;
|
|
const recentClaims = parseInt(REWARD_FUND.recent_claims, 10);
|
|
const rewards = rewardBalance / recentClaims;
|
|
const postValue = claims * rewards * ratio;
|
|
const totPost = postValue * (rshares / totalRshares);
|
|
return parseFloat(totPost.toFixed(3));
|
|
}
|
|
catch (e) {
|
|
throw e;
|
|
}
|
|
}
|
|
/**
|
|
* Get the conversion of VESTS to BLURT.
|
|
* @param VESTS VESTS value.
|
|
* @param DGP Dynamic global properties from `condenser_api.get_dynamic_global_properties`.
|
|
*/
|
|
convertVESTS(VESTS, DGP) {
|
|
try {
|
|
const total_vesting_fund_blurt = asset_1.Asset.from(DGP.total_vesting_fund_blurt).amount;
|
|
const total_vesting_shares = asset_1.Asset.from(DGP.total_vesting_shares).amount;
|
|
return Math.round(((total_vesting_fund_blurt * VESTS) / total_vesting_shares) * 1000) / 1000;
|
|
}
|
|
catch (e) {
|
|
throw e;
|
|
}
|
|
}
|
|
serialize(serializer, data) {
|
|
const buffer = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN);
|
|
serializer(buffer, data);
|
|
buffer.flip();
|
|
return Buffer.from(buffer.toBuffer());
|
|
}
|
|
buildWitnessSetPropertiesOp(owner, props) {
|
|
const data = {
|
|
extensions: [], owner, props: []
|
|
};
|
|
for (const key of Object.keys(props)) {
|
|
let type;
|
|
switch (key) {
|
|
case 'key':
|
|
case 'new_signing_key':
|
|
type = serializer_1.Types.PublicKey;
|
|
break;
|
|
case 'account_subsidy_budget':
|
|
case 'account_subsidy_decay':
|
|
case 'maximum_block_size':
|
|
type = serializer_1.Types.UInt32;
|
|
break;
|
|
case 'url':
|
|
type = serializer_1.Types.String;
|
|
break;
|
|
case 'account_creation_fee':
|
|
case 'operation_flat_fee':
|
|
case 'bandwidth_kbytes_fee':
|
|
case 'proposal_fee':
|
|
type = serializer_1.Types.Asset;
|
|
break;
|
|
default:
|
|
throw new Error(`Unknown witness prop: ${key}`);
|
|
}
|
|
data.props.push([key, this.serialize(type, props[key])]);
|
|
}
|
|
data.props.sort((a, b) => a[0].localeCompare(b[0]));
|
|
return ['witness_set_properties', data];
|
|
}
|
|
}
|
|
exports.Tools = Tools;
|