pulsar-sdk
v1.2.4
Published
Pulsar TypeScript SDK - Direct blockchain interaction library
Maintainers
Readme
Pulsar TypeScript/JavaScript SDK
100% on-chain messaging SDK for TypeScript and JavaScript.
Quick Links
- QuickStart Guide - Get started in 30 minutes
- Examples - Complete, runnable code examples
- API Reference - Full method documentation
- Troubleshooting - Common issues and solutions
Installation
npm install @pulsar/sdk
# or
yarn add @pulsar/sdk
# or
pnpm add @pulsar/sdkQuick Start
import { PulsarClient, CHAIN_CONFIGS } from '@pulsar/sdk';
// Initialize client
const client = new PulsarClient(CHAIN_CONFIGS.baseSepolia());
// Create application
const { applicationId } = await client.application.createApplication({
name: 'My App',
description: 'My decentralized app'
});
// Create topic
const { topicId } = await client.topic.createTopic({
applicationId,
name: 'my-topic',
isPrivate: false,
schemaId: 0,
retentionPeriod: 0n
});
// Send message
await client.messages.sendMessage({
topicId,
payload: { message: 'Hello, Pulsar!' }
});For a complete walkthrough, see the QuickStart Guide.
Configuration
Create a .env file in your project root:
# Required
PRIVATE_KEY=0x...
# RPC URLs (choose one per network)
BASE_SEPOLIA_RPC_URL=https://base-sepolia.g.alchemy.com/v2/YOUR_KEY
BASE_RPC_URL=https://mainnet.base.orgSecurity Note: Never commit .env to version control!
Available Networks
The SDK supports multiple networks via pre-configured chain settings:
import { PulsarClient, CHAIN_CONFIGS } from '@pulsar/sdk';
// Base Sepolia (testnet - recommended for development)
const client = new PulsarClient(CHAIN_CONFIGS.baseSepolia());
// Base Mainnet
const client = new PulsarClient(CHAIN_CONFIGS.base());
// Localhost (for local Hardhat node)
const client = new PulsarClient(CHAIN_CONFIGS.localhost());
// Custom configuration
const client = new PulsarClient({
chainId: ChainId.BASE_SEPOLIA,
privateKey: process.env.PRIVATE_KEY!,
rpcUrl: process.env.BASE_SEPOLIA_RPC_URL
});Features
- ✅ Application Management - Create and manage applications
- ✅ Topic Creation - Public and private topics with encryption
- ✅ Message Production - Send messages with automatic gas estimation
- ✅ Message Consumption - Consumer groups with offset management
- ✅ Access Control - Grant/revoke permissions for private topics
- ✅ Schema Registry - Register and validate message schemas
- ✅ Event Indexing - Query blockchain events efficiently
- ✅ Multi-Chain Support - Base, Ethereum, Arbitrum, Optimism, Avalanche
- ✅ TypeScript-First - Full type safety with IntelliSense
- ✅ Retry Logic - Automatic retries for transient failures
- ✅ Gas Optimization - Smart gas estimation with configurable buffers
Examples
The examples/ directory contains complete, runnable examples:
Basic Usage
npx ts-node examples/basic-usage.tsComplete workflow: create app, create topic, send messages, consume with consumer groups
Consumer Groups
npx ts-node examples/consumer-groups.tsAdvanced patterns: multiple consumer groups, auto-commit vs manual, batch processing
Comprehensive
npx ts-node examples/comprehensive.tsAll SDK features: public/private topics, access control, schemas, error handling
Advanced Features
npx ts-node examples/advanced-features.tsOptimization techniques: batching, event querying, performance monitoring
See examples/README.md for detailed example documentation.
API Overview
Client Initialization
import { PulsarClient, CHAIN_CONFIGS } from '@pulsar/sdk';
const client = new PulsarClient(CHAIN_CONFIGS.baseSepolia());Application Management
// Create application
const { applicationId } = await client.application.createApplication({
name: 'My App',
description: 'Description'
});
// Add team member
await client.application.addMember({
applicationId,
member: '0x...',
nickname: 'Alice'
});
// Get application details
const app = await client.application.getApplication(applicationId);Topic Management
// Create public topic
const { topicId } = await client.topic.createTopic({
applicationId,
name: 'general-chat',
isPrivate: false,
schemaId: 0,
retentionPeriod: 0n
});
// Create private topic (with encryption)
const { topicId } = await client.topic.createTopic({
applicationId,
name: 'private-data',
isPrivate: true,
schemaId: 0,
retentionPeriod: 0n
});
// Get topic details
const topic = await client.topic.getTopic(topicId);Message Production
// Send single message
const { txHash } = await client.messages.sendMessage({
topicId,
payload: {
type: 'notification',
message: 'Hello!',
timestamp: Date.now()
}
});
// Payload can be any JSON-serializable objectConsumer Groups & Consumption
// Create consumer group
const { groupId } = await client.consumerGroup.createConsumerGroup({
topicId,
groupName: 'notification-processor'
});
// Consume messages (auto-commit)
const result = await client.consumer.consumeMessages({
groupId,
limit: 100,
autoCommit: true
});
console.log(`Consumed ${result.messageCount} messages`);
result.messages.forEach(msg => {
console.log('Received:', msg.payload);
});
// Manual offset management
const result = await client.consumer.consumeMessages({
groupId,
limit: 100,
autoCommit: false
});
// Process messages...
// Commit offset manually
if (result.messages.length > 0) {
const lastMsg = result.messages[result.messages.length - 1];
await client.consumer.commitOffset({
groupId,
offset: lastMsg.blockNumber
});
}Access Control (Private Topics)
import { Permission } from '@pulsar/sdk';
// Grant permissions
await client.access.grantPermissions({
topicId,
member: '0x...',
permissions: Permission.READ_WRITE
});
// Revoke permissions
await client.access.revokePermissions({
topicId,
member: '0x...'
});
// Check permissions
const hasPermission = await client.access.checkPermissions({
topicId,
member: '0x...',
requiredPermission: Permission.READ
});For complete API documentation, see API.md.
Error Handling
import {
ValidationError,
NetworkError,
TransactionError,
PulsarError
} from '@pulsar/sdk';
try {
await client.messages.sendMessage({...});
} catch (error) {
if (error instanceof ValidationError) {
console.error('Invalid input:', error.message);
} else if (error instanceof NetworkError) {
console.error('Network issue:', error.message);
} else if (error instanceof TransactionError) {
console.error('Transaction failed:', error.txHash);
} else if (error instanceof PulsarError) {
console.error('Pulsar error:', error.message);
}
}TypeScript Support
The SDK is built with TypeScript and provides complete type definitions:
import type {
PulsarClient,
CreateApplicationParams,
CreateTopicParams,
SendMessageParams,
ApplicationResult,
TopicResult,
ConsumeResult
} from '@pulsar/sdk';
// All parameters are fully typed with IntelliSense
const params: CreateApplicationParams = {
name: 'My App',
description: 'Description'
};
const result: ApplicationResult = await client.application.createApplication(params);Testing
The SDK includes comprehensive test coverage:
# Run all tests
npm test
# Run with coverage
npm run test:coverage
# Run specific test file
npm test -- MessageProducerBuilding from Source
# Clone repository
git clone https://github.com/pulsar/sdk.git
cd sdk/packages/sdk
# Install dependencies
npm install
# Build
npm run build
# Run tests
npm testGet Test ETH
Need test ETH for Base Sepolia?
Troubleshooting
"Cannot find module '@pulsar/sdk'"
Build the package:
npm run build"Insufficient funds for gas"
- Get test ETH from faucets above
- Check balance:
await client.getBalance()
"Transaction reverted"
- Verify topic/application exists
- Check permissions for private topics
- Ensure valid payload (JSON-serializable)
RPC Connection Issues
- Verify RPC URL is correct
- Try alternative RPC provider
- Check network connectivity
For more solutions, see TROUBLESHOOTING.md.
Contributing
See CONTRIBUTING.md for contribution guidelines.
Changelog
See CHANGELOG.md for release history.
License
MIT
Support
- Documentation: Pulsar Docs
- GitHub Issues: Report bugs
- Discord: Join our community
Built with ❤️ by the Pulsar team
