TypeScript library providing unified, type-safe RPC client interfaces for multiple blockchain networks with configurable request execution strategies.
- Multi-Network Support: Unified API for 10+ blockchain networks including EVM chains (Ethereum, Optimism, Arbitrum, Polygon, BNB, Base, Avalanche, Aztec) and Bitcoin
- Bitcoin Support: Full Bitcoin Core v28+ RPC support with ~115 methods using CAIP-2/BIP122 chain identifiers
- Strategy Pattern: Pluggable request execution strategies (Fallback for reliability, Parallel for consistency detection, Race for minimum latency)
- Type Safety: Strong TypeScript typing with network-specific type definitions
- Dual Transport: HTTP and WebSocket support with automatic transport detection from URL scheme
- WebSocket Features: Persistent connections, request multiplexing, auto-reconnect with exponential backoff
- Zero Dependencies: Pure Node.js implementation with no external runtime dependencies
- ES Modules: Native ESM support for modern JavaScript environments
- Factory Pattern: Type-safe client instantiation based on chain IDs (numeric for EVM, CAIP-2 for Bitcoin)
- Inconsistency Detection: Parallel strategy can detect RPC provider data divergence
- Resource Lifecycle:
close()method for clean shutdown of WebSocket connections
npm install @openscan/network-connectors| Network | Chain ID | Client Class | Special Features |
|---|---|---|---|
| Ethereum | 1 | EthereumClient |
Full eth_, web3_, net_, debug_, trace_, txpool_ |
| Optimism | 10 | OptimismClient |
Ethereum + optimism_, opp2p_, admin_* methods |
| BNB Smart Chain | 56 | BNBClient |
Extended Ethereum methods + BSC-specific features |
| BNB Testnet | 97 | BNBClient |
Factory maps to BNBClient; BNBTestnetClient also exported for direct use |
| Polygon | 137 | PolygonClient |
Ethereum + Polygon Bor validator methods |
| Base | 8453 | BaseClient |
Optimism-compatible (reuses Optimism types) |
| Arbitrum One | 42161 | ArbitrumClient |
Ethereum + arbtrace_* (Arbitrum traces) |
| Avalanche C-Chain | 43114 | AvalancheClient |
Ethereum + avax cross-chain, admin, extended debug |
| Aztec | 677868 | AztecClient |
Custom node_/nodeAdmin_ methods (non-EVM) |
| Hardhat | 31337 | HardhatClient |
Ethereum + hardhat_/evm_ state manipulation methods |
| Sepolia Testnet | 11155111 | SepoliaClient |
Ethereum-compatible testnet |
Bitcoin uses CAIP-2/BIP122 chain identifiers instead of numeric chain IDs.
| Network | Chain ID (CAIP-2) | Client Class | Special Features |
|---|---|---|---|
| Bitcoin Mainnet | bip122:000000000019d6689c085ae165831e93 |
BitcoinClient |
Full Bitcoin Core v28+ RPC (~115 methods) |
| Bitcoin Testnet3 | bip122:000000000933ea01ad0ee984209779ba |
BitcoinClient |
Bitcoin testnet3 network |
| Bitcoin Testnet4 | bip122:00000000da84f2bafbbc53dee25a72ae |
BitcoinClient |
Bitcoin testnet4 (BIP94) |
| Bitcoin Signet | bip122:00000008819873e925422c1ff0f99f7c |
BitcoinClient |
Bitcoin signet (BIP325) |
For convenience, use the exported constants instead of raw chain ID strings:
import {
BITCOIN_MAINNET,
BITCOIN_TESTNET3,
BITCOIN_TESTNET4,
BITCOIN_SIGNET
} from "@openscan/network-connectors";
// BITCOIN_MAINNET = "bip122:000000000019d6689c085ae165831e93"| Category | Methods | Description |
|---|---|---|
| Blockchain | ~15 | getBlockchainInfo, getBlock, getBlockHash, getBlockHeader, getBlockStats, getChainTips, getDifficulty, etc. |
| Mempool | ~10 | getMempoolInfo, getRawMempool, getMempoolEntry, testMempoolAccept, submitPackage, etc. |
| Raw Transactions | ~7 | getRawTransaction, decodeRawTransaction, decodeScript, sendRawTransaction, createRawTransaction, etc. |
| PSBT | ~8 | createPsbt, decodePsbt, analyzePsbt, combinePsbt, finalizePsbt, joinPsbts, etc. |
| Network | ~13 | getNetworkInfo, getPeerInfo, getConnectionCount, getNetTotals, ping, addNode, etc. |
| Fee Estimation | ~1 | estimateSmartFee with economical/conservative modes |
| Utility | ~7 | validateAddress, getDescriptorInfo, deriveAddresses, createMultisig, verifyMessage, etc. |
| Mining | ~9 | getMiningInfo, getNetworkHashPs, getBlockTemplate, submitBlock, generateToAddress, etc. |
| Wallet | ~35 | getWalletInfo, getBalances, listWallets, sendToAddress, listUnspent, importDescriptors, etc. |
| Control | ~6 | getMemoryInfo, getRpcInfo, help, uptime, logging, stop |
@openscan/network-connectors/
├── src/
│ ├── strategies/ # Request execution strategies (Fallback, Parallel, Race)
│ ├── networks/ # Network-specific clients organized by chain ID
│ ├── factory/ # Client instantiation and chain ID mapping
│ ├── NetworkClient.ts # Base network client (concrete class)
│ ├── JsonRpcTransport.ts # Transport interface and auto-detect factory
│ ├── RpcClient.ts # HTTP JSON-RPC transport
│ ├── WebSocketRpcClient.ts # WebSocket JSON-RPC transport
│ ├── RpcClientTypes.ts # JSON-RPC request/response type definitions
│ └── index.ts # Main export file
├── tests/ # Comprehensive test suite
│ ├── http/ # HTTP transport tests (strategies, networks, factory)
│ ├── ws/ # WebSocket transport tests (strategies, networks)
│ ├── transport/ # Transport layer tests (auto-detection)
│ └── helpers/ # Test utilities (validators, env config)
├── scripts/
│ └── publish-and-tag.sh # Automated release workflow
├── .github/workflows/
│ └── npm-publish.yml # CI/CD automation
├── dist/ # Compiled JavaScript output (gitignored)
├── biome.json # Linting and formatting configuration
├── tsconfig.json # TypeScript configuration
└── package.json # Project metadata and dependencies
-
src/strategies/: Implements the Strategy pattern for RPC request execution
FallbackStrategy: Sequential execution with early exit on successParallelStrategy: Concurrent execution with inconsistency detectionRaceStrategy: Concurrent execution returning first successful responseStrategyFactory: Creates appropriate strategy based on configuration
-
src/networks/: Network-specific client implementations (one directory per chain ID)
- Each client extends
NetworkClientbase class - Provides network-specific RPC methods and type definitions
- Organized by chain ID for clarity
- Each client extends
-
src/factory/: Client instantiation logic
ClientRegistry: Maps chain IDs to client classes with type safety- Factory methods for creating clients
-
tests/: Comprehensive test coverage
- Uses Node.js native test framework with tsx
- Split by transport:
http/for HTTP tests,ws/for WebSocket tests transport/for transport layer auto-detection testshelpers/for shared validators and env config
-
scripts/: Automation scripts
- Release workflow (build, publish, tag)
The library uses the Strategy Pattern to provide flexible RPC request execution:
-
FallbackStrategy: Tries RPC providers sequentially until one succeeds
- Minimal overhead (stops at first success)
- Returns metadata tracking all attempted providers and response times
- Best for reliability when providers are generally consistent
-
ParallelStrategy: Executes all RPC providers concurrently
- Tracks response times and errors for all providers
- Detects data inconsistencies using response hashing
- Returns comprehensive metadata for debugging
- Best for detecting provider divergence
-
RaceStrategy: Executes all RPC providers concurrently, returns first success
- Uses
Promise.anyto return as soon as any provider succeeds - Minimizes latency by using the fastest responding provider
- Only fails if ALL providers fail
- Includes metadata with winning response and errors
- Best for latency-sensitive operations
- Uses
Strategies can be configured at client creation or switched dynamically using updateStrategy(). All three strategies support both HTTP and WebSocket transports interchangeably.
The library supports both HTTP and WebSocket transports through a unified JsonRpcTransport interface:
- RpcClient (HTTP): Stateless, one request per fetch call
- WebSocketRpcClient: Persistent connection with request multiplexing, auto-reconnect with exponential backoff, configurable timeouts
- createTransport(): Factory function that auto-detects transport from URL scheme (
http:///https://→ HTTP,ws:///wss://→ WebSocket)
HTTP and WebSocket endpoints can be mixed in the same strategy configuration. Call close() on the client when done to clean up WebSocket connections.
The ClientFactory provides type-safe client instantiation based on chain IDs:
import { ClientFactory, BITCOIN_MAINNET } from "@openscan/network-connectors";
const config = {
type: "fallback" as const,
rpcUrls: ["https://rpc.example.com"]
};
// EVM client (numeric chain ID)
const ethClient = ClientFactory.createClient(1, config);
// ethClient is typed as EthereumClient
// Bitcoin client (CAIP-2 chain ID)
const btcClient = ClientFactory.createClient(BITCOIN_MAINNET, config);
// btcClient is typed as BitcoinClient
// Type-safe client with network-specific methods
const arbClient = ClientFactory.createTypedClient(42161, config);
// arbClient has Arbitrum-specific methods like arbtraceBlock()Each network has a dedicated client class extending NetworkClient:
- Fully typed with network-specific type definitions
- Network-specific RPC methods (e.g., Arbitrum traces, Optimism rollup methods)
- Inherits base Ethereum methods for compatible networks
- Strong TypeScript inference for return types
| Command | Description |
|---|---|
npm install |
Install project dependencies |
npm run build |
Compile TypeScript to JavaScript (output: dist/) |
npm run typecheck |
Type check without code emission |
npm run test |
Run full test suite (HTTP + WebSocket) |
npm run test:http |
Run HTTP transport tests only |
npm run test:wss |
Run WebSocket transport tests only |
npm run format |
Check code formatting (Biome) |
npm run format:fix |
Auto-fix formatting issues |
npm run lint |
Check linting rules (Biome) |
npm run lint:fix |
Auto-fix linting issues |
npm run check |
Combined format + lint check |
The project includes a GitHub Actions workflow (.github/workflows/npm-publish.yml) that automatically publishes to npm on every push to the main branch:
- Trigger: Push to
mainbranch - Environment: ubuntu-latest, Node.js 24
- Steps: Checkout → Setup Node.js → Install dependencies → Build → Publish
- Authentication: Uses OIDC authentication for npm publishing
- Node.js: Version 24 or higher
- npm: Comes with Node.js
-
Clone the repository:
git clone https://github.com/openscan-explorer/network-connectors.git cd network-connectors -
Install dependencies:
npm install
-
Build the project:
npm run build
-
Run tests to verify setup:
npm run test
Before committing, ensure your code passes all quality checks:
npm run check # Check formatting and linting
npm run typecheck # Check TypeScript types
npm run test # Run test suiteOr auto-fix issues:
npm run format:fix # Auto-fix formatting
npm run lint:fix # Auto-fix lintingnpm run test # Run all tests (HTTP + WebSocket)
npm run test:http # Run HTTP transport tests only
npm run test:wss # Run WebSocket transport tests onlyThe project uses Node.js native test framework with tsx for TypeScript execution. No external test frameworks like Jest or Mocha are required.
Tests are split by transport type to validate both HTTP and WebSocket:
- tests/http/strategies/: Strategy tests over HTTP transport
- tests/http/networks/: Network client tests over HTTP transport
- tests/http/factory/: ClientFactory tests
- tests/ws/strategies/: Strategy tests over WebSocket transport
- tests/ws/networks/: Network client tests over WebSocket (organized by chain ID subdirectories)
- tests/transport/: Transport layer tests (auto-detection, interface compliance)
- tests/helpers/: Shared test utilities
validators.ts: Validators for hex strings, addresses, blocks, transactions, receipts, logs, strategy metadataenv.ts: Test URL configuration with optional Alchemy API key support
- Real RPC calls only: All network client tests must call live RPC endpoints. Never mock RPC calls.
- Type validation: Tests must validate that response data matches the expected TypeScript type definitions. Each test is tagged:
[strong]: Validates response shape, field types, and format (e.g., hex strings, required fields)[weak]: Cannot fully validate response types (e.g., admin/debug methods unsupported on public nodes). Only checks that a result is returned.
To add support for a new blockchain network:
-
Create network directory:
mkdir -p src/networks/<CHAIN_ID>
-
Define network-specific types (if needed):
- Create types file for network-specific data structures
- Extend base Ethereum types if applicable
-
Create client class:
- Extend
NetworkClientbase class - Implement network-specific RPC methods
- Use
this.execute<T>(method, params)for all RPC calls - Add JSDoc comments for all public methods
- Extend
-
Update factory:
- Add chain ID to
SupportedChainIdtype in src/factory/ClientRegistry.ts - Update
ChainIdToClienttype mapping - Add case to
createClient()andcreateTypedClient()methods
- Add chain ID to
-
Export from index:
- Add exports to src/index.ts
-
Add tests:
- Create HTTP test file in
tests/http/networks/ - Create WebSocket test directory and file in
tests/ws/networks/<CHAIN_ID>/ - Test client instantiation, methods, and type safety
- Create HTTP test file in
-
Update documentation:
- Add network to supported networks table in README.md
- Document any special features or methods
To add new RPC methods to an existing network:
-
Add method to client class:
async methodName(param1: Type1, param2?: Type2): Promise<StrategyResult<ReturnType>> { const params: any[] = [param1]; if (param2 !== undefined) params.push(param2); return this.execute<ReturnType>("rpc_methodName", params); }
-
Define return type (if needed):
- Add type definition to appropriate types file
- Use existing types where possible
-
Add JSDoc comment:
/** * Brief description of what this method does * @param param1 Description of parameter * @param param2 Optional parameter description * @returns Promise with strategy result containing return type */
-
Add test coverage:
- Test success case
- Test error handling
- Test parameter validation
This project uses Biome for linting and formatting:
- Line Width: 100 characters
- Indentation: 2 spaces
- Quotes: Double quotes
- Semicolons: Required
- Trailing Commas: ES5 (no trailing commas in function parameters)
Run formatters before committing:
npm run format:fix # Auto-fix formatting
npm run lint:fix # Auto-fix linting issues-
Fork the repository
-
Create a feature branch:
git checkout -b feature/your-feature-name
-
Make your changes:
- Follow code style guidelines
- Add tests for new functionality
- Update documentation if needed
-
Run quality checks:
npm run check npm run typecheck npm run test -
Commit your changes:
git commit -m "feat: description of your changes" -
Push to your fork:
git push origin feature/your-feature-name
-
Open a pull request against the
mainbranch
-
Ensure you're on the
mainbranch with a clean working directory -
Update version in
package.jsonif needed -
Run the release script:
npm run release
-
The script will automatically:
- Validate environment
- Run all quality checks
- Build the project
- Publish to npm
- Create and push git tag
Every push to the main branch triggers automatic npm publication via GitHub Actions:
- Merge your PR to
main - GitHub Actions automatically builds and publishes
- Check Actions tab for workflow status
- Version is managed in
package.json - Follow Semantic Versioning:
- MAJOR: Breaking changes
- MINOR: New features (backwards compatible)
- PATCH: Bug fixes (backwards compatible)
TypeScript Configuration (tsconfig.json)
- Target: ES5 (broad compatibility)
- Module: ESNext (native ES modules)
- Output:
dist/directory - Type Declarations: Generated in
dist/types/ - Strict Mode: Enabled for maximum type safety
Biome Configuration (biome.json)
- Formatter: 100 char line width, 2-space indent
- Linter: Recommended rules with custom overrides
- File Patterns:
src/**/*.ts,tests/**/*.ts - Special Rules: Relaxed explicit any checks in test files
Package Configuration (package.json)
- Type:
"module"(ES modules) - Main Entry:
dist/index.js - Type Definitions:
dist/index.d.ts - Exports: Dual support for require/import
- Files: Only
dist/directory published to npm
- Repository: https://github.com/openscan-explorer/network-connectors
- Issues: https://github.com/openscan-explorer/network-connectors/issues
- Package: @openscan/network-connectors on npm
- License: MIT
- CLAUDE.md: Comprehensive AI assistant context file with detailed codebase documentation
- TypeScript Handbook: https://www.typescriptlang.org/docs/handbook/intro.html
- Biome Documentation: https://biomejs.dev/
- Node.js Test Framework: https://nodejs.org/api/test.html
For questions, issues, or contributions:
- Check existing issues: GitHub Issues
- Open a new issue: Provide detailed description, steps to reproduce, and environment info
- Contribute: Follow the contribution guidelines above
This project is licensed under the MIT License - see the LICENSE file for details.
Built with TypeScript, tested with Node.js, formatted with Biome.