Production-grade TypeScript SDK for interacting with a Nano node, providing fully typed and runtime-validated RPC and WebSocket APIs, a built-in WebSocket client with typed ack and topic listeners, and utilities for blocks, cryptography, and safe raw amount arithmetic.
npm i nano-sdk zodimport { Nano } from "nano-sdk";
const nanoRpcUrl = "http://127.0.0.1:7076";
// Alias
type AccountString = Nano.Types.AccountString;
const AccountString = Nano.Types.AccountString();
async function fetchAccountBalance(account: AccountString) {
// 1) Validate user input
const validatedAccount = AccountString.parse(account);
// 2) Typed RPC call
const response = await Nano.RPC.account_balance(
nanoRpcUrl,
{
action: "account_balance",
account: validatedAccount,
include_only_confirmed: true,
},
{ timeoutInMs: 2000 }
);
// 3) Convert and format raw balance
const balanceInNano = Nano.Math.rawToNano({ raw: response.balance, decimalPlaces: 6 });
// 4) Output balanceInNano
console.log("Balance (Nano):", balanceInNano);
}
fetchAccountBalance("nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3").catch((err) => console.error("Unexpected failure:", err));RPC requests and responses are fully typed and validated at runtime. Response types are derived from the corresponding request parameters, meaning the shape of the response object adapts based on the options you provide.
The SDK uses a single root namespace (Nano), organized into sub-namespaces, each focused on a specific responsibility:
Nano.Blocks: Block schemas (Zod) for validating and composing Nano blocksNano.Crypto: Key derivation, block hashing, signing, and verification utilitiesNano.Math: Raw amount conversion, formatting, and safe raw arithmeticNano.RPC: Nano node RPC methods (HTTP POST), with typed requests and typed responsesNano.Types: Runtime validators for common Nano primitives (account, hash, keys, raw amounts, etc.)Nano.WebSocket: Fully typed Nano node WebSocket request and response schemas, including acknowledgement and topic message definitionsNano.WebSocketClient: Instantiable WebSocket client providing fully typed acknowledgement and topic-based message handling using theNano.WebSocketschemas
All RPC methods:
- validate requests using Zod
- perform an HTTP POST (default: native
fetch) - detect and handle post errors
- validate responses using Zod
All RPC methods follow a consistent signature:
Nano.RPC.<method>(rpcUrl, request, config?)
rpcUrl– Nano node RPC endpointrequest– typed request object (includingaction)config(optional) – request behavior and transport options
By default, RPC calls throw Nano.RPC.PostError for:
- Invalid request payloads
- HTTP or transport errors
- Nano node error responses
- Invalid or unexpected response data
If throwOnError is set to false, the method instead returns a structured result object indicating success or failure.
The optional config supports:
throwOnError– true (default) throws, false returns{ success, data / error }timeoutInMs– HTTP timeoutabortSignal– cancellation via AbortControllerhttpClient– custom HTTP transport
By default, errors throw Nano.RPC.PostError.
RPC methods accept a custom httpClient via the request config. See the axios example in
Nano.WebSocket provides a complete, strongly typed implementation of all Nano node WebSocket request and response schemas and ships with a built-in WebSocketClient. By default, the client uses the globally available WebSocket implementation provided by the current runtime environment (browser or Node.js).
The WebSocketClient exposes fully typed WebSocket interactions through two complementary listener APIs:
- Ack listeners for handling typed acknowledgement messages returned by the node when a WebSocket action explicitly requests an acknowledgement (
subscribe,unsubscribe,update, orpong) - Topic listeners for typed streaming subscriptions, including
bootstrap,confirmation,new_unconfirmed_block,started_election,stopped_election,telemetry,work, andvote
All incoming messages are validated and typed based on the corresponding WebSocket schemas, enabling safe, ergonomic access to response data without manual parsing or casting.
const ws = new Nano.WebSocketClient(webSocketUrl, undefined, {
webSocketClass: undefined, // WebSocket constructor, if none provided, defaults to global WebSocket
connectionTimeout: 4000, // retry connect if not connected after this time, in ms
minUptime: 5000, // min time in ms to consider connection as stable
maxEnqueuedMessages: Infinity, // maximum number of messages to buffer until reconnection
maxReconnectionAttempts: Infinity, // maximum number of reconnection attempts
maxReconnectionDelay: 10000, // max delay in ms between reconnections
minReconnectionDelay: 1000 + Math.random() * 4000, // min delay in ms between reconnections
reconnectionDelayGrowFactor: 1.3, // how fast the reconnection delay grows
startClosed: false, // start websocket in CLOSED state, call `.reconnect()` to connect
});Nano.Types provides a collection of reusable Zod schemas for common Nano-specific primitives. These schemas form the foundation for higher-level features such as cryptography and RPC validation. Use them to validate external input and to type values throughout your codebase:
- Prefer
.parse(...)when invalid input should throw immediately - Prefer
.safeParse(...)when you want a typed success/failure result without throwing
The available schemas cover a wide range of Nano primitives, including but not limited to:
AccountString,RawAmountString,NanoAmountString,PrivateKeyString,PublicKeyString,SignatureString,HashString,HexString, ...
Nano.Math provides safe arithmetic, comparison, and formatting utilities for nano and raw amounts.
Raw amounts can be represented as strings (RawAmountString, to remain JSON-serializable) and native BigInt values (RawAmount).
Nano amounts are represented as strings (NanoAmountString) to avoid precision issues and eliminate the need for a BigNumber.js dependency.
All raw functions support mixed inputs (RawAmount and RawAmountString).
The type of the first parameter of arithmetic functions determines the return type:
- If the first
rawparameter is aRawAmount(BigInt), the result is returned asBigInt - If the first
rawparameter is aRawAmountString(String), the result is returned asString
Available utilities:
- Conversion:
nanoToRaw,rawToNano - Formatting:
formatRaw - Arithmetic (with bounds checking):
rawPlus,rawMinus,rawMultiply,rawDivide,rawModulo - Comparisons:
rawIsZero,rawIsGreaterThan,rawIsGreaterThanOrEqualTo,rawIsLessThan,rawIsLessThanOrEqualTo,rawIsEqualTo
Nano.Crypto provides cryptographic utilities commonly needed when building Nano-related services:
- Key pair generation and deterministic key derivation
- Block hashing and hash verification
- Block signing and signature verification
- Block verification (combines hash, link, and signature validation for state blocks into a single method call)
- Proof-of-work hash verification
derive-account-from-seed.example.tshash-and-verify-hash.example.tssign-and-verify-signature.example.tsverify-block.example.ts
Nano.Blocks provides predefined Zod schemas for composing and validating Nano block variants. All schemas are provided as composable building blocks and can be used as a base to define extended schemas with additional custom fields.
Available block schemas:
StateBlockLegacySendBlock,LegacyReceiveBlock,LegacyOpenBlock,LegacyChangeBlockBlockas a union of all supported block variants
- Unit tests (
test/unit) cover schemas, math edge cases, crypto utilities, and parsing/validation flows (throwing and non-throwing). - Integration tests (
test/integration) verify both RPC and WebSocket functionality against a real Nano node, ensuring request and response schemas match live node behavior.
Unit tests are executed using:
npm run test:unitIntegration test requirements:
- A running Nano node is required.
- All public Nano RPC and WebSocket endpoints must be reachable.
enable_control=trueis not required for any currently enabled integration tests. - The RPC endpoint URL can be configured via the
config.nanoRpcUrlfield inpackage.jsonor via theNANO_RPC_URLenvironment variable. The environment variable takes precedence if both are set. - The WebSocket endpoint URL can be configured via the
config.nanoWebSocketUrlfield inpackage.jsonor via theNANO_WEB_SOCKET_URLenvironment variable. The environment variable takes precedence if both are set.
Integration tests for RPC and WebSocket are executed together using:
npm run test:integration- npm: https://www.npmjs.com/package/nano-sdk
- GitHub: https://github.com/infinitybay/nano-sdk
- Nano Node RPC Protocol: https://docs.nano.org/commands/rpc-protocol/
- Nano Node WebSockets Integration Guide: https://docs.nano.org/integration-guides/websockets/

