W3MSG Protocol Abstraction Layer - Usage Examples
This document provides practical usage examples for implementing the W3MSG Protocol Abstraction Layer in various scenarios.
Table of Contents
- Basic Setup
- Message Sending
- Protocol Switching
- Error Handling
- Health Monitoring
- Advanced Configurations
- Integration Examples
Basic Setup
Simple Initialization
import { W3MSGSDK } from '@w3msg/sdk';
import { ethers } from 'ethers';
async function initializeBasicSDK() {
// Connect to wallet
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
// Initialize W3MSG SDK
const w3msg = new W3MSGSDK({
signer,
environment: 'production'
});
await w3msg.initialize();
console.log('W3MSG SDK initialized successfully');
return w3msg;
}
Advanced Configuration
async function initializeAdvancedSDK() {
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const w3msg = new W3MSGSDK({
signer,
protocols: ['xmtp', 'push'],
environment: 'production',
apiKeys: {
'push': process.env.PUSH_API_KEY
},
endpoints: {
'xmtp': 'wss://production.xmtp.network',
'push': 'https://backend.push.org'
},
relayEndpoint: 'https://relay.w3msg.app',
retryPolicy: {
maxRetries: 5,
baseDelay: 1000,
backoffStrategy: 'exponential_jitter',
timeoutMs: 30000
},
healthMonitoring: {
intervalMs: 30000,
timeoutMs: 5000,
alertThresholds: {
errorRate: 0.1,
latencyMs: 3000,
uptimePercent: 95
}
},
circuitBreaker: {
failureThreshold: 5,
recoveryTimeout: 30000,
halfOpenRetries: 3
}
});
// Set up event listeners
w3msg.on('protocol:switched', (event) => {
console.log(`Protocol switched: ${event.from} → ${event.to} (${event.reason})`);
});
w3msg.on('health:alert', (alert) => {
if (alert.severity === 'HIGH' || alert.severity === 'CRITICAL') {
console.warn(`Health Alert: ${alert.message}`);
}
});
await w3msg.initialize();
return w3msg;
}
Environment-Specific Setup
// Development environment
const devConfig = {
signer,
environment: 'development' as const,
endpoints: {
'xmtp': 'wss://dev.xmtp.network',
'push': 'https://backend-staging.push.org'
},
retryPolicy: 'aggressive' as const,
healthMonitoring: true
};
// Production environment
const prodConfig = {
signer,
environment: 'production' as const,
protocols: ['xmtp', 'push'],
retryPolicy: 'conservative' as const,
healthMonitoring: {
intervalMs: 60000, // Check every minute in prod
alertThresholds: {
errorRate: 0.05, // 5% error rate threshold
latencyMs: 2000,
uptimePercent: 99
}
},
circuitBreaker: true
};
Message Sending
Basic Chat Messages
async function sendChatMessage(w3msg: W3MSGSDK) {
try {
// Send simple text message
const result = await w3msg.send({
to: '0x742d35Cc6634C0532925a3b8D900b5dF5D7F3E8a',
content: 'Hello from W3MSG!',
type: 'chat'
});
console.log('Message sent:', {
id: result.id,
status: result.status,
protocol: result.protocol
});
return result;
} catch (error) {
console.error('Failed to send message:', error);
throw error;
}
}
Rich Content Messages
async function sendRichMessage(w3msg: W3MSGSDK) {
const result = await w3msg.send({
to: '0x742d35Cc6634C0532925a3b8D900b5dF5D7F3E8a',
content: {
title: 'W3MSG Notification',
body: 'You have received a new message from the W3MSG SDK!',
image: 'https://example.com/image.png',
cta: 'View Message',
url: 'https://app.w3msg.com/messages/123'
},
type: 'notification',
metadata: {
priority: 'high',
category: 'social',
tags: ['important', 'notification']
}
});
return result;
}
Bulk Message Sending
async function sendBulkMessages(w3msg: W3MSGSDK, recipients: string[]) {
const results = await Promise.allSettled(
recipients.map(async (recipient) => {
return await w3msg.send({
to: recipient,
content: 'Bulk message from W3MSG!',
type: 'chat',
metadata: {
bulkId: crypto.randomUUID(),
timestamp: Date.now()
}
});
})
);
const successful = results.filter(r => r.status === 'fulfilled').length;
const failed = results.filter(r => r.status === 'rejected').length;
console.log(`Bulk send completed: ${successful} successful, ${failed} failed`);
return results;
}
Group Messaging
async function createGroupConversation(w3msg: W3MSGSDK) {
// Check if current protocol supports group chat
const protocol = w3msg.getCurrentProtocol();
if (!protocol) {
throw new Error('No protocol selected');
}
const capabilities = await protocol.getCapabilities();
if (!capabilities.groupChat) {
console.log('Current protocol does not support group chat, switching...');
await w3msg.switchProtocol('xmtp'); // XMTP supports group chat
}
// Create group conversation
const participants = [
'0x742d35Cc6634C0532925a3b8D900b5dF5D7F3E8a',
'0x8ba1f109551bD432803012645Hac136c4L5bF4Ab',
'0x95cED938F7991cd0dFcb48F0a06a40FA1aF46EBC'
];
const conversation = await protocol.createConversation(participants);
// Send group message
const result = await w3msg.send({
to: participants[0], // In group context, this might be the conversation ID
content: 'Hello everyone in the group!',
conversationId: conversation.id,
type: 'chat',
metadata: {
isGroup: true,
participants: participants.length
}
});
return { conversation, message: result };
}
Protocol Switching
Manual Protocol Switching
async function demonstrateProtocolSwitching(w3msg: W3MSGSDK) {
// Get available protocols
const protocols = w3msg.getAvailableProtocols();
console.log('Available protocols:', protocols);
// Send message with XMTP
await w3msg.switchProtocol('xmtp');
const xmtpResult = await w3msg.send({
to: '0x742d35Cc6634C0532925a3b8D900b5dF5D7F3E8a',
content: 'Message sent via XMTP',
type: 'chat'
});
console.log('XMTP message result:', xmtpResult);
// Switch to Push Protocol for notifications
await w3msg.switchProtocol('push');
const pushResult = await w3msg.send({
to: '0x742d35Cc6634C0532925a3b8D900b5dF5D7F3E8a',
content: {
title: 'Push Notification',
body: 'Message sent via Push Protocol'
},
type: 'notification'
});
console.log('Push Protocol result:', pushResult);
}
Automatic Failover
async function setupAutomaticFailover(w3msg: W3MSGSDK) {
// Configure automatic protocol switching
await w3msg.updateConfig({
switchingStrategy: {
healthWeight: 0.5, // 50% - Prioritize healthy protocols
preferenceWeight: 0.2, // 20% - User preferences
featureWeight: 0.2, // 20% - Feature compatibility
latencyWeight: 0.1 // 10% - Response time
}
});
// Set up event listeners for failover
w3msg.on('protocol:switched', (event) => {
console.log(`Automatic failover: ${event.from} → ${event.to}`);
console.log(`Reason: ${event.reason}`);
});
// Send message with automatic failover
try {
const result = await w3msg.send({
to: '0x742d35Cc6634C0532925a3b8D900b5dF5D7F3E8a',
content: 'Message with automatic failover',
type: 'chat'
});
console.log('Message sent successfully:', result);
} catch (error) {
console.error('All protocols failed:', error);
}
}
Protocol Health-Based Selection
async function healthBasedProtocolSelection(w3msg: W3MSGSDK) {
const healthReport = w3msg.getHealth();
console.log('Overall health:', healthReport.overallHealth);
console.log(`Healthy protocols: ${healthReport.healthyCount}/${healthReport.protocolCount}`);
// Find the healthiest protocol
const healthiestProtocol = healthReport.protocols
.filter(p => p.status.isHealthy)
.sort((a, b) => {
// Sort by uptime (descending) and latency (ascending)
if (a.status.uptime !== b.status.uptime) {
return b.status.uptime - a.status.uptime;
}
return a.status.latency - b.status.latency;
})[0];
if (healthiestProtocol) {
console.log(`Switching to healthiest protocol: ${healthiestProtocol.name}`);
await w3msg.switchProtocol(healthiestProtocol.name);
}
// Send message using the healthiest protocol
const result = await w3msg.send({
to: '0x742d35Cc6634C0532925a3b8D900b5dF5D7F3E8a',
content: 'Message sent via healthiest protocol',
type: 'chat'
});
return result;
}
Error Handling
Basic Error Handling
async function handleBasicErrors(w3msg: W3MSGSDK) {
try {
const result = await w3msg.send({
to: '0x742d35Cc6634C0532925a3b8D900b5dF5D7F3E8a',
content: 'Test message',
type: 'chat'
});
return result;
} catch (error) {
if (error instanceof ProtocolError) {
console.error('Protocol error occurred:', {
category: error.category,
severity: error.severity,
protocol: error.protocol,
message: error.message
});
// Check if recovery is possible
if (error.recovery?.canRetry) {
console.log(`Retrying in ${error.recovery.retryAfterMs}ms`);
// RetryManager will handle automatic retry
}
// Check for fallback options
if (error.recovery?.fallbackAvailable) {
console.log('Fallback protocol available, attempting switch');
// Protocol switching will be handled automatically
}
} else {
console.error('Unexpected error:', error);
}
}
}
Advanced Error Recovery
async function advancedErrorRecovery(w3msg: W3MSGSDK) {
const maxAttempts = 3;
let attempt = 0;
while (attempt < maxAttempts) {
try {
const result = await w3msg.send({
to: '0x742d35Cc6634C0532925a3b8D900b5dF5D7F3E8a',
content: 'Message with advanced error recovery',
type: 'chat'
});
return result;
} catch (error) {
attempt++;
if (error instanceof ProtocolError) {
switch (error.category) {
case ErrorCategory.NETWORK:
console.log(`Network error on attempt ${attempt}, retrying...`);
await new Promise(resolve => setTimeout(resolve, 2000 * attempt));
break;
case ErrorCategory.RATE_LIMIT:
const retryAfter = error.recovery?.retryAfterMs || 60000;
console.log(`Rate limited, waiting ${retryAfter}ms`);
await new Promise(resolve => setTimeout(resolve, retryAfter));
break;
case ErrorCategory.AUTHENTICATION:
console.log('Authentication error, requesting wallet reconnection');
await w3msg.connect(); // Reconnect wallet
break;
case ErrorCategory.PROTOCOL_INIT:
console.log('Protocol initialization failed, trying different protocol');
const availableProtocols = w3msg.getAvailableProtocols();
const currentProtocol = w3msg.getCurrentProtocol();
const alternativeProtocol = availableProtocols.find(p => p !== currentProtocol);
if (alternativeProtocol) {
await w3msg.switchProtocol(alternativeProtocol);
}
break;
default:
console.error('Unrecoverable error:', error);
throw error;
}
} else {
throw error;
}
}
}
throw new Error(`Failed to send message after ${maxAttempts} attempts`);
}
Error Categorization and Logging
class MessageLogger {
private errors: ProtocolError[] = [];
async sendWithLogging(w3msg: W3MSGSDK, params: SendMessageParams) {
try {
const result = await w3msg.send(params);
this.logSuccess(result);
return result;
} catch (error) {
if (error instanceof ProtocolError) {
this.logError(error);
await this.handleError(error, w3msg, params);
}
throw error;
}
}
private logSuccess(result: MessageResult) {
console.log(`✅ Message sent successfully:`, {
id: result.id,
protocol: result.protocol,
timestamp: result.timestamp
});
}
private logError(error: ProtocolError) {
this.errors.push(error);
const logLevel = this.getLogLevel(error.severity);
console[logLevel](`❌ Protocol error:`, {
category: error.category,
severity: error.severity,
protocol: error.protocol,
method: error.method,
message: error.message,
timestamp: error.timestamp
});
}
private getLogLevel(severity: ErrorSeverity): 'log' | 'warn' | 'error' {
switch (severity) {
case ErrorSeverity.LOW: return 'log';
case ErrorSeverity.MEDIUM: return 'log';
case ErrorSeverity.HIGH: return 'warn';
case ErrorSeverity.CRITICAL: return 'error';
default: return 'error';
}
}
private async handleError(error: ProtocolError, w3msg: W3MSGSDK, params: SendMessageParams) {
// Implement custom error handling logic
switch (error.category) {
case ErrorCategory.BROWSER_UNSUPPORTED:
await this.handleBrowserCompatibility(w3msg);
break;
case ErrorCategory.VC_VERIFICATION:
await this.handleVCVerification(params);
break;
// Add more error handling as needed
}
}
private async handleBrowserCompatibility(w3msg: W3MSGSDK) {
const compatibility = BrowserCompatibility.getInstance();
const report = compatibility.getW3MSGCompatibilityReport();
console.warn('Browser compatibility issues:', report.issues);
console.log('Recommendations:', report.recommendations);
}
private async handleVCVerification(params: SendMessageParams) {
console.warn('VC verification failed for message:', params.to);
// Implement VC-specific error handling
}
getErrorStats() {
const errorsByCategory = this.errors.reduce((acc, error) => {
acc[error.category] = (acc[error.category] || 0) + 1;
return acc;
}, {} as Record<string, number>);
return {
totalErrors: this.errors.length,
errorsByCategory,
criticalErrors: this.errors.filter(e => e.severity === ErrorSeverity.CRITICAL).length
};
}
}
Health Monitoring
Real-time Health Monitoring
import { healthMonitor } from '@w3msg/sdk';
async function setupHealthMonitoring() {
// Configure health monitoring
healthMonitor.configure({
intervalMs: 30000, // Check every 30 seconds
timeoutMs: 5000, // 5 second timeout
alertThresholds: {
errorRate: 0.1, // 10% error rate
latencyMs: 3000, // 3 second latency
uptimePercent: 95 // 95% uptime
}
});
// Set up event listeners
healthMonitor.on('health:protocol_checked', (event) => {
console.log(`Health check: ${event.protocolName} - ${event.isHealthy ? '✅' : '❌'}`);
});
healthMonitor.on('health:alert_created', (alert) => {
console.warn(`🚨 Health Alert [${alert.severity}]: ${alert.message}`);
if (alert.severity === 'CRITICAL') {
// Handle critical alerts
handleCriticalAlert(alert);
}
});
// Start monitoring
healthMonitor.startMonitoring();
console.log('Health monitoring started');
}
async function handleCriticalAlert(alert: HealthAlert) {
console.error('CRITICAL HEALTH ALERT:', alert);
// Implement critical alert handling
switch (alert.category) {
case 'health_check_failed':
// Protocol is completely down
console.log('Protocol down, enabling circuit breaker');
break;
case 'high_error_rate':
// High error rate detected
console.log('High error rate, switching protocols');
break;
case 'low_uptime':
// Low uptime detected
console.log('Low uptime, investigating issues');
break;
}
}
Health Trend Analysis
async function analyzeHealthTrends() {
const protocols = ['xmtp', 'push'];
for (const protocolName of protocols) {
const trend = healthMonitor.getHealthTrend(protocolName);
if (trend) {
console.log(`📊 Health Trend for ${protocolName}:`, {
trend: trend.trend,
confidence: `${(trend.confidence * 100).toFixed(1)}%`,
averageLatency: `${trend.averageLatency.toFixed(0)}ms`,
errorRate: `${(trend.errorRate * 100).toFixed(1)}%`,
uptime: `${trend.uptimePercent.toFixed(1)}%`
});
if (trend.issues.length > 0) {
console.warn(`Issues detected:`, trend.issues);
console.log(`Recommendations:`, trend.recommendations);
}
// Take action based on trends
if (trend.trend === 'degrading' && trend.confidence > 0.7) {
console.warn(`${protocolName} is degrading with high confidence`);
// Consider switching protocols or adjusting configuration
}
}
}
}
Custom Health Dashboard
class HealthDashboard {
private updateInterval: NodeJS.Timeout | null = null;
start() {
this.updateInterval = setInterval(() => {
this.updateDashboard();
}, 10000); // Update every 10 seconds
console.log('Health dashboard started');
}
stop() {
if (this.updateInterval) {
clearInterval(this.updateInterval);
this.updateInterval = null;
}
}
private updateDashboard() {
const report = healthMonitor.generateHealthReport();
console.clear();
console.log('🏥 W3MSG Health Dashboard');
console.log('========================');
console.log(`Overall Health: ${this.getHealthEmoji(report.overallHealth)} ${report.overallHealth.toUpperCase()}`);
console.log(`Protocols: ${report.healthyCount}/${report.protocolCount} healthy`);
console.log('');
// Protocol details
report.protocols.forEach(protocol => {
const emoji = protocol.status.isHealthy ? '✅' : '❌';
const latency = protocol.status.latency.toFixed(0);
const uptime = protocol.status.uptime.toFixed(1);
console.log(`${emoji} ${protocol.name.toUpperCase()}`);
console.log(` Latency: ${latency}ms | Uptime: ${uptime}% | Errors: ${protocol.status.errorCount}`);
if (protocol.alerts.length > 0) {
protocol.alerts.forEach(alert => {
console.log(` 🚨 ${alert.severity}: ${alert.message}`);
});
}
console.log('');
});
// System metrics
console.log('📊 System Metrics:');
console.log(` Total Requests: ${report.systemMetrics.totalRequests}`);
console.log(` Total Errors: ${report.systemMetrics.totalErrors}`);
console.log(` Average Latency: ${report.systemMetrics.averageLatency.toFixed(0)}ms`);
console.log(` Overall Uptime: ${report.systemMetrics.overallUptime.toFixed(1)}%`);
// Recommendations
if (report.recommendations.length > 0) {
console.log('');
console.log('💡 Recommendations:');
report.recommendations.forEach(rec => {
console.log(` - ${rec}`);
});
}
}
private getHealthEmoji(health: 'healthy' | 'degraded' | 'unhealthy'): string {
switch (health) {
case 'healthy': return '💚';
case 'degraded': return '💛';
case 'unhealthy': return '❤️';
default: return '⚪';
}
}
}
// Usage
const dashboard = new HealthDashboard();
dashboard.start();
// Stop after 5 minutes
setTimeout(() => {
dashboard.stop();
}, 5 * 60 * 1000);
Advanced Configurations
Custom Retry Policies
import { retryManager, BackoffStrategy } from '@w3msg/sdk';
// High-priority message retry policy
const criticalMessagePolicy = {
maxRetries: 7,
baseDelay: 500,
multiplier: 2,
backoffStrategy: BackoffStrategy.EXPONENTIAL_JITTER,
timeoutMs: 120000, // 2 minutes
shouldRetry: (error: any, attempt: number) => {
// Retry for network and rate limit errors
if (error instanceof ProtocolError) {
return error.category === ErrorCategory.NETWORK ||
error.category === ErrorCategory.RATE_LIMIT ||
(error.category === ErrorCategory.MESSAGE_SEND && attempt < 3);
}
return false;
},
onRetry: (error: any, attempt: number) => {
console.log(`Retry attempt ${attempt} for critical message:`, error.message);
}
};
async function sendCriticalMessage(w3msg: W3MSGSDK, params: SendMessageParams) {
return await retryManager.execute(
async () => await w3msg.send(params),
criticalMessagePolicy
);
}
Protocol-Specific Configuration
// XMTP-specific configuration
const xmtpConfig = {
signer,
environment: 'production' as const,
endpoints: {
'xmtp': 'wss://production.xmtp.network'
},
features: {
encryption: true,
groupChat: true,
messageHistory: true
},
retryPolicy: {
maxRetries: 3,
baseDelay: 1000,
backoffStrategy: BackoffStrategy.EXPONENTIAL
}
};
// Push Protocol specific configuration
const pushConfig = {
signer,
environment: 'production' as const,
apiKeys: {
'push': process.env.PUSH_API_KEY
},
endpoints: {
'push': 'https://backend.push.org'
},
features: {
browserNotifications: true,
serviceWorker: true
},
retryPolicy: {
maxRetries: 5,
baseDelay: 2000,
backoffStrategy: BackoffStrategy.LINEAR
}
};
Circuit Breaker Configuration
import { CircuitBreaker } from '@w3msg/sdk';
// Create protocol-specific circuit breakers
const xmtpBreaker = CircuitBreaker.createForProtocol('xmtp');
const pushBreaker = CircuitBreaker.createForProtocol('push');
// Configure circuit breakers
xmtpBreaker.updateConfig({
failureThreshold: 3, // Open after 3 failures
recoveryTimeout: 30000, // Try recovery after 30 seconds
halfOpenRetries: 2, // Allow 2 tries in half-open state
exponentialBackoff: true
});
pushBreaker.updateConfig({
failureThreshold: 5, // More tolerant for push notifications
recoveryTimeout: 60000, // Longer recovery time
halfOpenRetries: 1,
exponentialBackoff: true
});
// Monitor circuit breaker states
xmtpBreaker.on('stateChange', (newState, oldState) => {
console.log(`XMTP Circuit Breaker: ${oldState} → ${newState}`);
});
pushBreaker.on('stateChange', (newState, oldState) => {
console.log(`Push Circuit Breaker: ${oldState} → ${newState}`);
});
Integration Examples
React Application Integration
import React, { useEffect, useState } from 'react';
import { W3MSGSDK } from '@w3msg/sdk';
import { ethers } from 'ethers';
interface W3MSGContextType {
w3msg: W3MSGSDK | null;
isConnected: boolean;
currentProtocol: string | null;
health: any;
sendMessage: (params: any) => Promise<any>;
}
const W3MSGContext = React.createContext<W3MSGContextType | null>(null);
export const W3MSGProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [w3msg, setW3msg] = useState<W3MSGSDK | null>(null);
const [isConnected, setIsConnected] = useState(false);
const [currentProtocol, setCurrentProtocol] = useState<string | null>(null);
const [health, setHealth] = useState(null);
useEffect(() => {
const initializeW3MSG = async () => {
try {
// Connect to wallet
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
// Initialize SDK
const sdk = new W3MSGSDK({
signer,
environment: 'production',
healthMonitoring: true
});
// Set up event listeners
sdk.on('connected', () => setIsConnected(true));
sdk.on('disconnected', () => setIsConnected(false));
sdk.on('protocol:switched', (event) => {
setCurrentProtocol(event.to);
});
await sdk.initialize();
setW3msg(sdk);
setCurrentProtocol(sdk.getCurrentProtocol());
// Update health status periodically
const healthInterval = setInterval(() => {
const healthReport = sdk.getHealth();
setHealth(healthReport);
}, 30000);
return () => clearInterval(healthInterval);
} catch (error) {
console.error('Failed to initialize W3MSG:', error);
}
};
initializeW3MSG();
}, []);
const sendMessage = async (params: any) => {
if (!w3msg) throw new Error('W3MSG not initialized');
return await w3msg.send(params);
};
return (
<W3MSGContext.Provider value={{
w3msg,
isConnected,
currentProtocol,
health,
sendMessage
}}>
{children}
</W3MSGContext.Provider>
);
};
export const useW3MSG = () => {
const context = React.useContext(W3MSGContext);
if (!context) {
throw new Error('useW3MSG must be used within W3MSGProvider');
}
return context;
};
// Message component example
const MessageSender: React.FC = () => {
const { sendMessage, currentProtocol, isConnected } = useW3MSG();
const [recipient, setRecipient] = useState('');
const [message, setMessage] = useState('');
const [loading, setLoading] = useState(false);
const handleSend = async () => {
if (!recipient || !message) return;
setLoading(true);
try {
const result = await sendMessage({
to: recipient,
content: message,
type: 'chat'
});
console.log('Message sent:', result);
setMessage('');
} catch (error) {
console.error('Failed to send message:', error);
} finally {
setLoading(false);
}
};
return (
<div>
<p>Status: {isConnected ? '🟢 Connected' : '🔴 Disconnected'}</p>
<p>Protocol: {currentProtocol || 'None'}</p>
<input
type="text"
placeholder="Recipient address"
value={recipient}
onChange={(e) => setRecipient(e.target.value)}
/>
<textarea
placeholder="Message content"
value={message}
onChange={(e) => setMessage(e.target.value)}
/>
<button onClick={handleSend} disabled={!isConnected || loading}>
{loading ? 'Sending...' : 'Send Message'}
</button>
</div>
);
};
Express.js API Integration
import express from 'express';
import { W3MSGSDK } from '@w3msg/sdk';
import { ethers } from 'ethers';
const app = express();
app.use(express.json());
let w3msg: W3MSGSDK;
// Initialize W3MSG SDK
async function initializeSDK() {
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const signer = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
w3msg = new W3MSGSDK({
signer,
environment: 'production',
apiKeys: {
'push': process.env.PUSH_API_KEY
},
healthMonitoring: true,
retryPolicy: 'aggressive'
});
await w3msg.initialize();
console.log('W3MSG SDK initialized for API server');
}
// API endpoints
app.post('/api/send-message', async (req, res) => {
try {
const { to, content, type } = req.body;
if (!to || !content) {
return res.status(400).json({ error: 'Missing required fields' });
}
const result = await w3msg.send({
to,
content,
type: type || 'chat'
});
res.json({
success: true,
messageId: result.id,
protocol: result.protocol,
status: result.status
});
} catch (error) {
console.error('Failed to send message:', error);
res.status(500).json({
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
});
}
});
app.get('/api/health', (req, res) => {
const health = w3msg.getHealth();
const status = w3msg.getStatus();
res.json({
health: health.overallHealth,
protocols: health.protocols.map(p => ({
name: p.name,
healthy: p.status.isHealthy,
latency: p.status.latency
})),
connected: status.isConnected
});
});
app.get('/api/protocols', (req, res) => {
const protocols = w3msg.getAvailableProtocols();
const current = w3msg.getCurrentProtocol();
res.json({
available: protocols,
current: current
});
});
app.post('/api/switch-protocol', async (req, res) => {
try {
const { protocol } = req.body;
await w3msg.switchProtocol(protocol);
res.json({
success: true,
current: w3msg.getCurrentProtocol()
});
} catch (error) {
res.status(500).json({
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
});
}
});
// Start server
const PORT = process.env.PORT || 3000;
initializeSDK().then(() => {
app.listen(PORT, () => {
console.log(`W3MSG API server running on port ${PORT}`);
});
}).catch(console.error);
WebSocket Real-time Integration
import WebSocket from 'ws';
import { W3MSGSDK } from '@w3msg/sdk';
class W3MSGWebSocketServer {
private wss: WebSocket.Server;
private w3msg: W3MSGSDK;
private clients: Map<string, WebSocket> = new Map();
constructor(port: number) {
this.wss = new WebSocket.Server({ port });
this.setupWebSocketServer();
}
async initialize() {
// Initialize W3MSG SDK
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const signer = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
this.w3msg = new W3MSGSDK({
signer,
environment: 'production',
healthMonitoring: true
});
// Set up message listening
await this.w3msg.listen((message) => {
this.broadcastMessage(message);
});
await this.w3msg.initialize();
console.log('W3MSG WebSocket server initialized');
}
private setupWebSocketServer() {
this.wss.on('connection', (ws, req) => {
const clientId = crypto.randomUUID();
this.clients.set(clientId, ws);
console.log(`Client connected: ${clientId}`);
ws.on('message', async (data) => {
try {
const message = JSON.parse(data.toString());
await this.handleClientMessage(clientId, message);
} catch (error) {
ws.send(JSON.stringify({
type: 'error',
error: 'Invalid message format'
}));
}
});
ws.on('close', () => {
this.clients.delete(clientId);
console.log(`Client disconnected: ${clientId}`);
});
// Send initial status
ws.send(JSON.stringify({
type: 'connected',
clientId,
protocols: this.w3msg.getAvailableProtocols(),
currentProtocol: this.w3msg.getCurrentProtocol()
}));
});
}
private async handleClientMessage(clientId: string, message: any) {
const client = this.clients.get(clientId);
if (!client) return;
try {
switch (message.type) {
case 'send_message':
const result = await this.w3msg.send({
to: message.to,
content: message.content,
type: message.messageType || 'chat'
});
client.send(JSON.stringify({
type: 'message_sent',
messageId: result.id,
status: result.status,
protocol: result.protocol
}));
break;
case 'switch_protocol':
await this.w3msg.switchProtocol(message.protocol);
client.send(JSON.stringify({
type: 'protocol_switched',
protocol: message.protocol
}));
break;
case 'get_health':
const health = this.w3msg.getHealth();
client.send(JSON.stringify({
type: 'health_report',
health: health
}));
break;
default:
client.send(JSON.stringify({
type: 'error',
error: 'Unknown message type'
}));
}
} catch (error) {
client.send(JSON.stringify({
type: 'error',
error: error instanceof Error ? error.message : 'Unknown error'
}));
}
}
private broadcastMessage(message: any) {
const broadcast = JSON.stringify({
type: 'message_received',
message: message
});
this.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(broadcast);
}
});
}
}
// Usage
const server = new W3MSGWebSocketServer(8080);
server.initialize().catch(console.error);
These examples demonstrate various ways to integrate and use the W3MSG Protocol Abstraction Layer in different scenarios, from basic message sending to advanced error handling and real-time integrations.