@c4tplatform/caminojs
Version:
Camino Platform JS Library
1,066 lines • 357 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PlatformVMAPI = void 0;
/**
* @packageDocumentation
* @module API-PlatformVM
*/
const buffer_1 = require("buffer/");
const bn_js_1 = __importDefault(require("bn.js"));
const common_1 = require("../../common");
const errors_1 = require("../../utils/errors");
const bintools_1 = __importDefault(require("../../utils/bintools"));
const keychain_1 = require("./keychain");
const constants_1 = require("../../utils/constants");
const constants_2 = require("./constants");
const tx_1 = require("./tx");
const payload_1 = require("../../utils/payload");
const helperfunctions_1 = require("../../utils/helperfunctions");
const utxos_1 = require("../platformvm/utxos");
const errors_2 = require("../../utils/errors");
const inputs_1 = require("./inputs");
const outputs_1 = require("./outputs");
const utils_1 = require("../../utils");
const builder_1 = require("./builder");
const spender_1 = require("./spender");
const adddepositoffertx_1 = require("./adddepositoffertx");
const subnetauth_1 = require("./subnetauth");
/**
* @ignore
*/
const bintools = bintools_1.default.getInstance();
const serialization = utils_1.Serialization.getInstance();
const NanoBN = new bn_js_1.default(1000000000);
const rewardPercentDenom = 1000000;
/**
* Class for interacting with a node's PlatformVMAPI
*
* @category RPCAPIs
*
* @remarks This extends the [[JRPCAPI]] class. This class should not be directly called. Instead, use the [[Avalanche.addAPI]] function to register this interface with Avalanche.
*/
class PlatformVMAPI extends common_1.JRPCAPI {
/**
* @ignore
*/
_cleanAddressArray(addresses, caller) {
const addrs = [];
const chainid = this.getBlockchainAlias()
? this.getBlockchainAlias()
: this.getBlockchainID();
if (addresses && addresses.length > 0) {
for (let i = 0; i < addresses.length; i++) {
if (typeof addresses[`${i}`] === "string") {
if (typeof this.parseAddress(addresses[`${i}`]) ===
"undefined") {
/* istanbul ignore next */
throw new errors_2.AddressError(`Error - Invalid address format (${caller})`);
}
addrs.push(addresses[`${i}`]);
}
else {
const bech32 = "bech32";
addrs.push(serialization.bufferToType(addresses[`${i}`], bech32, this.core.getHRP(), chainid));
}
}
}
return addrs;
}
_cleanAddressArrayBuffer(addresses, caller) {
return this._cleanAddressArray(addresses, caller).map((a) => {
return typeof a === "undefined"
? undefined
: bintools.stringToAddress(a);
});
}
_parseFromSigner(from, caller) {
if (from.length > 0) {
if (typeof from[0] === "string")
return {
from: this._cleanAddressArrayBuffer(from, caller),
signer: []
};
else
return {
from: this._cleanAddressArrayBuffer(from[0], caller),
signer: from.length > 1
? this._cleanAddressArrayBuffer(from[1], caller)
: []
};
}
return { from: [], signer: [] };
}
/**
* This class should not be instantiated directly.
* Instead use the [[Avalanche.addAPI]] method.
*
* @param core A reference to the Avalanche class
* @param baseURL Defaults to the string "/ext/P" as the path to blockchain's baseURL
*/
constructor(core, baseURL = "/ext/bc/P") {
super(core, baseURL);
/**
* @ignore
*/
this.keychain = new keychain_1.KeyChain("", "");
this.blockchainID = "";
this.blockchainAlias = undefined;
this.AVAXAssetID = undefined;
this.txFee = undefined;
this.creationTxFee = undefined;
this.minValidatorStake = undefined;
this.minDelegatorStake = undefined;
/**
* Gets the alias for the blockchainID if it exists, otherwise returns `undefined`.
*
* @returns The alias for the blockchainID
*/
this.getBlockchainAlias = () => {
return this.core.getNetwork().P.alias;
};
/**
* Gets the current network, fetched via avalanche.fetchNetworkSettings.
*
* @returns The current Network
*/
this.getNetwork = () => {
return this.core.getNetwork();
};
/**
* Gets the blockchainID and returns it.
*
* @returns The blockchainID
*/
this.getBlockchainID = () => this.blockchainID;
/**
* Takes an address string and returns its {@link https://github.com/feross/buffer|Buffer} representation if valid.
*
* @returns A {@link https://github.com/feross/buffer|Buffer} for the address if valid, undefined if not valid.
*/
this.parseAddress = (addr) => {
const alias = this.getBlockchainAlias();
const blockchainID = this.getBlockchainID();
return bintools.parseAddress(addr, blockchainID, alias, constants_2.PlatformVMConstants.ADDRESSLENGTH);
};
this.addressFromBuffer = (address) => {
const chainid = this.getBlockchainAlias()
? this.getBlockchainAlias()
: this.getBlockchainID();
const type = "bech32";
return serialization.bufferToType(address, type, this.core.getHRP(), chainid);
};
/**
* Fetches the AVAX AssetID and returns it in a Promise.
*
* @param refresh This function caches the response. Refresh = true will bust the cache.
*
* @returns The the provided string representing the AVAX AssetID
*/
this.getAVAXAssetID = (refresh = false) => __awaiter(this, void 0, void 0, function* () {
if (typeof this.AVAXAssetID === "undefined" || refresh) {
this.AVAXAssetID = bintools.cb58Decode(this.core.getNetwork().X.avaxAssetID);
}
return this.AVAXAssetID;
});
/**
* Overrides the defaults and sets the cache to a specific AVAX AssetID
*
* @param avaxAssetID A cb58 string or Buffer representing the AVAX AssetID
*
* @returns The the provided string representing the AVAX AssetID
*/
this.setAVAXAssetID = (avaxAssetID) => {
if (typeof avaxAssetID === "string") {
avaxAssetID = bintools.cb58Decode(avaxAssetID);
}
this.AVAXAssetID = avaxAssetID;
};
/**
* Gets the default tx fee for this chain.
*
* @returns The default tx fee as a {@link https://github.com/indutny/bn.js/|BN}
*/
this.getDefaultTxFee = () => {
return new bn_js_1.default(this.core.getNetwork().P.txFee);
};
/**
* Gets the tx fee for this chain.
*
* @returns The tx fee as a {@link https://github.com/indutny/bn.js/|BN}
*/
this.getTxFee = () => {
if (typeof this.txFee === "undefined") {
this.txFee = this.getDefaultTxFee();
}
return this.txFee;
};
/**
* Gets the CreateAssetTx fee.
*
* @returns The CreateAssetTx fee as a {@link https://github.com/indutny/bn.js/|BN}
*/
this.getCreateAssetTxFee = () => {
var _a;
return new bn_js_1.default((_a = this.core.getNetwork().P.createAssetTxFee) !== null && _a !== void 0 ? _a : 0);
};
/**
* Gets the CreateSubnetTx fee.
*
* @returns The CreateSubnetTx fee as a {@link https://github.com/indutny/bn.js/|BN}
*/
this.getCreateSubnetTxFee = () => {
var _a;
return new bn_js_1.default((_a = this.core.getNetwork().P.createSubnetTx) !== null && _a !== void 0 ? _a : 0);
};
/**
* Gets the CreateChainTx fee.
*
* @returns The CreateChainTx fee as a {@link https://github.com/indutny/bn.js/|BN}
*/
this.getCreateChainTxFee = () => {
var _a;
return new bn_js_1.default((_a = this.core.getNetwork().P.createChainTx) !== null && _a !== void 0 ? _a : 0);
};
/**
* Sets the tx fee for this chain.
*
* @param fee The tx fee amount to set as {@link https://github.com/indutny/bn.js/|BN}
*/
this.setTxFee = (fee) => {
this.txFee = fee;
};
/**
* Gets the default creation fee for this chain.
*
* @returns The default creation fee as a {@link https://github.com/indutny/bn.js/|BN}
*/
this.getDefaultCreationTxFee = () => {
return new bn_js_1.default(this.core.getNetwork().P.createAssetTxFee);
};
/**
* Gets the creation fee for this chain.
*
* @returns The creation fee as a {@link https://github.com/indutny/bn.js/|BN}
*/
this.getCreationTxFee = () => {
if (typeof this.creationTxFee === "undefined") {
this.creationTxFee = this.getDefaultCreationTxFee();
}
return this.creationTxFee;
};
/**
* Sets the creation fee for this chain.
*
* @param fee The creation fee amount to set as {@link https://github.com/indutny/bn.js/|BN}
*/
this.setCreationTxFee = (fee) => {
this.creationTxFee = fee;
};
/**
* Gets a reference to the keychain for this class.
*
* @returns The instance of [[]] for this class
*/
this.keyChain = () => this.keychain;
/**
* @ignore
*/
this.newKeyChain = () => {
// warning, overwrites the old keychain
const alias = this.getBlockchainAlias();
if (alias) {
this.keychain = new keychain_1.KeyChain(this.core.getHRP(), alias);
}
else {
this.keychain = new keychain_1.KeyChain(this.core.getHRP(), this.blockchainID);
}
return this.keychain;
};
/**
* Helper function which determines if a tx is a goose egg transaction.
*
* @param utx An UnsignedTx
*
* @returns boolean true if passes goose egg test and false if fails.
*
* @remarks
* A "Goose Egg Transaction" is when the fee far exceeds a reasonable amount
*/
this.checkGooseEgg = (utx, outTotal = common_1.ZeroBN) => __awaiter(this, void 0, void 0, function* () {
const avaxAssetID = yield this.getAVAXAssetID();
let outputTotal = outTotal.gt(common_1.ZeroBN)
? outTotal
: utx.getOutputTotal(avaxAssetID);
const fee = utx.getBurn(avaxAssetID);
if (fee.lte(constants_1.ONEAVAX.mul(new bn_js_1.default(10))) || fee.lte(outputTotal)) {
return true;
}
else {
return false;
}
});
/**
* Retrieves an assetID for a subnet"s staking assset.
*
* @returns Returns a Promise string with cb58 encoded value of the assetID.
*/
this.getStakingAssetID = () => __awaiter(this, void 0, void 0, function* () {
const response = yield this.callMethod("platform.getStakingAssetID");
return response.data.result.assetID;
});
/**
* Creates a new blockchain.
*
* @param username The username of the Keystore user that controls the new account
* @param password The password of the Keystore user that controls the new account
* @param subnetID Optional. Either a {@link https://github.com/feross/buffer|Buffer} or an cb58 serialized string for the SubnetID or its alias.
* @param vmID The ID of the Virtual Machine the blockchain runs. Can also be an alias of the Virtual Machine.
* @param fxIDs The ids of the FXs the VM is running.
* @param name A human-readable name for the new blockchain
* @param genesis The base 58 (with checksum) representation of the genesis state of the new blockchain. Virtual Machines should have a static API method named buildGenesis that can be used to generate genesisData.
*
* @returns Promise for the unsigned transaction to create this blockchain. Must be signed by a sufficient number of the Subnet’s control keys and by the account paying the transaction fee.
*/
this.createBlockchain = (username, password, subnetID = undefined, vmID, fxIDs, name, genesis) => __awaiter(this, void 0, void 0, function* () {
const params = {
username,
password,
fxIDs,
vmID,
name,
genesisData: genesis
};
if (typeof subnetID === "string") {
params.subnetID = subnetID;
}
else if (typeof subnetID !== "undefined") {
params.subnetID = bintools.cb58Encode(subnetID);
}
const response = yield this.callMethod("platform.createBlockchain", params);
return response.data.result.txID;
});
/**
* Gets the status of a blockchain.
*
* @param blockchainID The blockchainID requesting a status update
*
* @returns Promise for a string of one of: "Validating", "Created", "Preferred", "Unknown".
*/
this.getBlockchainStatus = (blockchainID) => __awaiter(this, void 0, void 0, function* () {
const params = {
blockchainID
};
const response = yield this.callMethod("platform.getBlockchainStatus", params);
return response.data.result.status;
});
/**
* Get the validators and their weights of a subnet or the Primary Network at a given P-Chain height.
*
* @param height The P-Chain height to get the validator set at.
* @param subnetID Optional. A cb58 serialized string for the SubnetID or its alias.
*
* @returns Promise GetValidatorsAtResponse
*/
this.getValidatorsAt = (height, subnetID) => __awaiter(this, void 0, void 0, function* () {
const params = {
height
};
if (typeof subnetID !== "undefined") {
params.subnetID = subnetID;
}
const response = yield this.callMethod("platform.getValidatorsAt", params);
return response.data.result;
});
/**
* Gets the block at given height
* @param height The P-Chain height to get the block at.
* @param encoding
*
* @returns Promise GetBlockResponse
*/
this.getBlockByHeight = (height, encoding) => __awaiter(this, void 0, void 0, function* () {
const params = {
height,
encoding
};
const response = yield this.callMethod("platform.getBlockByHeight", params);
return response.data.result;
});
/**
* Create an address in the node's keystore.
*
* @param username The username of the Keystore user that controls the new account
* @param password The password of the Keystore user that controls the new account
*
* @returns Promise for a string of the newly created account address.
*/
this.createAddress = (username, password) => __awaiter(this, void 0, void 0, function* () {
const params = {
username,
password
};
const response = yield this.callMethod("platform.createAddress", params);
return response.data.result.address;
});
/**
* Gets the balance of a particular asset.
*
* @param addresses The addresses to pull the asset balance from
*
* @returns Promise with the balance as a {@link https://github.com/indutny/bn.js/|BN} on the provided address.
*/
this.getBalance = (addresses) => __awaiter(this, void 0, void 0, function* () {
addresses.forEach((address) => {
if (typeof this.parseAddress(address) === "undefined") {
/* istanbul ignore next */
throw new errors_2.AddressError("Error - PlatformVMAPI.getBalance: Invalid address format");
}
});
const params = {
addresses
};
const response = yield this.callMethod("platform.getBalance", params);
const result = response.data.result;
const parseDict = (input) => {
let dict = {};
for (const [k, v] of Object.entries(input))
dict[k] = new bn_js_1.default(v);
return dict;
};
if (this.core.getNetwork().P.lockModeBondDeposit) {
return {
balances: parseDict(result.balances),
unlockedOutputs: parseDict(result.unlockedOutputs),
bondedOutputs: parseDict(result.bondedOutputs),
depositedOutputs: parseDict(result.depositedOutputs),
bondedDepositedOutputs: parseDict(result.bondedDepositedOutputs),
utxoIDs: result.utxoIDs
};
}
return {
balance: new bn_js_1.default(result.balance),
unlocked: new bn_js_1.default(result.unlocked),
lockedStakeable: new bn_js_1.default(result.lockedStakeable),
lockedNotStakeable: new bn_js_1.default(result.lockedNotStakeable),
utxoIDs: result.utxoIDs
};
});
/**
* List the addresses controlled by the user.
*
* @param username The username of the Keystore user
* @param password The password of the Keystore user
*
* @returns Promise for an array of addresses.
*/
this.listAddresses = (username, password) => __awaiter(this, void 0, void 0, function* () {
const params = {
username,
password
};
const response = yield this.callMethod("platform.listAddresses", params);
return response.data.result.addresses;
});
/**
* Lists the set of current validators.
*
* @param subnetID Optional. Either a {@link https://github.com/feross/buffer|Buffer} or an
* cb58 serialized string for the SubnetID or its alias.
* @param nodeIDs Optional. An array of strings
*
* @returns Promise for an array of validators that are currently staking, see: {@link https://docs.avax.network/v1.0/en/api/platform/#platformgetcurrentvalidators|platform.getCurrentValidators documentation}.
*
*/
this.getCurrentValidators = (subnetID = undefined, nodeIDs = undefined) => __awaiter(this, void 0, void 0, function* () {
const params = {};
if (typeof subnetID === "string") {
params.subnetID = subnetID;
}
else if (typeof subnetID !== "undefined") {
params.subnetID = bintools.cb58Encode(subnetID);
}
if (typeof nodeIDs != "undefined" && nodeIDs.length > 0) {
params.nodeIDs = nodeIDs;
}
const response = yield this.callMethod("platform.getCurrentValidators", params);
return response.data.result;
});
/**
* A request that in address field accepts either a nodeID (and returns a bech32 address if it exists), or a bech32 address (and returns a NodeID if it exists).
*
* @param address A nodeID or a bech32 address
*
* @returns Promise for a string containing bech32 address that is the node owner or nodeID that the address passed is an owner of.
*/
this.getRegisteredShortIDLink = (address) => __awaiter(this, void 0, void 0, function* () {
const params = {
address
};
const response = yield this.callMethod("platform.getRegisteredShortIDLink", params);
return response.data.result.address;
});
/**
* Returns active or inactive deposit offers.
*
* @param active A boolean indicating whether to return active or inactive deposit offers.
*
* @returns Promise for a list containing deposit offers.
*/
this.getAllDepositOffers = (timestamp) => __awaiter(this, void 0, void 0, function* () {
if (!timestamp)
timestamp = Math.floor(Date.now() / 1000);
const params = {
timestamp
};
const response = yield this.callMethod("platform.getAllDepositOffers", params);
const offers = response.data.result;
if (!offers.depositOffers)
return [];
return offers.depositOffers.map((offer) => {
return {
upgradeVersion: offer.upgradeVersion,
id: offer.id,
interestRateNominator: new bn_js_1.default(offer.interestRateNominator),
start: new bn_js_1.default(offer.start),
end: new bn_js_1.default(offer.end),
minAmount: new bn_js_1.default(offer.minAmount),
totalMaxAmount: new bn_js_1.default(offer.totalMaxAmount),
depositedAmount: new bn_js_1.default(offer.depositedAmount),
minDuration: offer.minDuration,
maxDuration: offer.maxDuration,
unlockPeriodDuration: offer.unlockPeriodDuration,
noRewardsPeriodDuration: offer.noRewardsPeriodDuration,
memo: offer.memo,
flags: new bn_js_1.default(offer.flags),
totalMaxRewardAmount: new bn_js_1.default(offer.totalMaxRewardAmount),
rewardedAmount: new bn_js_1.default(offer.rewardedAmount),
ownerAddress: offer.ownerAddress
};
});
});
/**
* Returns deposits corresponding to requested txIDs.
*
* @param depositTxIDs A list of txIDs (cb58) to request deposits for.
*
* @returns Promise for a GetDepositsResponse object.
*/
this.getDeposits = (depositTxIDs) => __awaiter(this, void 0, void 0, function* () {
const params = {
depositTxIDs
};
const response = yield this.callMethod("platform.getDeposits", params);
const deposits = response.data.result;
if (!deposits.deposits)
return { deposits: [], availableRewards: [], timestamp: common_1.ZeroBN };
return {
deposits: deposits.deposits.map((deposit) => {
return {
depositTxID: deposit.depositTxID,
depositOfferID: deposit.depositOfferID,
unlockedAmount: new bn_js_1.default(deposit.unlockedAmount),
unlockableAmount: new bn_js_1.default(deposit.unlockableAmount),
claimedRewardAmount: new bn_js_1.default(deposit.claimedRewardAmount),
start: new bn_js_1.default(deposit.start),
duration: deposit.duration,
amount: new bn_js_1.default(deposit.amount),
rewardOwner: {
locktime: new bn_js_1.default(deposit.rewardOwner.locktime),
threshold: new bn_js_1.default(deposit.rewardOwner.threshold).toNumber(),
addresses: deposit.rewardOwner.addresses
}
};
}),
availableRewards: deposits.availableRewards.map((a) => new bn_js_1.default(a)),
timestamp: new bn_js_1.default(deposits.timestamp)
};
});
/**
* List amounts that can be claimed: validator rewards, expired deposit rewards claimable at current time.
*
* @param owners RewardOwner of DepositTx or AddValidatorTx
*
* @returns Promise for an object containing the amounts that can be claimed.
*/
this.getClaimables = (owners) => __awaiter(this, void 0, void 0, function* () {
const params = {
Owners: owners
};
const response = yield this.callMethod("platform.getClaimables", params);
const result = response.data.result;
return {
claimables: result.claimables.map((c) => {
return {
rewardOwner: c.rewardOwner
? {
locktime: new bn_js_1.default(c.rewardOwner.locktime),
threshold: new bn_js_1.default(c.rewardOwner.threshold).toNumber(),
addresses: c.rewardOwner.addresses
}
: undefined,
validatorRewards: new bn_js_1.default(c.validatorRewards),
expiredDepositRewards: new bn_js_1.default(c.expiredDepositRewards)
};
})
};
});
/**
* Lists the set of pending validators.
*
* @param subnetID Optional. Either a {@link https://github.com/feross/buffer|Buffer}
* or a cb58 serialized string for the SubnetID or its alias.
* @param nodeIDs Optional. An array of strings
*
* @returns Promise for an array of validators that are pending staking, see: {@link https://docs.avax.network/v1.0/en/api/platform/#platformgetpendingvalidators|platform.getPendingValidators documentation}.
*
*/
this.getPendingValidators = (subnetID = undefined, nodeIDs = undefined) => __awaiter(this, void 0, void 0, function* () {
const params = {};
if (typeof subnetID === "string") {
params.subnetID = subnetID;
}
else if (typeof subnetID !== "undefined") {
params.subnetID = bintools.cb58Encode(subnetID);
}
if (typeof nodeIDs != "undefined" && nodeIDs.length > 0) {
params.nodeIDs = nodeIDs;
}
const response = yield this.callMethod("platform.getPendingValidators", params);
return response.data.result;
});
/**
* Retrieves the current phases.
*
* @returns Returns a Promise of a UpgradePhasesReply.
*/
this.getUpgradePhases = () => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
const response = yield this.callMethod("platform.getUpgradePhases");
return {
SunrisePhase: parseInt((_a = response.data.result) === null || _a === void 0 ? void 0 : _a.sunrisePhase),
AthensPhase: parseInt((_b = response.data.result) === null || _b === void 0 ? void 0 : _b.athensPhase),
BerlinPhase: parseInt((_c = response.data.result) === null || _c === void 0 ? void 0 : _c.berlinPhase),
CairoPhase: parseInt((_d = response.data.result) === null || _d === void 0 ? void 0 : _d.cairoPhase)
};
});
/**
* Samples `Size` validators from the current validator set.
*
* @param sampleSize Of the total universe of validators, select this many at random
* @param subnetID Optional. Either a {@link https://github.com/feross/buffer|Buffer} or an
* cb58 serialized string for the SubnetID or its alias.
*
* @returns Promise for an array of validator"s stakingIDs.
*/
this.sampleValidators = (sampleSize, subnetID = undefined) => __awaiter(this, void 0, void 0, function* () {
const params = {
size: sampleSize.toString()
};
if (typeof subnetID === "string") {
params.subnetID = subnetID;
}
else if (typeof subnetID !== "undefined") {
params.subnetID = bintools.cb58Encode(subnetID);
}
const response = yield this.callMethod("platform.sampleValidators", params);
return response.data.result.validators;
});
/**
* Add a validator to the Primary Network.
*
* @param username The username of the Keystore user
* @param password The password of the Keystore user
* @param nodeID The node ID of the validator
* @param startTime Javascript Date object for the start time to validate
* @param endTime Javascript Date object for the end time to validate
* @param stakeAmount The amount of nAVAX the validator is staking as
* a {@link https://github.com/indutny/bn.js/|BN}
* @param rewardAddress The address the validator reward will go to, if there is one.
* @param delegationFeeRate Optional. A {@link https://github.com/indutny/bn.js/|BN} for the percent fee this validator
* charges when others delegate stake to them. Up to 4 decimal places allowed additional decimal places are ignored.
* Must be between 0 and 100, inclusive. For example, if delegationFeeRate is 1.2345 and someone delegates to this
* validator, then when the delegation period is over, 1.2345% of the reward goes to the validator and the rest goes
* to the delegator.
*
* @returns Promise for a base58 string of the unsigned transaction.
*/
this.addValidator = (username, password, nodeID, startTime, endTime, stakeAmount, rewardAddress, delegationFeeRate = undefined) => __awaiter(this, void 0, void 0, function* () {
const params = {
username,
password,
nodeID,
startTime: startTime.getTime() / 1000,
endTime: endTime.getTime() / 1000,
stakeAmount: stakeAmount.toString(10),
rewardAddress
};
if (typeof delegationFeeRate !== "undefined") {
params.delegationFeeRate = delegationFeeRate.toString(10);
}
const response = yield this.callMethod("platform.addValidator", params);
return response.data.result.txID;
});
/**
* Add a validator to a Subnet other than the Primary Network. The validator must validate the Primary Network for the entire duration they validate this Subnet.
*
* @param username The username of the Keystore user
* @param password The password of the Keystore user
* @param nodeID The node ID of the validator
* @param subnetID Either a {@link https://github.com/feross/buffer|Buffer} or a cb58 serialized string for the SubnetID or its alias.
* @param startTime Javascript Date object for the start time to validate
* @param endTime Javascript Date object for the end time to validate
* @param weight The validator’s weight used for sampling
*
* @returns Promise for the unsigned transaction. It must be signed (using sign) by the proper number of the Subnet’s control keys and by the key of the account paying the transaction fee before it can be issued.
*/
this.addSubnetValidator = (username, password, nodeID, subnetID, startTime, endTime, weight) => __awaiter(this, void 0, void 0, function* () {
const params = {
username,
password,
nodeID,
startTime: startTime.getTime() / 1000,
endTime: endTime.getTime() / 1000,
weight
};
if (typeof subnetID === "string") {
params.subnetID = subnetID;
}
else if (typeof subnetID !== "undefined") {
params.subnetID = bintools.cb58Encode(subnetID);
}
const response = yield this.callMethod("platform.addSubnetValidator", params);
return response.data.result.txID;
});
/**
* Add a delegator to the Primary Network.
*
* @param username The username of the Keystore user
* @param password The password of the Keystore user
* @param nodeID The node ID of the delegatee
* @param startTime Javascript Date object for when the delegator starts delegating
* @param endTime Javascript Date object for when the delegator starts delegating
* @param stakeAmount The amount of nAVAX the delegator is staking as
* a {@link https://github.com/indutny/bn.js/|BN}
* @param rewardAddress The address of the account the staked AVAX and validation reward
* (if applicable) are sent to at endTime
*
* @returns Promise for an array of validator"s stakingIDs.
*/
this.addDelegator = (username, password, nodeID, startTime, endTime, stakeAmount, rewardAddress) => __awaiter(this, void 0, void 0, function* () {
const params = {
username,
password,
nodeID,
startTime: startTime.getTime() / 1000,
endTime: endTime.getTime() / 1000,
stakeAmount: stakeAmount.toString(10),
rewardAddress
};
const response = yield this.callMethod("platform.addDelegator", params);
return response.data.result.txID;
});
/**
* Create an unsigned transaction to create a new Subnet. The unsigned transaction must be
* signed with the key of the account paying the transaction fee. The Subnet’s ID is the ID of the transaction that creates it (ie the response from issueTx when issuing the signed transaction).
*
* @param username The username of the Keystore user
* @param password The password of the Keystore user
* @param controlKeys Array of platform addresses as strings
* @param threshold To add a validator to this Subnet, a transaction must have threshold
* signatures, where each signature is from a key whose address is an element of `controlKeys`
*
* @returns Promise for a string with the unsigned transaction encoded as base58.
*/
this.createSubnet = (username, password, controlKeys, threshold) => __awaiter(this, void 0, void 0, function* () {
const params = {
username,
password,
controlKeys,
threshold
};
const response = yield this.callMethod("platform.createSubnet", params);
return response.data.result.txID
? response.data.result.txID
: response.data.result;
});
/**
* Get the Subnet that validates a given blockchain.
*
* @param blockchainID Either a {@link https://github.com/feross/buffer|Buffer} or a cb58
* encoded string for the blockchainID or its alias.
*
* @returns Promise for a string of the subnetID that validates the blockchain.
*/
this.validatedBy = (blockchainID) => __awaiter(this, void 0, void 0, function* () {
const params = {
blockchainID
};
const response = yield this.callMethod("platform.validatedBy", params);
return response.data.result.subnetID;
});
/**
* Get the IDs of the blockchains a Subnet validates.
*
* @param subnetID Either a {@link https://github.com/feross/buffer|Buffer} or an AVAX
* serialized string for the SubnetID or its alias.
*
* @returns Promise for an array of blockchainIDs the subnet validates.
*/
this.validates = (subnetID) => __awaiter(this, void 0, void 0, function* () {
const params = {
subnetID
};
if (typeof subnetID === "string") {
params.subnetID = subnetID;
}
else if (typeof subnetID !== "undefined") {
params.subnetID = bintools.cb58Encode(subnetID);
}
const response = yield this.callMethod("platform.validates", params);
return response.data.result.blockchainIDs;
});
/**
* Get all the blockchains that exist (excluding the P-Chain).
*
* @returns Promise for an array of objects containing fields "id", "subnetID", and "vmID".
*/
this.getBlockchains = () => __awaiter(this, void 0, void 0, function* () {
const response = yield this.callMethod("platform.getBlockchains");
return response.data.result.blockchains;
});
/**
* Send AVAX from an account on the P-Chain to an address on the X-Chain. This transaction
* must be signed with the key of the account that the AVAX is sent from and which pays the
* transaction fee. After issuing this transaction, you must call the X-Chain’s importAVAX
* method to complete the transfer.
*
* @param username The Keystore user that controls the account specified in `to`
* @param password The password of the Keystore user
* @param to The address on the X-Chain to send the AVAX to. Do not include X- in the address
* @param amount Amount of AVAX to export as a {@link https://github.com/indutny/bn.js/|BN}
*
* @returns Promise for an unsigned transaction to be signed by the account the the AVAX is
* sent from and pays the transaction fee.
*/
this.exportAVAX = (username, password, amount, to) => __awaiter(this, void 0, void 0, function* () {
const params = {
username,
password,
to,
amount: amount.toString(10)
};
const response = yield this.callMethod("platform.exportAVAX", params);
return response.data.result.txID
? response.data.result.txID
: response.data.result;
});
/**
* Send AVAX from an account on the P-Chain to an address on the X-Chain. This transaction
* must be signed with the key of the account that the AVAX is sent from and which pays
* the transaction fee. After issuing this transaction, you must call the X-Chain’s
* importAVAX method to complete the transfer.
*
* @param username The Keystore user that controls the account specified in `to`
* @param password The password of the Keystore user
* @param to The ID of the account the AVAX is sent to. This must be the same as the to
* argument in the corresponding call to the X-Chain’s exportAVAX
* @param sourceChain The chainID where the funds are coming from.
*
* @returns Promise for a string for the transaction, which should be sent to the network
* by calling issueTx.
*/
this.importAVAX = (username, password, to, sourceChain) => __awaiter(this, void 0, void 0, function* () {
const params = {
to,
sourceChain,
username,
password
};
const response = yield this.callMethod("platform.importAVAX", params);
return response.data.result.txID
? response.data.result.txID
: response.data.result;
});
/**
* Calls the node's issueTx method from the API and returns the resulting transaction ID as a string.
*
* @param tx A string, {@link https://github.com/feross/buffer|Buffer}, or [[Tx]] representing a transaction
*
* @returns A Promise string representing the transaction ID of the posted transaction.
*/
this.issueTx = (tx) => __awaiter(this, void 0, void 0, function* () {
let Transaction = "";
if (typeof tx === "string") {
Transaction = tx;
}
else if (tx instanceof buffer_1.Buffer) {
const txobj = new tx_1.Tx();
txobj.fromBuffer(tx);
Transaction = txobj.toStringHex();
}
else if (tx instanceof tx_1.Tx) {
Transaction = tx.toStringHex();
}
else {
/* istanbul ignore next */
throw new errors_2.TransactionError("Error - platform.issueTx: provided tx is not expected type of string, Buffer, or Tx");
}
const params = {
tx: Transaction.toString(),
encoding: "hex"
};
const response = yield this.callMethod("platform.issueTx", params);
return response.data.result.txID;
});
/**
* Returns an upper bound on the amount of tokens that exist along with the P-chain height. Not monotonically increasing because this number can go down if a staker"s reward is denied.
*/
this.getCurrentSupply = () => __awaiter(this, void 0, void 0, function* () {
const response = yield this.callMethod("platform.getCurrentSupply");
return {
supply: new bn_js_1.default(response.data.result.supply, 10),
height: new bn_js_1.default(response.data.result.height, 10)
};
});
/**
* Returns the height of the platform chain.
*/
this.getHeight = () => __awaiter(this, void 0, void 0, function* () {
const response = yield this.callMethod("platform.getHeight");
return new bn_js_1.default(response.data.result.height, 10);
});
/**
* Gets the minimum staking amount.
*
* @param refresh A boolean to bypass the local cached value of Minimum Stake Amount, polling the node instead.
*/
this.getMinStake = (refresh = false) => __awaiter(this, void 0, void 0, function* () {
if (refresh !== true &&
typeof this.minValidatorStake !== "undefined" &&
typeof this.minDelegatorStake !== "undefined") {
return {
minValidatorStake: this.minValidatorStake,
minDelegatorStake: this.minDelegatorStake
};
}
const response = yield this.callMethod("platform.getMinStake");
this.minValidatorStake = new bn_js_1.default(response.data.result.minValidatorStake, 10);
this.minDelegatorStake = new bn_js_1.default(response.data.result.minDelegatorStake, 10);
return {
minValidatorStake: this.minValidatorStake,
minDelegatorStake: this.minDelegatorStake
};
});
/**
* getTotalStake() returns the total amount staked on the Primary Network
*
* @returns A big number representing total staked by validators on the primary network
*/
this.getTotalStake = () => __awaiter(this, void 0, void 0, function* () {
const response = yield this.callMethod("platform.getTotalStake");
return new bn_js_1.default(response.data.result.stake, 10);
});
/**
* getMaxStakeAmount() returns the maximum amount of nAVAX staking to the named node during the time period.
*
* @param subnetID A Buffer or cb58 string representing subnet
* @param nodeID A string representing ID of the node whose stake amount is required during the given duration
* @param startTime A big number denoting start time of the duration during which stake amount of the node is required.
* @param endTime A big number denoting end time of the duration during which stake amount of the node is required.
* @returns A big number representing total staked by validators on the primary network
*/
this.getMaxStakeAmount = (subnetID, nodeID, startTime, endTime) => __awaiter(this, void 0, void 0, function* () {
const now = (0, helperfunctions_1.UnixNow)();
if (startTime.gt(now) || endTime.lte(startTime)) {
throw new errors_2.TimeError("PlatformVMAPI.getMaxStakeAmount -- startTime must be in the past and endTime must come after startTime");
}
const params = {
nodeID: nodeID,
startTime: startTime.toString(10),
endTime: endTime.toString(10)
};
if (typeof subnetID === "string") {
params.subnetID = subnetID;
}
else if (typeof subnetID !== "undefined") {
params.subnetID = bintools.cb58Encode(subnetID);
}
const response = yield this.callMethod("platform.getMaxStakeAmount", params);
return new bn_js_1.default(response.data.result.amount, 10);
});
/**
* Sets the minimum stake cached in this class.
* @param minValidatorStake A {@link https://github.com/indutny/bn.js/|BN} to set the minimum stake amount cached in this class.
* @param minDelegatorStake A {@link https://github.com/indutny/bn.js/|BN} to set the minimum delegation amount cached in this class.
*/
this.setMinStake = (minValidatorStake = undefined, minDelegatorStake = undefined) => {
if (typeof minValidatorStake !== "undefined") {
this.minValidatorStake = minValidatorStake;
}
if (typeof minDelegatorStake !== "undefined") {
this.minDelegatorStake = minDelegatorStake;
}
};
/**
* Gets the total amount staked for an array of addresses.
*/
this.getStake = (addresses, encoding = "hex") => __awaiter(this, void 0, void 0, function* () {
const params = {
addresses,
encoding
};
const response = yield this.callMethod("platform.getStake", params);
return {
staked: new bn_js_1.default(response.data.result.staked, 10),
stakedOutputs: response.data.result.stakedOutputs.map((stakedOutput) => {
const transferableOutput = new outputs_1.TransferableOutput();
let buf;
if (encoding === "cb58") {
buf = bintools.cb58Decode(stakedOutput);
}
else {
buf = buffer_1.Buffer.from(stakedOutput.replace(/0x/g, ""), "hex");
}
transferableOutput.fromBuffer(buf, 2);
return transferableOutput;
})
};
});
/**
* Get all the subnets that exist.
*
* @param ids IDs of the subnets to retrieve information about. If omitted, gets all subnets
*
* @returns Promise for an array of objects containing fields "id",
* "controlKeys", and "threshold".
*/
this.getSubnets = (ids = undefined) => __awaiter(this, void 0, void 0, function* () {
const params = {};
if (typeof ids !== undefined) {
params.ids = ids;
}
const response = yield this.callMethod("platform.getSubnets", params);
return response.data.result.subnets;
});
/**
* Exports the private key for an address.
*
* @param username The name of the user with the private key
* @param password The password used to decrypt the private key
* @param address The address whose private key should be exported
*
* @returns Promise with the decrypted private key as store in the database
*/
this.exportKey = (username, password, address) => __awa