Skip to main content

Your First Integration

This guide walks you through creating your first integration with Starbloom, focusing on practical examples and common use cases.

Choose Your Integration Type​

Starbloom offers several integration patterns based on your needs:

1. Data Consumption​

  • REST API for historical data
  • WebSocket/SSE for real-time data
  • Batch processing for large datasets

2. Data Production​

  • Custom source connectors
  • Protocol integrations
  • Smart contract monitoring

Example: Market Data Integration​

Let's build a simple market data monitor that tracks Ethereum-based DEX trades.

1. Basic REST API Integration​

market-monitor.ts
import { StarbloomClient } from '@starbloom-ai/client';

async function getRecentTrades() {
const endpoint = 'starbloom.uniswap.1_0_0.Swap';
const params = new URLSearchParams({
limit: '10',
order: 'desc'
});

try {
const response = await fetch(
`https://api.starbloom.ai/v1/data/${endpoint}?${params}`,
{
headers: {
'Authorization': `Bearer ${process.env.STARBLOOM_API_KEY}`,
'Origin': process.env.ORIGIN
}
}
);

const trades = await response.json();
return trades.map(formatTrade);
} catch (error) {
console.error('Failed to fetch trades:', error);
throw error;
}
}

function formatTrade(trade: any) {
return {
timestamp: new Date(trade.ts).toISOString(),
tokenIn: trade.tokenIn,
tokenOut: trade.tokenOut,
amountIn: trade.amountIn,
amountOut: trade.amountOut
};
}

2. Real-time WebSocket Integration​

real-time-monitor.ts
class MarketMonitor {
private ws: WebSocket;
private reconnectAttempts = 0;
private maxReconnectAttempts = 5;

constructor(private apiKey: string) {
this.connect();
}

private connect() {
this.ws = new WebSocket(
`wss://stream.starbloom.ai/ws/v1/${this.apiKey}?topics=starbloom.uniswap.1_0_0.Swap`
);

this.ws.onopen = this.handleOpen.bind(this);
this.ws.onmessage = this.handleMessage.bind(this);
this.ws.onclose = this.handleClose.bind(this);
this.ws.onerror = this.handleError.bind(this);
}

private handleOpen() {
console.log('Connected to Starbloom WebSocket');
this.reconnectAttempts = 0;
}

private handleMessage(event: MessageEvent) {
const trade = JSON.parse(event.data);
this.processTrade(trade);
}

private handleClose() {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++;
console.log(`Reconnecting... Attempt ${this.reconnectAttempts}`);
setTimeout(() => this.connect(), 1000 * Math.pow(2, this.reconnectAttempts));
}
}

private handleError(error: Event) {
console.error('WebSocket error:', error);
}

private processTrade(trade: any) {
// Implement your trade processing logic here
console.log('New trade:', formatTrade(trade));
}

public close() {
this.ws.close();
}
}

3. Combined Integration Example​

Here's a complete example that combines historical and real-time data:

market-dashboard.ts
class MarketDashboard {
private monitor: MarketMonitor;
private trades: any[] = [];

constructor(private apiKey: string) {
this.monitor = new MarketMonitor(apiKey);
this.initialize();
}

private async initialize() {
try {
// Load historical data first
const recentTrades = await getRecentTrades();
this.trades = recentTrades;

// Start real-time monitoring
this.monitor = new MarketMonitor(this.apiKey);

// Update dashboard every 5 seconds
setInterval(() => this.updateMetrics(), 5000);
} catch (error) {
console.error('Failed to initialize dashboard:', error);
}
}

private updateMetrics() {
const lastHour = new Date(Date.now() - 3600000);
const recentTrades = this.trades.filter(t =>
new Date(t.timestamp) > lastHour
);

const metrics = {
tradeCount: recentTrades.length,
volume: this.calculateVolume(recentTrades),
averageSize: this.calculateAverageSize(recentTrades)
};

console.log('Updated metrics:', metrics);
}

private calculateVolume(trades: any[]): number {
return trades.reduce((sum, trade) => sum + Number(trade.amountIn), 0);
}

private calculateAverageSize(trades: any[]): number {
if (trades.length === 0) return 0;
return this.calculateVolume(trades) / trades.length;
}

public close() {
this.monitor.close();
}
}

// Usage
const dashboard = new MarketDashboard(process.env.STARBLOOM_API_KEY!);

Error Handling​

Implement proper error handling for production use:

error-handling.ts
class StarbloomError extends Error {
constructor(
message: string,
public statusCode?: number,
public retryable: boolean = false
) {
super(message);
this.name = 'StarbloomError';
}
}

async function handleStarbloomRequest<T>(
request: Promise<T>,
retries = 3
): Promise<T> {
try {
return await request;
} catch (error) {
if (error.statusCode === 429 && retries > 0) {
// Rate limit hit - implement backoff
await new Promise(resolve =>
setTimeout(resolve, 1000 * (4 - retries))
);
return handleStarbloomRequest(request, retries - 1);
}
throw new StarbloomError(
error.message,
error.statusCode,
error.statusCode >= 500
);
}
}

Best Practices​

  1. Error Handling

    • Always implement retry logic with backoff
    • Handle WebSocket disconnections gracefully
    • Log errors appropriately
  2. Data Management

    • Cache frequently accessed data
    • Implement data cleanup for memory management
    • Use appropriate data structures for your use case
  3. Resource Management

    • Close WebSocket connections when not in use
    • Implement connection pooling for multiple streams
    • Monitor resource usage

Troubleshooting Common Issues​

  • No data received: Check topic names and authentication
  • Slow responses: Review rate limits and connection quality
  • Memory issues: Implement data cleanup and pagination
  • Connection drops: Implement reconnection logic

Need help? Join our Discord community or email our support team.