EOSJS Library
EOSJS is the official JavaScript library for interacting with EOSIO blockchain APIs. It provides a comprehensive set of tools for sending transactions, querying blockchain state, managing accounts, and performing cryptographic operations like signing and verifying. The current stable version is 22.1.0, which introduces support for read-only transactions within smart contracts via HTTP-RPC and action return values. Historically, the library has undergone significant internal changes, such as the switch from `eosjs-ecc` to the `elliptic` cryptography library in v21.0.2, while striving to maintain a stable public API. Releases often include security, stability, and miscellaneous fixes, with release candidates preceding major version bumps. It is a critical component for building applications that interact with EOSIO-based blockchains, offering robust TypeScript support and keeping pace with new blockchain features.
Common errors
-
TypeError: fetch is not a function
cause The `JsonRpc` constructor expects a global `fetch` API, which is available in browsers but not natively in Node.js environments prior to Node 18 without a polyfill or explicit import.fixIn Node.js, install `node-fetch` (e.g., `npm install node-fetch`) and pass it explicitly: `new JsonRpc(rpcEndpoint, { fetch: require('node-fetch') })` or `new JsonRpc(rpcEndpoint, { fetch })` after `import fetch from 'node-fetch'`. -
RpcError: unknown key: signature
cause This error commonly occurs when attempting to push a transaction without a properly configured or working `SignatureProvider`, or if the provided private key is invalid or mismatched for the account's permissions defined in the transaction's `authorization` array.fixEnsure your `SignatureProvider` (e.g., `JsSignatureProvider`) is correctly initialized with the private key corresponding to the `actor` and `permission` specified in your transaction's `authorization` array. Double-check the private key and account name for accuracy and that the private key corresponds to the network you're connected to. -
TypeError: Cannot read properties of undefined (reading 'textDecoder')
cause The `Api` constructor requires `textDecoder` and `textEncoder` instances, which are global in modern browser environments but need to be explicitly imported or polyfilled in some Node.js environments.fixIn Node.js, import `TextEncoder` and `TextDecoder` from the built-in `util` module: `import { TextEncoder, TextDecoder } from 'util';` and pass them to the `Api` constructor: `{ textDecoder: new TextDecoder(), textEncoder: new TextEncoder() }`. -
Error: Missing RpcInterfaces.SignatureProvider
cause The `Api` class constructor strictly requires an instance of a `SignatureProvider` to be passed, even if you only intend to perform read-only operations with the `Api` instance later. This ensures a consistent API interface.fixProvide an instance of a `SignatureProvider` (e.g., `JsSignatureProvider` for testing purposes, or a more secure provider for production) to the `Api` constructor. If you only need to query blockchain state and do not intend to send transactions, you can use `JsonRpc` directly without `Api`.
Warnings
- breaking EOSJS v22.0.0-rc2 (which became v22.0.0 stable) introduced new endpoints and TypeScript types for Nodeos API plugins. This can lead to type errors in existing TypeScript projects or incorrect endpoint usage if not updated carefully.
- breaking In EOSJS v21.0.2, the internal cryptographic library was switched from `eosjs-ecc` to `elliptic`. While the public API was largely maintained, projects that relied on internal specifics of `eosjs-ecc` or expected certain key/signature formats might experience breaking changes.
- gotcha Versions 21.0.3 and earlier had an issue with `sign`/`recover`/`verify` methods when the `shouldHash` argument was set to `false` while sending *unhashed* data, leading to incorrect cryptographic operations.
- security EOSJS v21.0.4 addressed several identified security vulnerabilities in underlying dependencies, including `y18n`, `elliptic`, `node-notifier`, `ini`, and `node-fetch`. Older versions are susceptible to these vulnerabilities.
- gotcha Newer versions of `eosjs` are often developed with ECMAScript Modules (ESM) in mind, which can lead to import/export issues when used in CommonJS (CJS) environments with `require()`. This can manifest as `TypeError: (0, _eosjs.Api) is not a constructor` or similar.
Install
-
npm install eosjs -
yarn add eosjs -
pnpm add eosjs
Imports
- JsonRpc
const JsonRpc = require('eosjs').JsonRpc;import { JsonRpc } from 'eosjs'; - Api
import Api from 'eosjs';
import { Api, RpcInterfaces, SignatureProvider, TransactConfig } from 'eosjs'; - PrivateKey
import { PrivateKey } from 'eosjs';import { PrivateKey } from 'eosjs/dist/eosjs-key-conversions'; - JsSignatureProvider
import { JsSignatureProvider } from 'eosjs';import { JsSignatureProvider } from 'eosjs/dist/eosjs-jssig';
Quickstart
import { JsonRpc } from 'eosjs';
import { Api, RpcInterfaces } from 'eosjs';
import { JsSignatureProvider } from 'eosjs/dist/eosjs-jssig'; // Example signature provider
import { TextEncoder, TextDecoder } from 'util'; // For Node.js environments
// Configuration
const defaultPrivateKey = process.env.EOS_PRIVATE_KEY ?? ''; // Replace with an actual private key for signing, DO NOT expose in client-side code.
const rpcEndpoint = 'https://eos.greymass.com'; // Example public EOS mainnet endpoint
// 1. Setup RPC client
const rpc = new JsonRpc(rpcEndpoint, { fetch }); // Using global fetch or node-fetch in Node.js
// 2. Setup SignatureProvider (required even for read-only if you intend to send transactions later)
// For demonstration, using a JS-based signature provider. In production, consider more secure options.
const signatureProvider = new JsSignatureProvider([defaultPrivateKey]);
// 3. Setup API client
const api = new Api({
rpc,
signatureProvider,
textDecoder: new TextDecoder(), // Required for Node.js
textEncoder: new TextEncoder(), // Required for Node.js
});
async function runExample() {
try {
console.log(`Querying a public contract table on ${rpcEndpoint}...`);
// Example: Get 'stat' table from 'eosio.token' contract for 'EOS' symbol
const tableRows = await rpc.get_table_rows({
json: true,
code: 'eosio.token',
scope: 'EOS',
table: 'stat',
lower_bound: null,
upper_bound: null,
limit: 1,
});
console.log('Table Rows (eosio.token, EOS, stat):', JSON.stringify(tableRows, null, 2));
// Example of pushing a transaction (requires a valid private key and account for 'youraccount')
// This part is commented out as it requires a real key and funded account to execute.
/*
if (defaultPrivateKey && defaultPrivateKey !== '') {
console.log('Attempting to push a dummy transaction...');
const transactionResult = await api.transact({
actions: [{
account: 'eosio.token',
name: 'transfer',
authorization: [{
actor: 'youraccount', // Replace with your EOS account name
permission: 'active',
}],
data: {
from: 'youraccount',
to: 'teamgreymass', // Example recipient
quantity: '0.0001 EOS', // Use a small test amount
memo: 'Test transfer from eosjs quickstart',
},
}]
}, {
blocksBehind: 3,
expireSeconds: 30,
});
console.log('Transaction Result:', JSON.stringify(transactionResult, null, 2));
}
*/
} catch (error) {
console.error('Error:', error);
if (error instanceof RpcInterfaces.RpcError) {
console.error('RPC Error details:', JSON.stringify(error.json, null, 2));
}
}
}
runExample();