@flarenetwork/flare-stake-tool
Version:
Utilities for staking on the Flare network
232 lines • 9.3 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getWeb3 = getWeb3;
exports.getCBalance = getCBalance;
exports.getPBalance = getPBalance;
exports.getPCBalance = getPCBalance;
exports.getCPBalance = getCPBalance;
exports.getPStake = getPStake;
exports.getPStakes = getPStakes;
exports.getCurrentPStakes = getCurrentPStakes;
exports.getPStakesOf = getPStakesOf;
exports.getPStakesTo = getPStakesTo;
exports.getCTxBaseFee = getCTxBaseFee;
exports.estimateEIP1559Fee = estimateEIP1559Fee;
exports.numberOfCTxs = numberOfCTxs;
exports.getPTxDefaultFee = getPTxDefaultFee;
const settings = __importStar(require("../settings"));
const utils = __importStar(require("../utils"));
const pubk = __importStar(require("./pubk"));
const txs = __importStar(require("./txs"));
const bn_js_1 = __importDefault(require("bn.js"));
const flarejs_1 = require("@flarenetwork/flarejs");
const web3_1 = __importDefault(require("web3"));
const context_1 = require("./context");
function getWeb3(network) {
const web3 = new web3_1.default(settings.RPC[network]);
return web3;
}
async function getCBalance(network, cAddress) {
const balance = await getWeb3(network).eth.getBalance(cAddress);
return utils.weiToGwei(balance);
}
async function getPBalance(network, pAddress) {
const pvmapi = new flarejs_1.pvm.PVMApi(settings.URL[network]);
const { balance } = await pvmapi.getBalance({ addresses: [pAddress] });
return new bn_js_1.default(balance.toString());
}
async function getPCBalance(network, pAddress) {
const evmapi = new flarejs_1.evm.EVMApi(settings.URL[network]);
const context = await (0, context_1.getContext)(network);
const { utxos } = await evmapi.getUTXOs({
addresses: [`C-${pAddress.slice(2)}`],
sourceChain: context.pBlockchainID,
});
return sumUtxoTransferableOutputs(utxos);
}
async function getCPBalance(network, pAddress) {
const pvmapi = new flarejs_1.pvm.PVMApi(settings.URL[network]);
const context = await (0, context_1.getContext)(network);
const { utxos } = await pvmapi.getUTXOs({
addresses: [pAddress],
sourceChain: context.cBlockchainID,
});
return sumUtxoTransferableOutputs(utxos);
}
async function getPStake(network, pAddress) {
const pvmapi = new flarejs_1.pvm.PVMApi(settings.URL[network]);
const { staked } = await pvmapi.getStake({ addresses: [pAddress] });
return new bn_js_1.default(staked.toString());
}
async function getPStakes(network) {
let stakes = Array();
stakes = stakes.concat(await getCurrentPStakes(network));
return stakes;
}
async function getCurrentPStakes(network) {
const pvmapi = new flarejs_1.pvm.PVMApi(settings.URL[network]);
const { validators } = await pvmapi.getCurrentValidators();
const stakes = Array();
for (const validator of validators) {
stakes.push(await _parsePStake(network, validator, "validator"));
const delegators = validator.delegators;
if (delegators) {
for (const delegator of delegators) {
stakes.push(await _parsePStake(network, delegator, "delegator"));
}
}
}
return stakes;
}
async function getPStakesOf(network, pAddress, stakes) {
if (!stakes) {
stakes = await getPStakes(network);
}
return stakes.filter((s) => pubk.equalPAddress(network, s.address, pAddress));
}
async function getPStakesTo(network, pAddress, stakes) {
if (!stakes) {
stakes = await getPStakes(network);
}
const nodeIds = stakes
.filter((s) => s.type === "validator" && pubk.equalPAddress(network, s.address, pAddress))
.map((s) => s.nodeId);
return stakes.filter((s) => nodeIds.includes(s.nodeId));
}
async function _parsePStake(network, stake, type) {
let address;
if ("validationRewardOwner" in stake &&
stake.validationRewardOwner &&
stake.validationRewardOwner.addresses &&
stake.validationRewardOwner.addresses.length > 0) {
address = stake.validationRewardOwner.addresses[0];
}
else if ("delegationRewardOwner" in stake &&
stake.delegationRewardOwner &&
stake.delegationRewardOwner.addresses &&
stake.delegationRewardOwner.addresses.length > 0) {
address = stake.delegationRewardOwner.addresses[0];
}
else if ("rewardOwner" in stake &&
stake.rewardOwner &&
stake.rewardOwner.addresses &&
stake.rewardOwner.addresses.length > 0) {
address = stake.rewardOwner.addresses[0];
}
else {
const tx = await txs.getStakeTransaction(network, stake.txID);
if (tx instanceof flarejs_1.pvmSerial.AddDelegatorTx || tx instanceof flarejs_1.pvmSerial.AddValidatorTx) {
address = tx.getRewardsOwner().addrs[0].toHex();
}
else if (tx instanceof flarejs_1.pvmSerial.AddPermissionlessDelegatorTx) {
address = tx.getDelegatorRewardsOwner().addrs[0].toHex();
}
else if (tx instanceof flarejs_1.pvmSerial.AddPermissionlessValidatorTx) {
address = tx.getValidatorRewardsOwner().addrs[0].toHex();
}
else {
throw new Error("Unknown stake transaction type");
}
}
address = pubk.normalizePAddress(network, address);
return {
txId: stake.txID,
type: type,
address: address,
nodeId: stake.nodeID,
startTime: new Date(parseInt(stake.startTime) * 1e3),
endTime: new Date(parseInt(stake.endTime) * 1e3),
amount: new bn_js_1.default(stake.stakeAmount),
feePercentage: "delegationFee" in stake ? parseFloat(stake.delegationFee) : undefined,
};
}
async function getCTxBaseFee(network) {
// let avajs = getAvalanche(network)
// let feeWei = new BN(utils.toHex(await avajs.CChain().getBaseFee(), false), "hex")
const feeEstimate = await estimateEIP1559Fee(network);
const feeWei = feeEstimate[0] - feeEstimate[1];
return utils.weiToGweiCeil(feeWei);
}
async function estimateEIP1559Fee(network) {
const web3 = getWeb3(network);
const feeHistory = await web3.eth.getFeeHistory(4, "latest", ["10", "50"]);
let baseFee = BigInt(0);
let gasUsedRatio = 0;
let priorityFee10 = BigInt(0);
let priorityFee50 = BigInt(0);
for (let i = 0; i < 4; i++) {
const factor = BigInt(10 * (i + 1));
baseFee += factor * BigInt(feeHistory.baseFeePerGas[i]);
gasUsedRatio += Number(feeHistory.gasUsedRatio[i]); // feeHistory.gasUsedRatio is number
priorityFee10 += factor * BigInt(feeHistory.reward[i][0]);
priorityFee50 += factor * BigInt(feeHistory.reward[i][1]);
}
baseFee = baseFee / BigInt(100);
const priorityFee = (gasUsedRatio / 4 < 0.9 ? priorityFee10 : priorityFee50) / BigInt(100);
const maxFee = BigInt(2) * baseFee + priorityFee;
return [maxFee, priorityFee];
}
async function numberOfCTxs(network, cAddress) {
const web3 = getWeb3(network);
const nonce = await web3.eth.getTransactionCount(cAddress);
return Number(nonce);
}
async function getPTxDefaultFee(network) {
const context = await (0, context_1.getContext)(network);
return new bn_js_1.default(context.baseTxFee.toString());
}
//function _getChainId(network: string): number {
// let value = settings.CHAIN_ID[network]
// let chainId = parseInt(value)
// if (isNaN(chainId)) {
// chainId = parseInt(value, 16)
// }
// return chainId
//}
function sumUtxoTransferableOutputs(utxos) {
let balance = 0n;
for (const utxo of utxos) {
const out = utxo.output;
if (flarejs_1.utils.isTransferOut(out)) {
balance += out.amount();
}
}
return new bn_js_1.default(balance.toString());
}
//# sourceMappingURL=chain.js.map