@pixagram/dpixa
v1.5.4
Published
Pixa blockchain RPC client library
Maintainers
Readme
dpixa
Robust pixa client library that runs in both node.js and the browser.
Needs test net urls, chain id
note As of version 0.7.0 WebSocket support has been removed. The only transport provided now is HTTP(2). For most users the only change required is to swap wss:// to https:// in the address. If you run your own full node make sure to set the proper CORS headers if you plan to access it from a browser.
Browser compatibility
Installation
Via npm
For node.js or the browser with browserify or webpack.
npm install @pixagram/dpixaBundling
The easiest way to bundle dpixa (with browserify, webpack etc.) is to just npm install @pixagram/dpixa and require('@pixagram/dpixa') which will give you well-tested (see browser compatibility matrix above) pre-bundled code guaranteed to JustWork™. However, that is not always desirable since it will not allow your bundler to de-duplicate any shared dependencies dpixa and your app might have.
To allow for deduplication you can require('@pixagram/dpixa/lib/index-browser'), or if you plan to provide your own polyfills: require('@pixagram/dpixa/lib/index'). See src/index-browser.ts for a list of polyfills expected.
Share and Enjoy!
client.database
.getDiscussions("trending", { tag: "writing", limit: 5 })
.then(function(discussions) {
discussions.forEach(post => {
console.log(${post.title} by @${post.author});
});
});
</script>
const client = new Client([ "https://api.pixagram.io", "https://api.hivekings.com" ]);
async function main() {
const props = await client.database.getDynamicGlobalProperties();
console.log(Current block: ${props.head_block_number});
}
main();
const client = new Client(["https://api.pixagram.io"]);
// Vote on a post const key = PrivateKey.fromLogin("username", "password", "posting");
client.broadcast
.vote(
{
voter: "username",
author: "almost-digital",
permlink: "dpixa-is-the-best",
weight: 10000
},
key
)
.then(result => {
console.log(Included in block: ${result.block_num});
});
// Basic initialization with multiple nodes for failover const client = new Client([ "https://api.pixagram.io", "https://api.hivekings.com", "https://anyx.io", "https://api.openhive.network" ]);
// With custom options const clientWithOptions = new Client(["https://api.pixagram.io"], { timeout: 30000, // Request timeout in ms (default: 60000) failoverThreshold: 3, // Retry rounds before giving up consoleOnFailover: true, // Log when failing over to another node addressPrefix: "PIX", // Network address prefix chainId: "your-chain-id" // Custom chain ID });
Option | Type | Default | Description -- | -- | -- | -- timeout | number | 60000 | Request timeout in milliseconds. Set to 0 to retry forever. failoverThreshold | number | 3 | Number of retry rounds across all URLs before failing. Set to 0 for infinite retries. consoleOnFailover | boolean | false | Log failover events to console addressPrefix | string | "PIX" | Network address prefix for key encoding chainId | string | Main chain ID | Blockchain chain ID (32-byte hex string) agent | http.Agent | https.globalAgent | Custom HTTP agent for keep-alive connections backoff | (tries: number) => number | Default backoff | Custom retry backoff function returning milliseconds
</details>
// BlockchainMode BlockchainMode.Irreversible // 0 — Only confirmed blocks (default) BlockchainMode.Latest // 1 — Head block (may be reversed on fork)
console.log(VERSION); // Library version string console.log(DEFAULT_ADDRESS_PREFIX); // "PIX" console.log(DEFAULT_CHAIN_ID); // Buffer (32 bytes) console.log(NETWORK_ID); // Buffer (network ID for WIF)
const agent = new https.Agent({ keepAlive: true, maxSockets: 10 });
const client = new Client(["https://api.pixagram.io"], { agent: agent });
for await (const op of client.blockchain.getOperations()) { const [opType, opData] = op.op;
if (opType === "comment" &&
opData.parent_author === "" && // Root post only
authors.includes(opData.author)) {
try {
await client.broadcast.vote({
voter: "mybot",
author: opData.author,
permlink: opData.permlink,
weight: weight
}, postingKey);
console.log(`Voted on @${opData.author}/${opData.permlink}`);
} catch (error) {
console.error(`Vote failed: ${error.message}`);
}
}} }
autoVoter(["favorite-author1", "favorite-author2"]);
Table of Contents
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Browser Usage](#browser-usage)
- [Node.js with ES Modules](#nodejs-with-es-modules)
- [Node.js with CommonJS](#nodejs-with-commonjs)
- [Core Concepts](#core-concepts)
- [Client](#client)
- [Creating a Client](#creating-a-client)
- [Using Testnet](#using-testnet)
- [Making Raw RPC Calls](#making-raw-rpc-calls)
- [Client Options Reference](#client-options-reference)
- [Client Properties](#client-properties)
- [Database API](#database-api) —
client.database[getDynamicGlobalProperties()](#getdynamicglobalproperties)→[DynamicGlobalProperties](#-dynamicglobalproperties-interface)[getChainProperties()](#getchainproperties)→[ChainProperties](#-chainproperties-interface)[getCurrentMedianHistoryPrice()](#getcurrentmedianhistoryprice)→[Price](#price-class)[getConfig()](#getconfig)[getState(path)](#getstatepath)[getBlockHeader(blockNum)](#getblockheaderblocknum)→[BlockHeader](#-blockheader-interface)[getBlock(blockNum)](#getblockblocknum)→[SignedBlock](#-signedblock-interface)[getOperations(blockNum, onlyVirtual?)](#getoperationsblocknum-onlyvirtual)→[AppliedOperation[]](#-appliedoperation-interface)[getAccounts(usernames)](#getaccountsusernames)→[ExtendedAccount[]](#-account-interface)[getDiscussions(by, query)](#getdiscussionsby-query)→[Discussion[]](#-discussion-interface)[getTransaction(txId)](#gettransactiontxid)→[SignedTransaction](#-transaction-interface)[getAccountHistory(account, from, limit, bitmask?)](#getaccounthistoryaccount-from-limit-operation_bitmask)→[AppliedOperation[]](#-appliedoperation-interface)[getVestingDelegations(account, from?, limit?)](#getvestingdelegationsaccount-from-limit)→[VestingDelegation[]](#-vestingdelegation-interface)[verifyAuthority(signedTransaction)](#verifyauthoritysignedtransaction)[getVersion()](#getversion)
- [Blockchain](#blockchain) —
client.blockchain[getCurrentBlockNum(mode?)](#getcurrentblocknummode)[getCurrentBlockHeader(mode?)](#getcurrentblockheadermode)→[BlockHeader](#-blockheader-interface)[getCurrentBlock(mode?)](#getcurrentblockmode)→[SignedBlock](#-signedblock-interface)[getBlockNumbers(options?)](#getblocknumbersoptions)[getBlocks(options?)](#getblocksoptions)→[SignedBlock](#-signedblock-interface)[getOperations(options?)](#getoperationsoptions)→[AppliedOperation](#-appliedoperation-interface)- [Stream Methods (Node.js)](#stream-methods-nodejs-streams)
- [Broadcast API](#broadcast-api) —
client.broadcast- [Voting on Content](#voting-on-content) →
[TransactionConfirmation](#-transaction-interface) - [Transferring Funds](#transferring-funds) →
[TransactionConfirmation](#-transaction-interface) - [Creating Posts and Comments](#creating-posts-and-comments) →
[TransactionConfirmation](#-transaction-interface) - [Custom JSON Operations](#custom-json-operations) →
[TransactionConfirmation](#-transaction-interface) - [Claiming Rewards](#claiming-rewards) →
[TransactionConfirmation](#-transaction-interface)
- [Voting on Content](#voting-on-content) →
- [Resource Credits API](#resource-credits-api) —
client.rc - [Pixamind API](#pixamind-api) —
client.pixamind[getRankedPosts(options)](#getrankedpostsoptions)→[Discussion[]](#-discussion-interface)[getAccountPosts(options)](#getaccountpostsoptions)→[Discussion[]](#-discussion-interface)[getCommunity(options)](#getcommunityoptions)→[CommunityDetail](#-communitydetail-interface)[listCommunities(options)](#listcommunitiesoptions)→[CommunityDetail[]](#-communitydetail-interface)[listAllSubscriptions(account)](#listallsubscriptionsaccount)[getAccountNotifications(options)](#getaccountnotificationsoptions)→[Notifications[]](#-notifications-interface)
- [Account By Key API](#account-by-key-api) —
client.keys
- [Client](#client)
- [Working with Assets](#working-with-assets)
- [Asset Class](#asset-class)
- [Creating Assets](#creating-assets)
- [Asset Properties & Methods](#asset-properties--methods)
- [Asset Symbols Reference](#asset-symbols-reference)
- [Price Class](#price-class)
- [Helper Functions](#helper-functions)
- [Asset Class](#asset-class)
- [Cryptography](#cryptography)
- [Private Keys](#private-keys) —
PrivateKey - [Public Keys](#public-keys) —
PublicKey - [Signatures](#signatures) —
Signature - [Memo Encryption](#memo-encryption) —
Memo - [Crypto Utilities](#crypto-utilities) —
cryptoUtils
- [Private Keys](#private-keys) —
- [Building Transactions](#building-transactions)
- [Operations Reference](#operations-reference)
- [Transfer Operations](#operations-reference)
- [Content Operations](#operations-reference)
- [Account Operations](#operations-reference)
- [Governance Operations](#operations-reference)
- [Market Operations](#operations-reference)
- [Savings Operations](#operations-reference)
- [Escrow Operations](#operations-reference)
- [Custom Operations](#operations-reference)
- [Virtual Operations (Read-Only)](#operations-reference)
- [Utilities](#utilities) —
utils[utils.operationOrders](#operation-bitmask-filter)[utils.makeBitMaskFilter(ops)](#operation-bitmask-filter)[utils.sleep(ms)](#sleep)[utils.copy(obj)](#copy-objects)[utils.iteratorStream(iterator)](#iterator-to-stream)[utils.buildWitnessUpdateOp(owner, props)](#build-witness-update)[utils.waitForEvent(emitter, event)](#wait-for-event)[utils.retryingFetch(...)](#retrying-fetch)
- [Serialization](#serialization) —
Types - [Error Handling](#error-handling)
- [Types & Interfaces](#types--interfaces)
[Account](#-account-interface)/[ExtendedAccount](#-account-interface)[AppliedOperation](#-appliedoperation-interface)Authority/AuthorityType[BlockHeader](#-blockheader-interface)/[SignedBlock](#-signedblock-interface)[ChainProperties](#-chainproperties-interface)[CommunityDetail](#-communitydetail-interface)[Discussion](#-discussion-interface)/[Comment](#-discussion-interface)[DynamicGlobalProperties](#-dynamicglobalproperties-interface)[DisqussionQuery](#-disqussionquery-interface)[HexBuffer](#-hexbuffer-class)[Notifications](#-notifications-interface)Transaction/SignedTransaction/TransactionConfirmationVestingDelegationAccountsByKey- Operation Interfaces (full list)
- Enumerations
- Constants
- Advanced Usage
Installation
Via npm
npm install @pixagram/dpixaVia yarn
yarn add @pixagram/dpixaVia CDN
<script src="https://unpkg.com/@pixagram/dpixa@latest/dist/dpixa.js"></script>Self-hosted
Download dist/dpixa.js from the repository and include it in your HTML:
<script src="dpixa.js"></script>Quick Start
Browser Usage
<script src="https://unpkg.com/@pixagram/dpixa@latest/dist/dpixa.js"></script>
<script>
const client = new dpixa.Client([
"https://api.pixagram.io",
"https://api.hivekings.com",
"https://anyx.io"
]);
client.database
.getDiscussions("trending", { tag: "writing", limit: 5 })
.then(function(discussions) {
discussions.forEach(post => {
console.log(`${post.title} by @${post.author}`);
});
});
</script>Node.js with ES Modules
import { Client } from "@pixagram/dpixa";
const client = new Client([
"https://api.pixagram.io",
"https://api.hivekings.com"
]);
async function main() {
const props = await client.database.getDynamicGlobalProperties();
console.log(`Current block: ${props.head_block_number}`);
}
main();Node.js with CommonJS
const { Client, PrivateKey } = require("@pixagram/dpixa");
const client = new Client(["https://api.pixagram.io"]);
// Vote on a post
const key = PrivateKey.fromLogin("username", "password", "posting");
client.broadcast
.vote(
{
voter: "username",
author: "almost-digital",
permlink: "dpixa-is-the-best",
weight: 10000
},
key
)
.then(result => {
console.log(`Included in block: ${result.block_num}`);
});Core Concepts
Client
The Client class is your main entry point to interact with the Pixa blockchain. It manages RPC connections, provides access to various APIs, and handles failover between multiple nodes.
Creating a Client
import { Client } from "@pixagram/dpixa";
// Basic initialization with multiple nodes for failover
const client = new Client([
"https://api.pixagram.io",
"https://api.hivekings.com",
"https://anyx.io",
"https://api.openhive.network"
]);
// With custom options
const clientWithOptions = new Client(["https://api.pixagram.io"], {
timeout: 30000, // Request timeout in ms (default: 60000)
failoverThreshold: 3, // Retry rounds before giving up
consoleOnFailover: true, // Log when failing over to another node
addressPrefix: "PIX", // Network address prefix
chainId: "your-chain-id" // Custom chain ID
});Using Testnet
// Create a client configured for testnet
const testClient = Client.testnet();Making Raw RPC Calls
// Direct RPC call to any API
const result = await client.call("database_api", "get_dynamic_global_properties", []);| Option | Type | Default | Description |
|--------|------|---------|-------------|
| timeout | number | 60000 | Request timeout in milliseconds. Set to 0 to retry forever. |
| failoverThreshold | number | 3 | Number of retry rounds across all URLs before failing. Set to 0 for infinite retries. |
| consoleOnFailover | boolean | false | Log failover events to console |
| addressPrefix | string | "PIX" | Network address prefix for key encoding |
| chainId | string | Main chain ID | Blockchain chain ID (32-byte hex string) |
| agent | http.Agent | https.globalAgent | Custom HTTP agent for keep-alive connections |
| backoff | (tries: number) => number | Default backoff | Custom retry backoff function returning milliseconds |
Client Properties
// Available API helpers
client.database // DatabaseAPI - Query blockchain state
client.broadcast // BroadcastAPI - Send transactions
client.blockchain // Blockchain - Stream blocks and operations
client.rc // RCAPI - Resource credits
client.keys // AccountByKeyAPI - Find accounts by key
client.pixamind // PixamindAPI - Community features
client.transaction // TransactionStatusAPI - Check transaction status
// Network configuration (read-only)
client.chainId // Buffer - Current chain ID
client.addressPrefix // string - Address prefix (e.g., "PIX")
client.address // string | string[] - Configured RPC addresses
client.options // ClientOptions - Current options
// Mutable
client.currentAddress // string - Currently active RPC nodeDatabase API
The DatabaseAPI provides methods to query blockchain state, retrieve accounts, blocks, and content.
getDynamicGlobalProperties()
Returns the current state of the blockchain.
Returns: Promise<DynamicGlobalProperties>
const props = await client.database.getDynamicGlobalProperties();{
id: 0,
head_block_number: 12345678,
head_block_id: "00bc614e...",
time: "2024-01-15T12:30:00",
current_witness: "witness-name",
total_pow: 514415,
num_pow_witnesses: 172,
virtual_supply: "400000000.000 PIXA",
current_supply: "380000000.000 PIXA",
current_pxs_supply: "15000000.000 PXS",
total_vesting_fund_pixa: "150000000.000 PIXA",
total_vesting_shares: "300000000000.000000 VESTS",
total_reward_fund_pixa: "800000.000 PIXA",
pending_rewarded_vesting_shares: "500000.000000 VESTS",
pending_rewarded_vesting_pixa: "250.000 PIXA",
pxs_interest_rate: 1000, // 10% APR
pxs_print_rate: 10000,
maximum_block_size: 65536,
current_aslot: 12500000,
recent_slots_filled: "340282366920938463463374607431768211455",
participation_count: 128,
last_irreversible_block_num: 12345660,
vote_power_reserve_rate: 10,
current_reserve_ratio: 200000000
}Use Cases:
- Check current block height
- Calculate VESTS to PIXA conversion
- Monitor network participation
- Get current witness schedule
// Practical example: Calculate PIXA Power from VESTS
const props = await client.database.getDynamicGlobalProperties();
const totalVestingFund = Asset.fromString(props.total_vesting_fund_pixa);
const totalVestingShares = Asset.fromString(props.total_vesting_shares);
function vestsToPixa(vests) {
return (vests * totalVestingFund.amount) / totalVestingShares.amount;
}
console.log(`1M VESTS = ${vestsToPixa(1000000).toFixed(3)} PIXA`);getChainProperties()
Returns the median chain properties as voted by witnesses.
Returns: Promise<ChainProperties>
const chainProps = await client.database.getChainProperties();{
account_creation_fee: "3.000 PIXA",
maximum_block_size: 65536,
pxs_interest_rate: 1000 // 10% APR (basis points)
}Use Cases:
- Check minimum account creation fee
- Get current interest rate on PXS
// Calculate actual account creation fee (30x the base fee)
const props = await client.database.getChainProperties();
const baseFee = Asset.fromString(props.account_creation_fee);
const actualFee = baseFee.multiply(30);
console.log(`Account creation costs: ${actualFee}`); // "90.000 PIXA"getCurrentMedianHistoryPrice()
Returns the median PIXA/PXS price feed as reported by witnesses.
Returns: Promise<Price>
const price = await client.database.getCurrentMedianHistoryPrice();{
base: "0.500 PXS",
quote: "1.000 PIXA"
}
// This means 1 PIXA = 0.5 PXSUse Cases:
- Calculate USD value of PIXA (PXS is pegged to USD)
- Estimate post payouts
const price = await client.database.getCurrentMedianHistoryPrice();
const priceObj = Price.from(price);
// Convert PIXA to PXS value
const pixaAmount = Asset.fromString("100.000 PIXA");
const pxsValue = priceObj.convert(pixaAmount);
console.log(`100 PIXA ≈ ${pxsValue}`); // "50.000 PXS"getConfig()
Returns the compile-time configuration of the node.
Returns: Promise<{[name: string]: string | number | boolean}>
const config = await client.database.getConfig();{
IS_TEST_NET: false,
PIXA_BLOCKCHAIN_HARDFORK_VERSION: "1.27.0",
PIXA_BLOCK_INTERVAL: 3,
PIXA_BLOCKS_PER_DAY: 28800,
PIXA_BLOCKS_PER_YEAR: 10512000,
PIXA_CASHOUT_WINDOW_SECONDS: 604800,
PIXA_CREATE_ACCOUNT_WITH_PIXA_MODIFIER: 30,
PIXA_MAX_ACCOUNT_NAME_LENGTH: 16,
PIXA_MAX_MEMO_SIZE: 2048,
PIXA_MIN_ACCOUNT_NAME_LENGTH: 3,
PIXA_SAVINGS_WITHDRAW_TIME: 259200,
PIXA_VESTING_WITHDRAW_INTERVALS: 13,
PIXA_VOTE_DUST_THRESHOLD: 50000000
// ... many more
}getState(path)
Returns the complete state for a URL path (legacy, use specific methods when possible).
Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| path | string | URL path like @username or trending/tag |
Returns: Promise<any>
// Get state for a user profile
const state = await client.database.getState("@alice");
// Get state for a tag
const tagState = await client.database.getState("trending/photography");getBlockHeader(blockNum)
Returns the header of a specific block (without transactions).
Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| blockNum | number | Block number to fetch |
Returns: Promise<BlockHeader>
const header = await client.database.getBlockHeader(12345678);{
previous: "00bc614d...",
timestamp: "2024-01-15T12:30:00",
witness: "witness-name",
transaction_merkle_root: "0000000000000000000000000000000000000000",
extensions: []
}getBlock(blockNum)
Returns a complete block including all transactions.
Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| blockNum | number | Block number to fetch |
Returns: Promise<SignedBlock>
const block = await client.database.getBlock(12345678);{
previous: "00bc614d...",
timestamp: "2024-01-15T12:30:00",
witness: "witness-name",
transaction_merkle_root: "abc123...",
extensions: [],
witness_signature: "1f4a2b...",
block_id: "00bc614e...",
signing_key: "PIX7abc...",
transaction_ids: ["trx123...", "trx456..."],
transactions: [
{
ref_block_num: 12345,
ref_block_prefix: 987654321,
expiration: "2024-01-15T12:31:00",
operations: [
["vote", { voter: "alice", author: "bob", permlink: "post", weight: 10000 }]
],
extensions: [],
signatures: ["1f5b3c..."]
}
]
}Use Cases:
- Analyze block contents
- Process historical data
- Verify transactions
// Process all transfers in a block
const block = await client.database.getBlock(12345678);
for (const tx of block.transactions) {
for (const op of tx.operations) {
const [opType, opData] = op;
if (opType === "transfer") {
console.log(`${opData.from} → ${opData.to}: ${opData.amount}`);
}
}
}getOperations(blockNum, onlyVirtual?)
Returns all operations from a block, including virtual operations.
Parameters:
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| blockNum | number | - | Block number |
| onlyVirtual | boolean | false | Return only virtual operations |
Returns: Promise<AppliedOperation[]>
// Get all operations
const allOps = await client.database.getOperations(12345678);
// Get only virtual operations (rewards, etc.)
const virtualOps = await client.database.getOperations(12345678, true);[
{
trx_id: "abc123...",
block: 12345678,
trx_in_block: 0,
op_in_trx: 0,
virtual_op: 0,
timestamp: "2024-01-15T12:30:00",
op: ["vote", { voter: "alice", author: "bob", permlink: "post", weight: 10000 }]
},
{
trx_id: "0000000000000000000000000000000000000000",
block: 12345678,
trx_in_block: 65535,
op_in_trx: 0,
virtual_op: 1,
timestamp: "2024-01-15T12:30:00",
op: ["curation_reward", { curator: "alice", reward: "1.234567 VESTS", ... }]
}
]getAccounts(usernames)
Returns detailed information for multiple accounts.
Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| usernames | string[] | Array of account names (max 1000) |
Returns: Promise<ExtendedAccount[]>
const accounts = await client.database.getAccounts(["alice", "bob", "charlie"]);[
{
id: 12345,
name: "alice",
owner: {
weight_threshold: 1,
account_auths: [],
key_auths: [["PIX7abc...", 1]]
},
active: { /* similar structure */ },
posting: { /* similar structure */ },
memo_key: "PIX7xyz...",
json_metadata: "{\"profile\":{\"name\":\"Alice\"}}",
posting_json_metadata: "{\"profile\":{\"about\":\"Hello!\"}}",
proxy: "",
balance: "100.000 PIXA",
savings_balance: "50.000 PIXA",
pxs_balance: "25.000 PXS",
savings_pxs_balance: "10.000 PXS",
vesting_shares: "1000000.000000 VESTS",
delegated_vesting_shares: "100000.000000 VESTS",
received_vesting_shares: "50000.000000 VESTS",
vesting_withdraw_rate: "0.000000 VESTS",
reward_pixa_balance: "1.000 PIXA",
reward_pxs_balance: "0.500 PXS",
reward_vesting_balance: "100.000000 VESTS",
reward_vesting_pixa: "0.050 PIXA",
voting_power: 9800, // 98%
voting_manabar: {
current_mana: "950000000000",
last_update_time: 1705320600
},
post_count: 150,
created: "2020-01-01T00:00:00",
last_post: "2024-01-14T10:00:00",
last_vote_time: "2024-01-15T12:00:00",
curation_rewards: 50000,
posting_rewards: 100000,
witnesses_voted_for: 30
}
]Use Cases:
- Display user profiles
- Check balances
- Verify account authority
// Get account and display formatted info
const [account] = await client.database.getAccounts(["alice"]);
if (account) {
console.log(`@${account.name}`);
console.log(`Balance: ${account.balance}`);
console.log(`Pixa Power: ${account.vesting_shares}`);
console.log(`Voting Power: ${(account.voting_power / 100).toFixed(2)}%`);
console.log(`Posts: ${account.post_count}`);
// Parse profile metadata
try {
const meta = JSON.parse(account.posting_json_metadata || account.json_metadata);
if (meta.profile) {
console.log(`Name: ${meta.profile.name || 'N/A'}`);
console.log(`About: ${meta.profile.about || 'N/A'}`);
}
} catch (e) {
// Invalid JSON metadata
}
} else {
console.log("Account not found");
}getDiscussions(by, query)
Returns an array of posts/discussions based on sorting method.
Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| by | DiscussionQueryCategory | Sorting method |
| query | DisqussionQuery | Query parameters |
Returns: Promise<Discussion[]>
Query Parameters:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| tag | string | No | Tag name, or username for blog/feed |
| limit | number | Yes | Results to return (max 100) |
| filter_tags | string[] | No | Tags to exclude |
| select_authors | string[] | No | Only include these authors |
| select_tags | string[] | No | Only include these tags |
| truncate_body | number | No | Truncate body to N bytes (0 = all) |
| start_author | string | No | Pagination: start from this author |
| start_permlink | string | No | Pagination: start from this permlink |
| parent_author | string | No | Filter by parent author |
| parent_permlink | string | No | Filter by parent permlink |
// Get trending posts in a tag
const trending = await client.database.getDiscussions("trending", {
tag: "photography",
limit: 20
});
// Get posts from a user's blog
const blog = await client.database.getDiscussions("blog", {
tag: "alice", // For 'blog', tag = username
limit: 10
});
// Get a user's feed (posts from people they follow)
const feed = await client.database.getDiscussions("feed", {
tag: "alice",
limit: 10
});
// Pagination
const page1 = await client.database.getDiscussions("trending", {
tag: "art",
limit: 20
});
const page2 = await client.database.getDiscussions("trending", {
tag: "art",
limit: 20,
start_author: page1[page1.length - 1].author,
start_permlink: page1[page1.length - 1].permlink
});| Category | Description | Tag Usage |
|----------|-------------|-----------|
| trending | Posts sorted by trending algorithm | Tag name |
| hot | Hot posts (recent + popular) | Tag name |
| created | Newest posts first | Tag name |
| promoted | Promoted posts (by spent PXS) | Tag name |
| active | Recently active (new comments) | Tag name |
| blog | Posts from user's blog | Username |
| feed | Posts from followed accounts | Username |
| comments | Comments by an author | Username |
| votes | Posts sorted by vote count | Tag name |
| children | Posts sorted by comment count | Tag name |
| cashout | Posts approaching payout | Tag name |
[
{
id: 123456,
author: "alice",
permlink: "my-awesome-post",
category: "photography",
parent_author: "",
parent_permlink: "photography",
title: "My Awesome Photography Post",
body: "Here is my post content with **markdown**...",
json_metadata: "{\"tags\":[\"photography\",\"nature\"],\"image\":[\"https://...\"]}",
created: "2024-01-14T10:00:00",
last_update: "2024-01-14T10:00:00",
depth: 0,
children: 15,
net_rshares: "50000000000000",
net_votes: 42,
total_payout_value: "0.000 PXS",
curator_payout_value: "0.000 PXS",
pending_payout_value: "12.500 PXS",
active_votes: [
{ voter: "bob", weight: 10000, rshares: "1000000000", time: "2024-01-14T10:05:00" }
],
author_reputation: 65000000000000,
url: "/photography/@alice/my-awesome-post",
root_title: "My Awesome Photography Post",
beneficiaries: [],
max_accepted_payout: "1000000.000 PXS",
percent_pxs: 10000,
allow_votes: true,
allow_curation_rewards: true
}
]getTransaction(txId)
Returns a transaction by its ID.
Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| txId | string | Transaction ID (40-char hex string) |
Returns: Promise<SignedTransaction>
const tx = await client.database.getTransaction("abc123def456...");{
ref_block_num: 12345,
ref_block_prefix: 987654321,
expiration: "2024-01-15T12:31:00",
operations: [
["transfer", {
from: "alice",
to: "bob",
amount: "10.000 PIXA",
memo: "Payment"
}]
],
extensions: [],
signatures: ["1f4a2b3c..."]
}getAccountHistory(account, from, limit, operation_bitmask?)
Returns account operation history.
Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| account | string | Account name |
| from | number | Start index (-1 for most recent) |
| limit | number | Number of operations (max 1000) |
| operation_bitmask | [number, number] | Optional: filter by operation types |
Returns: Promise<[[number, AppliedOperation]]>
// Get last 100 operations
const history = await client.database.getAccountHistory("alice", -1, 100);
// Process results (returns [index, operation] pairs)
for (const [index, op] of history) {
console.log(`#${index}: ${op.op[0]} at block ${op.block}`);
}Filtering by Operation Type:
import { utils } from "@pixagram/dpixa";
const op = utils.operationOrders;
// Create filter for transfer-related operations
const transferFilter = utils.makeBitMaskFilter([
op.transfer,
op.transfer_to_vesting,
op.transfer_to_savings,
op.transfer_from_savings,
op.claim_reward_balance
]);
const transfers = await client.database.getAccountHistory(
"alice",
-1,
100,
transferFilter
);
// Process only transfer operations
for (const [index, operation] of transfers) {
const [opType, opData] = operation.op;
console.log(`${opType}: ${JSON.stringify(opData)}`);
}[
[
12345, // Operation index
{
trx_id: "abc123...",
block: 12345678,
trx_in_block: 5,
op_in_trx: 0,
virtual_op: 0,
timestamp: "2024-01-15T12:30:00",
op: ["transfer", {
from: "alice",
to: "bob",
amount: "10.000 PIXA",
memo: "Payment"
}]
}
]
]getVestingDelegations(account, from?, limit?)
Returns vesting delegations made by an account.
Parameters:
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| account | string | - | Delegator account name |
| from | string | "" | Start from delegatee (for pagination) |
| limit | number | 1000 | Max results (max 1000) |
Returns: Promise<VestingDelegation[]>
const delegations = await client.database.getVestingDelegations("alice", "", 100);
for (const d of delegations) {
console.log(`Delegating ${d.vesting_shares} to @${d.delegatee}`);
}[
{
id: 12345,
delegator: "alice",
delegatee: "bob",
vesting_shares: "100000.000000 VESTS",
min_delegation_time: "2024-01-20T12:00:00"
},
{
id: 12346,
delegator: "alice",
delegatee: "charlie",
vesting_shares: "50000.000000 VESTS",
min_delegation_time: "2024-01-22T08:00:00"
}
]verifyAuthority(signedTransaction)
Verifies that a signed transaction has valid signatures.
Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| signedTransaction | SignedTransaction | Transaction with signatures |
Returns: Promise<boolean>
const isValid = await client.database.verifyAuthority(signedTx);
console.log(`Transaction is ${isValid ? "valid" : "invalid"}`);getVersion()
Returns the version information of the RPC node.
Returns: Promise<{blockchain_version: string, pixa_revision: string, fc_revision: string}>
const version = await client.database.getVersion();
console.log(`Node version: ${version.blockchain_version}`);Blockchain
The Blockchain helper provides streaming capabilities for real-time blockchain data.
getCurrentBlockNum(mode?)
Returns the current block number.
Parameters:
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| mode | BlockchainMode | Irreversible | Block finality mode |
Returns: Promise<number>
import { BlockchainMode } from "@pixagram/dpixa";
// Get last irreversible block (confirmed, won't change)
const irreversible = await client.blockchain.getCurrentBlockNum();
// Get head block (may be reversed in case of fork)
const head = await client.blockchain.getCurrentBlockNum(BlockchainMode.Latest);
console.log(`Irreversible: ${irreversible}, Head: ${head}`);getCurrentBlockHeader(mode?)
Returns the current block header.
Returns: Promise<BlockHeader>
const header = await client.blockchain.getCurrentBlockHeader();
console.log(`Current witness: ${header.witness}`);getCurrentBlock(mode?)
Returns the current full block.
Returns: Promise<SignedBlock>
const block = await client.blockchain.getCurrentBlock();
console.log(`Block has ${block.transactions.length} transactions`);getBlockNumbers(options?)
Returns an async iterator of block numbers.
Parameters:
| Option | Type | Description |
|--------|------|-------------|
| from | number | Starting block (default: current) |
| to | number | Ending block (default: infinite) |
| mode | BlockchainMode | Finality mode |
Returns: AsyncGenerator<number>
// Stream new block numbers indefinitely
for await (const num of client.blockchain.getBlockNumbers()) {
console.log(`New block: ${num}`);
}
// Process specific range
for await (const num of client.blockchain.getBlockNumbers({
from: 50000000,
to: 50000100
})) {
console.log(`Processing block ${num}`);
}
// Get latest blocks (may include reversible)
for await (const num of client.blockchain.getBlockNumbers({
mode: BlockchainMode.Latest
})) {
console.log(`Head block: ${num}`);
}getBlocks(options?)
Returns an async iterator of full blocks.
Returns: AsyncGenerator<SignedBlock>
// Stream all new blocks
for await (const block of client.blockchain.getBlocks()) {
console.log(`Block #${block.block_id} by @${block.witness}`);
console.log(` Transactions: ${block.transactions.length}`);
// Process each transaction
for (const tx of block.transactions) {
for (const [opType, opData] of tx.operations) {
// Handle operations
}
}
}
// Start from specific block
for await (const block of client.blockchain.getBlocks({ from: 50000000 })) {
// Process historical blocks
if (block.block_id === "target") break;
}getOperations(options?)
Returns an async iterator of all operations (including virtual).
Returns: AsyncGenerator<AppliedOperation>
// Stream all operations
for await (const appliedOp of client.blockchain.getOperations()) {
const [opType, opData] = appliedOp.op;
switch (opType) {
case "transfer":
console.log(`Transfer: ${opData.from} → ${opData.to}: ${opData.amount}`);
break;
case "vote":
const voteType = opData.weight > 0 ? "upvote" : opData.weight < 0 ? "downvote" : "unvote";
console.log(`Vote: ${opData.voter} ${voteType} @${opData.author}/${opData.permlink}`);
break;
case "curation_reward": // Virtual operation
console.log(`Curation reward: ${opData.curator} earned ${opData.reward}`);
break;
}
}Stream Methods (Node.js Streams)
Convert iterators to Node.js readable streams.
Returns: ReadableStream
// Block number stream
const numStream = client.blockchain.getBlockNumberStream();
// Block stream
const blockStream = client.blockchain.getBlockStream();
// Operations stream
const opStream = client.blockchain.getOperationsStream();
// Use with pipes
const es = require("event-stream");
blockStream
.pipe(es.map((block, cb) => {
cb(null, `Block ${block.block_id}\n`);
}))
.pipe(process.stdout);Broadcast API
The broadcast API sends transactions to the blockchain and returns a TransactionConfirmation.
{
id: "trx123abc...", // Transaction ID
block_num: 12345678, // Block number where included
trx_num: 5, // Transaction index in block
expired: false // Whether transaction expired
}Voting on Content
import { Client, PrivateKey } from "@pixagram/dpixa";
const client = new Client(["https://api.pixagram.io"]);
const postingKey = PrivateKey.fromLogin("myuser", "mypassword", "posting");
// Upvote 100%
const result = await client.broadcast.vote({
voter: "myuser",
author: "post-author",
permlink: "post-permlink",
weight: 10000 // 100% = 10000
}, postingKey);
console.log(`Vote included in block ${result.block_num}`);Vote Weight Guide:
| Weight | Meaning |
|--------|---------|
| 10000 | 100% upvote |
| 5000 | 50% upvote |
| 0 | Remove vote |
| -5000 | 50% downvote |
| -10000 | 100% downvote |
Transferring Funds
const activeKey = PrivateKey.fromLogin("myuser", "mypassword", "active");
// Transfer PIXA
await client.broadcast.transfer({
from: "myuser",
to: "recipient",
amount: "10.000 PIXA",
memo: "Here's your payment!"
}, activeKey);
// Transfer PXS
await client.broadcast.transfer({
from: "myuser",
to: "recipient",
amount: "5.000 PXS",
memo: "PXS transfer"
}, activeKey);
// Encrypted memo (starts with #)
const memoKey = PrivateKey.fromLogin("myuser", "mypassword", "memo");
const recipientMemoKey = "PIX7abc..."; // Get from recipient's account
const encryptedMemo = Memo.encode(memoKey, recipientMemoKey, "Secret message");
await client.broadcast.transfer({
from: "myuser",
to: "recipient",
amount: "1.000 PIXA",
memo: encryptedMemo // "#encoded..."
}, activeKey);Creating Posts and Comments
const postingKey = PrivateKey.fromLogin("myuser", "mypassword", "posting");
// Create a new post
await client.broadcast.comment({
parent_author: "", // Empty for root posts
parent_permlink: "photography", // Category/tag
author: "myuser",
permlink: "my-first-photo-post",
title: "My First Photography Post",
body: `
# Hello World!
This is my first post with **markdown** support.

`,
json_metadata: JSON.stringify({
tags: ["photography", "nature", "introduction"],
image: ["https://example.com/photo.jpg"],
app: "myapp/1.0",
format: "markdown"
})
}, postingKey);
// Reply to a post
await client.broadcast.comment({
parent_author: "originalauthor",
parent_permlink: "original-post",
author: "myuser",
permlink: "re-originalauthor-original-post-20240115",
title: "", // Replies typically have no title
body: "Great post! Thanks for sharing this.",
json_metadata: JSON.stringify({
tags: ["photography"],
app: "myapp/1.0"
})
}, postingKey);Custom JSON Operations
// Follow a user
await client.broadcast.customJson({
required_auths: [],
required_posting_auths: ["myuser"],
id: "follow",
json: JSON.stringify([
"follow",
{
follower: "myuser",
following: "targetuser",
what: ["blog"] // ["blog"] to follow, [] to unfollow
}
])
}, postingKey);
// Reblog/Resteem a post
await client.broadcast.customJson({
required_auths: [],
required_posting_auths: ["myuser"],
id: "follow",
json: 