Some checks failed
morphit-release / Build + publish release tarball (push) Has been cancelled
371 lines
15 KiB
JavaScript
371 lines
15 KiB
JavaScript
"use strict";
|
|
/**
|
|
* @file Blurt Condenser API helpers.
|
|
* @author BeBlurt <https://beblurt.com/@beblurt>
|
|
* @description adaptation from Johan Nordberg <code@johan-nordberg.com> Database API helpers.
|
|
* @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.CondenserAPI = void 0;
|
|
const authority_1 = require("../authority");
|
|
class CondenserAPI {
|
|
constructor(client) {
|
|
this.client = client;
|
|
}
|
|
/** Convenience for calling `condenser_api`. */
|
|
call(method, params) {
|
|
return this.client.call('condenser_api', method, params);
|
|
}
|
|
/**
|
|
* Returns one or more account history objects for account operations
|
|
*
|
|
* @param account The account to fetch
|
|
* @param from The starting index
|
|
* @param limit The maximum number of results to return
|
|
* @param operation_bitmask Generated by utils.makeBitMaskFilter() - see example below (not yet usable)
|
|
* @example
|
|
* ```typescript
|
|
* import { utils } from "@beblurt/dblurt"
|
|
* const op = dblurt.utils.operationOrders
|
|
* const operationsBitmask = dblurt.utils.makeBitMaskFilter([
|
|
* op.vote,
|
|
* op.comment,
|
|
* op.delete_comment,
|
|
* op.comment_options,
|
|
* op.claim_reward_balance,
|
|
* op.author_reward,
|
|
* op.curation_reward,
|
|
* op.comment_reward,
|
|
* op.producer_reward,
|
|
* ])
|
|
* const accountHistory = await client.condenser.getAccountHistory('beblurt', -1, 10, operationsBitmask)
|
|
* ```
|
|
*/
|
|
getAccountHistory(account, from, limit, operation_bitmask) {
|
|
// const params = [account, from, limit]
|
|
// Future usage when filter will be availabe
|
|
let params = [account, from, limit];
|
|
if (operation_bitmask && Array.isArray(operation_bitmask)) {
|
|
if (operation_bitmask.length !== 2) {
|
|
throw Error('operation_bitmask should be generated by the helper function');
|
|
}
|
|
else {
|
|
params = operation_bitmask[1] ? [...params, operation_bitmask[0], operation_bitmask[1]] : [...params, operation_bitmask[0]];
|
|
}
|
|
}
|
|
return this.call('get_account_history', params);
|
|
}
|
|
/**
|
|
* Return Layer 1 account state for one or more account names.
|
|
*
|
|
* Backing JSON-RPC method: `condenser_api.get_accounts`.
|
|
*
|
|
* Use this when exact account balances, authorities or chain state matter.
|
|
* For Nexus profile metadata, use `client.nexus.getProfile` instead.
|
|
*
|
|
* @param usernames Account names to fetch.
|
|
* @returns Account objects in the same order as requested names when found.
|
|
* @example
|
|
* ```js
|
|
* const accounts = await client.condenser.getAccounts(['beblurt']);
|
|
* ```
|
|
*/
|
|
getAccounts(usernames) {
|
|
return this.call('get_accounts', [usernames]);
|
|
}
|
|
/**
|
|
* Validate whether a public/private key satisfies an account's Layer 1 posting authority.
|
|
*
|
|
* This helper reads the account through `condenser_api.get_accounts`, follows
|
|
* delegated account authorities through their posting authorities, and returns
|
|
* an explanatory result without broadcasting or signing anything.
|
|
*/
|
|
async validatePostingAuthority(accountName, key) {
|
|
const accounts = new Map();
|
|
const fetched = new Set();
|
|
const fetchAccount = async (name) => {
|
|
const existing = accounts.get(name);
|
|
if (existing) {
|
|
return existing;
|
|
}
|
|
if (fetched.has(name)) {
|
|
throw new Error(`account not found: ${name}`);
|
|
}
|
|
fetched.add(name);
|
|
const [account] = await this.getAccounts([name]);
|
|
if (!account || account.name !== name) {
|
|
throw new Error(`account not found: ${name}`);
|
|
}
|
|
accounts.set(name, account);
|
|
return account;
|
|
};
|
|
const root = await fetchAccount(accountName);
|
|
const queue = [accountName];
|
|
let index = 0;
|
|
while (index < queue.length) {
|
|
const current = await fetchAccount(queue[index]);
|
|
index++;
|
|
for (const auth of [current.owner, current.active, current.posting]) {
|
|
for (const [delegated] of auth.account_auths || []) {
|
|
if (!accounts.has(delegated) && !queue.includes(delegated)) {
|
|
queue.push(delegated);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return (0, authority_1.validatePostingAuthority)(root, key, {
|
|
getAccount: name => accounts.get(name)
|
|
});
|
|
}
|
|
/**
|
|
* Return active Layer 1 votes for a post or comment.
|
|
*
|
|
* Backing JSON-RPC method: `condenser_api.get_active_votes`.
|
|
*
|
|
* @param author Post/comment author.
|
|
* @param permlink Post/comment permlink.
|
|
* @returns Active vote entries known by the RPC node.
|
|
* @example
|
|
* ```js
|
|
* const votes = await client.condenser.getActiveVotes(author, permlink);
|
|
* ```
|
|
*/
|
|
async getActiveVotes(author, permlink) {
|
|
return this.call('get_active_votes', [author, permlink]);
|
|
}
|
|
/** Returns the list of active witnesses */
|
|
async getActiveWitnesses() {
|
|
return this.call('get_active_witnesses', []);
|
|
}
|
|
/** Return block *blockNum*. */
|
|
getBlock(blockNum) {
|
|
return this.call('get_block', [blockNum]);
|
|
}
|
|
/** Return header for *blockNum*. */
|
|
getBlockHeader(blockNum) {
|
|
return this.call('get_block_header', [blockNum]);
|
|
}
|
|
/** Returns a list of blog entries for an account. */
|
|
getBlogEntries(account, start_entry_id, limit) {
|
|
return this.call('get_blog_entries', [account, start_entry_id, limit]);
|
|
}
|
|
/** Return median chain properties decided by witness. */
|
|
async getChainProperties() {
|
|
return this.call('get_chain_properties');
|
|
}
|
|
/** Return server config. See:
|
|
* https://gitlab.com/blurt/blurt/-/blob/master/libraries/protocol/include/blurt/protocol/config.hpp
|
|
*/
|
|
getConfig() {
|
|
return this.call('get_config', []);
|
|
}
|
|
/**
|
|
* Return a Layer 1 content object for a post or comment.
|
|
*
|
|
* Backing JSON-RPC method: `condenser_api.get_content`.
|
|
*
|
|
* This reads the chain content object. If you need social/indexed ranking,
|
|
* discovery or community context, use Nexus helpers first and then read the
|
|
* Layer 1 object with this method when exact chain content matters.
|
|
*
|
|
* @param author Post/comment author.
|
|
* @param permlink Post/comment permlink.
|
|
* @returns The content object returned by the RPC node.
|
|
*/
|
|
getContent(author, permlink) {
|
|
return this.call('get_content', [author, permlink]);
|
|
}
|
|
/** Returns a list of replies. */
|
|
getContentReplies(author, permlink) {
|
|
return this.call('get_content_replies', [author, permlink]);
|
|
}
|
|
/**
|
|
* Return current Layer 1 dynamic global properties.
|
|
*
|
|
* Backing JSON-RPC method: `condenser_api.get_dynamic_global_properties`.
|
|
*
|
|
* This is the usual source for head block number, last irreversible block,
|
|
* time and other current chain-level values.
|
|
*/
|
|
getDynamicGlobalProperties() {
|
|
return this.call('get_dynamic_global_properties');
|
|
}
|
|
/**
|
|
* Return array of discussions (a.k.a. posts).
|
|
* @param by The type of sorting for the discussions, valid options are:
|
|
* `active` `blog` `cashout` `children` `comments` `created`
|
|
* `feed` `hot` `promoted` `trending` `votes`. Note that
|
|
* for `blog` and `feed` the tag is set to a username.
|
|
*/
|
|
getDiscussions(by, query) {
|
|
return this.call(`get_discussions_by_${by}`, [query]);
|
|
}
|
|
/** return the count of followers/following for an account */
|
|
async getFollowCount(accounts) {
|
|
return this.call('get_follow_count', accounts);
|
|
}
|
|
/** return the list of the followers of an account */
|
|
async getFollowers(account, start, type, limit) {
|
|
return this.call('get_followers', [account, start, type, limit]);
|
|
}
|
|
/** return the list of accounts that are following an account */
|
|
async getFollowing(account, start, type, limit) {
|
|
return this.call('get_following', [account, start, type, limit]);
|
|
}
|
|
/** Returns the list of accounts that are reblogged a content (post). */
|
|
getRebloggedBy(author, permlink) {
|
|
return this.call('get_reblogged_by', [author, permlink]);
|
|
}
|
|
/**
|
|
* Return applied operations in a Layer 1 block.
|
|
*
|
|
* Backing JSON-RPC method: `condenser_api.get_ops_in_block`.
|
|
*
|
|
* Operation order is the order reported by the node for that block. Use an
|
|
* irreversible block number when building examples or replay tools that must
|
|
* avoid reversible chain state.
|
|
*
|
|
* @param blockNum Block number to inspect.
|
|
* @param onlyVirtual When true, return only virtual operations.
|
|
* @returns Applied operations for the requested block.
|
|
* @example
|
|
* ```js
|
|
* const operations = await client.condenser.getOperations(blockNum, false);
|
|
* ```
|
|
*/
|
|
getOperations(blockNum, onlyVirtual = false) {
|
|
return this.call('get_ops_in_block', [blockNum, onlyVirtual]);
|
|
}
|
|
/**
|
|
* Returns an array of proposals filtered by the specified parameters.
|
|
* @param start - Depends on order (see below)
|
|
* - creator - creator of the proposal (account name string)
|
|
* - start_date - start date of the proposal (date string)
|
|
* - end_date - end date of the proposal (date string)
|
|
* - total_votes - total votes of the proposal (int)
|
|
* @param limit - The maximum number of proposals to return (max 1000).
|
|
* @param order - can be one of:
|
|
* - by_creator - order by proposal creator
|
|
* - by_start_date - order by proposal start date
|
|
* - by_end_date - order by proposal end date
|
|
* - by_total_votes - order by proposal total votes
|
|
* @param order_direction - The direction in which to order the results. Can be ascending or descending
|
|
* @param status - The status of proposals to return.
|
|
* @returns A Promise that resolves to an array of Proposal objects.
|
|
*/
|
|
getProposals(start, limit, order, order_direction, status) {
|
|
return this.call('list_proposals', [start, limit, order, order_direction, status]);
|
|
}
|
|
/**
|
|
* Returns all proposal votes, starting with the specified voter or proposal.id.
|
|
* @param start - Depends on order (see below)
|
|
* - voter - voter of the proposal (account name string)
|
|
* - proposal.id - id the proposal (int)
|
|
* @param limit - The maximum number of proposals to return (max 1000).
|
|
* @param order - can be one of:
|
|
* - by_voter_proposal - order by proposal voter
|
|
* - by_proposal_voter - order by proposal.id
|
|
* @param order_direction - The direction in which to order the results. Can be ascending or descending
|
|
* @param status - The status of proposals to return.
|
|
* @returns A Promise that resolves to an array of ProposalVote objects.
|
|
*/
|
|
getProposalVotes(start, limit, order, order_direction, status) {
|
|
return this.call('list_proposal_votes', [start, limit, order, order_direction, status]);
|
|
}
|
|
/** Returns information about the current reward funds */
|
|
async getRewardFund(fund) {
|
|
return this.call('get_reward_fund', [fund]);
|
|
}
|
|
/**
|
|
* Return all of the state required for a particular url path.
|
|
* @param path Path component of url conforming to condenser's scheme
|
|
* e.g. `@beblurt` or `trending/travel`
|
|
*/
|
|
async getState(path) {
|
|
return this.call('get_state', [path]);
|
|
}
|
|
/** Returns the details of a transaction based on a transaction id. */
|
|
async getTransaction(txId) {
|
|
return this.call('get_transaction', [txId]);
|
|
}
|
|
/** return rpc node version */
|
|
async getVersion() {
|
|
return this.call('get_version', []);
|
|
}
|
|
/**
|
|
* Get list of delegations made by account.
|
|
* @param account Account delegating
|
|
* @param from Delegatee start offset, used for paging.
|
|
* @param limit Number of results, max 1000.
|
|
*/
|
|
async getVestingDelegations(account, from = '', limit = 1000) {
|
|
return this.call('get_vesting_delegations', [account, from, limit]);
|
|
}
|
|
/** Returns the current witness schedule */
|
|
async getWitnessSchedule() {
|
|
return this.call('get_witness_schedule', []);
|
|
}
|
|
/**
|
|
* Return Layer 1 witness information for an account.
|
|
*
|
|
* Backing JSON-RPC method: `condenser_api.get_witness_by_account`.
|
|
*
|
|
* Not every account is a witness. Use `getActiveWitnesses` or
|
|
* `getWitnessesByVote` when you need to discover witness accounts first.
|
|
*
|
|
* @param account Witness account name.
|
|
*/
|
|
async getWitnessByAccount(account) {
|
|
return this.call('get_witness_by_account', [account]);
|
|
}
|
|
/** Returns list of witnesses by vote */
|
|
async getWitnessesByVote(account, limit) {
|
|
return this.call('get_witnesses_by_vote', [account, limit]);
|
|
}
|
|
/** Returns the current number of witnesses */
|
|
async getWitnessesCount() {
|
|
return this.call('get_witness_count', []);
|
|
}
|
|
/** Looks up accounts starting with name */
|
|
async lookupAccounts(account, limit) {
|
|
return this.call('lookup_accounts', [account, limit]);
|
|
}
|
|
/** Looks up accounts starting with name */
|
|
async lookupWitnessAccounts(account, limit) {
|
|
return this.call('lookup_witness_accounts', [account, limit]);
|
|
}
|
|
/** Verify signed transaction. */
|
|
async verifyAuthority(stx) {
|
|
return this.call('verify_authority', [stx]);
|
|
}
|
|
}
|
|
exports.CondenserAPI = CondenserAPI;
|