/** * @file Hive RPC client implementation. * @author Johan Nordberg * @license * Copyright (c) 2017 Johan Nordberg. 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. */ import { Blockchain } from "./helpers/blockchain.js"; import { BroadcastAPI } from "./helpers/broadcast.js"; import { DatabaseAPI } from "./helpers/database.js"; import { HivemindAPI } from "./helpers/hivemind.js"; import { AccountByKeyAPI } from "./helpers/key.js"; import { MarketHistoryAPI } from "./helpers/market.js"; import { RCAPI } from "./helpers/rc.js"; import { TransactionStatusAPI } from "./helpers/transaction.js"; import { NodeHealthTracker, HealthTrackerOptions } from "./health-tracker.js"; /** * Published Pollen package version. * * @remarks * This value is generated from `package.json` during the build and is also used * in Node request metadata so RPC operators can identify Pollen clients. * * @example * ```ts * import { VERSION } from '@srbde/pollen' * * console.log(`Running Pollen ${VERSION}`) * ``` */ export declare const VERSION = "1.0.5"; /** * Main Hive network chain id as 32 raw bytes. * * @remarks * The chain id is mixed into transaction signatures. Keeping the default here * prevents signatures produced for Hive mainnet from being replayed on a * different chain. * * @example * ```ts * import { DEFAULT_CHAIN_ID } from '@srbde/pollen' * * console.log(toHex(DEFAULT_CHAIN_ID)) * ``` */ export declare const DEFAULT_CHAIN_ID: Uint8Array; /** * Main Hive network public-key address prefix. * * @remarks * Hive-compatible public keys are rendered with a network prefix. Mainnet uses * `STM`, and custom networks can override this through {@link ClientOptions}. */ export declare const DEFAULT_ADDRESS_PREFIX = "STM"; /** * Configuration for a {@link Client} instance. * * @remarks * Options control both protocol identity, such as `chainId` and * `addressPrefix`, and resilience behavior, such as timeout, failover, and * jittered backoff. A single configured client owns the Nectar helpers for * database reads, broadcasting, RC, Hivemind, and transaction-status calls. * * @example * ```ts * import { Client } from '@srbde/pollen' * * const client = new Client( * ['https://api.hive.blog', 'https://api.openhive.network'], * { * timeout: 45_000, * failoverThreshold: 2, * consoleOnFailover: true * } * ) * ``` */ export interface ClientOptions { /** * Hive chain id. Defaults to main hive network: * need the new id? * `beeab0de00000000000000000000000000000000000000000000000000000000` * */ chainId?: string; /** * Hive address prefix. Defaults to main network: * `STM` */ addressPrefix?: string; /** * Send timeout, how long to wait in milliseconds before giving * up on a rpc call. Note that this is not an exact timeout, * no in-flight requests will be aborted, they will just not * be retried any more past the timeout. * Can be set to 0 to retry forever. Defaults to 60 * 1000 ms. */ timeout?: number; /** * Specifies the amount of times the urls (RPC nodes) should be * iterated and retried in case of timeout errors. * (important) Requires url parameter to be an array (string[])! * Can be set to 0 to iterate and retry forever. Defaults to 3 rounds. */ failoverThreshold?: number; /** * Whether a console.log should be made when RPC failed over to another one */ consoleOnFailover?: boolean; /** * Retry backoff function, returns milliseconds. Defaults to Pollen's * jittered exponential backoff. */ backoff?: (tries: number) => number; /** * Node.js http(s) agent, use if you want http keep-alive. * Defaults to using https.globalAgent. * @see https://nodejs.org/api/http.html#http_new_agent_options. */ agent?: unknown; /** * Options for the node health tracker. * Controls cooldown periods, stale block thresholds, etc. */ healthTrackerOptions?: HealthTrackerOptions; } /** * High-level Hive RPC client used by every Pollen helper. * * @remarks * `Client` centralizes JSON-RPC transport, node failover, API health tracking, * network identity, and helper construction. It can run in Node.js or a browser * bundle and exposes purpose-built helpers such as {@link DatabaseAPI}, * broadcasting, and {@link Blockchain} so application code rarely needs * to assemble raw RPC payloads. * * @example * ```ts * import { Client } from '@srbde/pollen' * * const client = new Client('https://api.hive.blog') * const props = await client.database.getDynamicGlobalProperties() * * console.log(`Hive head block: ${props.head_block_number}`) * ``` * * @see {@link ClientOptions} * @see {@link RPCError} */ export declare class Client { /** * Client options, *read-only*. */ readonly options: ClientOptions; /** * Address to Hive RPC server. * String or String[] *read-only* */ address: string | string[]; /** * Database API helper. */ readonly database: DatabaseAPI; /** * RC API helper. */ readonly rc: RCAPI; /** * Broadcast API helper. */ readonly broadcast: BroadcastAPI; /** * Blockchain helper. */ readonly blockchain: Blockchain; /** * Market History API helper. */ readonly market: MarketHistoryAPI; /** * Hivemind helper. */ readonly hivemind: HivemindAPI; /** * Accounts by key API helper. */ readonly keys: AccountByKeyAPI; /** * Transaction status API helper. */ readonly transaction: TransactionStatusAPI; /** * Node health tracker for smart failover. * Tracks per-node, per-API health and head block freshness. */ readonly healthTracker: NodeHealthTracker; /** * Chain ID for current network. */ readonly chainId: Uint8Array; /** * Address prefix for current network. */ readonly addressPrefix: string; private timeout; private backoff; private failoverThreshold; private consoleOnFailover; currentAddress: string; /** * Creates a client for one or more Hive RPC endpoints. * * @param address - RPC endpoint URL or ordered failover list. For example, * `https://api.hive.blog` or `['https://api.hive.blog', 'https://api.openhive.network']`. * @param options - Network identity and resilience settings. * * @remarks * The first endpoint becomes the active node. When calls fail, Pollen uses * the configured backoff and health tracker to move across the endpoint * list without requiring callers to recreate helper objects. * * @throws AssertionError * Thrown when `options.chainId` is not exactly 32 bytes after hex decoding. * * @example * ```ts * import { Client } from '@srbde/pollen' * * const client = new Client( * ['https://api.hive.blog', 'https://api.deathwing.me'], * { timeout: 30_000, failoverThreshold: 2 } * ) * * const accounts = await client.database.getAccounts(['srbde']) * console.log(accounts[0].balance) * ``` */ constructor(address: string | string[], options?: ClientOptions); /** * Creates a client preconfigured for the public Hive testnet. * * @param options - Optional client settings copied into the testnet * configuration. * @returns A {@link Client} targeting `https://api.fake.openhive.network` * with the testnet chain id. * * @remarks * This helper preserves transport options such as custom HTTP agents while * replacing chain identity values so test transactions cannot be confused * with mainnet signatures. * * @example * ```ts * import { Client } from '@srbde/pollen' * * const testnet = Client.testnet({ timeout: 20_000 }) * const props = await testnet.database.getDynamicGlobalProperties() * console.log(props.head_block_number) * ``` */ static testnet(options?: ClientOptions): Client; /** * Creates a Client instance initialized with healthy nodes fetched dynamically * from nectarflower's on-chain metadata. * * @param options - Additional options for the client. * @param bootstrapNodes - Optional list of bootstrap nodes to fetch metadata from. * Defaults to mainnet public nodes. * * @example * ```ts * import { Client } from '@srbde/pollen' * * const client = await Client.fromNectarflower() * const props = await client.database.getDynamicGlobalProperties() * console.log(props.head_block_number) * ``` */ static fromNectarflower(options?: ClientOptions, bootstrapNodes?: string | string[]): Promise; /** * Sends a JSON-RPC request through the configured failover transport. * * @param api - API namespace to call, such as `condenser_api`. * @param method - Method within the API namespace, such as * `get_dynamic_global_properties`. * @param params - Positional RPC parameters. Defaults to an empty array. * @returns The decoded `result` member returned by the RPC node. * * @remarks * The transport serializes `Uint8Array` values as Hive-compatible hex strings, applies * jittered retry backoff, tracks API-specific node failures, and passively * records head-block freshness from `get_dynamic_global_properties` * responses. Broadcast calls skip the short per-fetch timeout because they * must not be retried as aggressively as read-only calls. * * @throws RPCError * Thrown when the node returns a JSON-RPC error. The `info` property carries * the original error data when the node provides it. * @throws AssertionError * Thrown when the response id does not match the request id. * * @example * ```ts * import { Client } from '@srbde/pollen' * * const client = new Client('https://api.hive.blog') * const config = await client.call('condenser_api', 'get_config') * * console.log(config.HIVE_BLOCK_INTERVAL) * ``` * * @see {@link retryingFetch} * @see {@link NodeHealthTracker} */ call(api: string, method: string, params?: unknown): Promise; }