// @jsx h // @jsxImportSource preact import eveApiExample from "../highlight/eve-api-example.ts" with { type: "text" }; import subscriptionExamples from "../highlight/subscription-examples.ts" with { type: "text" }; import websocketExample from "../highlight/websocket-example.ts" with { type: "text" }; import { useSyntaxHighlighting } from "../hooks/useSyntaxHighlighting.js"; import { CodeBlock } from "./CodeBlock.jsx"; /** * API Section - Comprehensive guide to available APIs * Covers window.eve API and WebSocket alternatives */ export const APISection = () => { useSyntaxHighlighting(); return (

API Reference

Understanding Arxlet APIs

Your Arxlet has access to powerful APIs that let you interact with Nostr data, manage user profiles, and create real-time applications. Think of these APIs as your toolkit for building social, decentralized applications within the CCN ecosystem.

Two approaches available: You can use the convenient window.eve API (recommended for most cases) or connect directly via WebSocket for advanced scenarios. Both give you full access to Nostr events and CCN features.

🎯 Which API Should You Use?

✨ window.eve API (Recommended)

Best for most Arxlets. This high-level API handles all the complex Nostr protocol details for you.

Simple promise-based functions
Automatic error handling
Built-in RxJS observables for real-time data
Profile and avatar helpers
Perfect for beginners

⚡ Direct WebSocket

For advanced use cases. Direct connection to the Nostr relay with full protocol control.

Maximum performance and control
Custom subscription management
Raw Nostr protocol access
! Requires Nostr protocol knowledge
! More complex error handling
💡 Our Recommendation: Start with window.eve for your first Arxlet. You can always switch to WebSocket later if you need more control or performance.
{/* window.eve API */}

🚀 window.eve API - Your Main Toolkit

The window.eve API is your primary interface for working with Nostr data in Arxlets. It provides simple, promise-based functions that handle all the complex protocol details behind the scenes.

How it works: Each function communicates with the local Nostr relay, processes the results, and returns clean JavaScript objects. No need to understand Nostr protocol internals - just call the functions and get your data.

📤 Publishing & Writing Data

publish(event)

Publishes a Nostr event to the relay. This is how you save data, post messages, or create any content.

Use cases: Posting messages, saving user preferences, creating notes, updating profiles

Promise<void>
signEvent(event)

Signs an unsigned Nostr event with the user's private key. Required before publishing most events.

Use cases: Preparing events for publication, authenticating user actions

Promise<NostrEvent>

🔍 Reading & Querying Data

getSingleEventById(id)

Retrieves a specific event when you know its exact ID. Perfect for loading specific posts or data.

Use cases: Loading a specific message, fetching referenced content, getting event details

Promise<NostrEvent | null>
getSingleEventWithFilter(filter)

Gets the first event matching your criteria. Useful when you expect only one result or want the most recent.

Use cases: Getting a user's latest profile, finding the most recent post, checking if something exists

Promise<NostrEvent | null>
getAllEventsWithFilter(filter)

Gets all events matching your criteria. Use this for lists, feeds, or when you need multiple results.

Use cases: Building feeds, loading message history, getting all posts by a user

Promise<NostrEvent[]>

🔄 Real-time Subscriptions

subscribeToEvents(filter)

Creates a live stream of events matching your filter. Your app updates automatically when new events arrive.

Use cases: Live chat, real-time feeds, notifications, collaborative features

Observable<NostrEvent>
subscribeToProfile(pubkey)

Watches for profile changes for a specific user. Updates automatically when they change their name, bio, avatar, etc.

Use cases: User profile displays, contact lists, member directories

Observable<Profile>

👤 User & Profile Helpers

getProfile(pubkey)

Retrieves user profile information (name, bio, avatar, etc.) for any user by their public key.

Use cases: Displaying user info, building contact lists, showing message authors

Promise<Profile | null>
getAvatar(pubkey)

Quick helper to get just the avatar URL from a user's profile. Saves you from parsing the full profile.

Use cases: Profile pictures, user avatars in lists, message author images

Promise<string | null>
publicKey

Gets the current user's public key. This identifies the user and is needed for many operations.

Use cases: Identifying the current user, filtering their content, permission checks

Promise<string>

Practical Example:

Here's how these functions work together in a real Arxlet. This example shows fetching events, displaying user profiles, and handling real-time updates:

{/* Real-time Subscriptions */}

🔄 Understanding Real-time Subscriptions

What are subscriptions? Think of subscriptions as "live feeds" that automatically notify your Arxlet when new data arrives. Instead of repeatedly asking "is there new data?", subscriptions push updates to you instantly.

How they work: When you subscribe to events or profiles, you get an RxJS Observable - a stream of data that flows over time. Your Arxlet can "listen" to this stream and update the UI whenever new data arrives.

Why use them? Subscriptions make your Arxlet feel alive and responsive. Users see new messages instantly, profile changes update immediately, and collaborative features work in real-time.

🎯 Event Subscriptions

subscribeToEvents(filter) gives you a live stream of events matching your criteria.

Perfect for:
  • Live chat applications
  • Real-time feeds and timelines
  • Notification systems
  • Collaborative tools
  • Activity monitoring

👤 Profile Subscriptions

subscribeToProfile(pubkey) watches for changes to a specific user's profile.

Perfect for:
  • User profile displays
  • Contact lists that stay current
  • Member directories
  • Avatar/name displays
  • User status indicators

How to Use Subscriptions:

Here's a complete example showing how to set up subscriptions, handle incoming data, and clean up properly:

! Memory Management

Always call unsubscribe() when:

  • Your component unmounts
  • User navigates away
  • You no longer need the data
  • Your Arxlet is closing

Why? Prevents memory leaks and unnecessary disk i/o.

✨ Pro Tips

  • Use specific filters to reduce data volume
  • Debounce rapid updates for better UX
  • Cache data to avoid duplicate processing
  • Handle errors gracefully with catchError
  • Consider using takeUntil for automatic cleanup
{/* WebSocket Alternative */}

🔌 Direct WebSocket Connection - Advanced Usage

What is the WebSocket approach? Instead of using the convenient window.eve{" "} API, you can connect directly to the Nostr relay at ws://localhost:6942 and speak the raw Nostr protocol.

Why would you use this? Direct WebSocket gives you maximum control and performance. You can implement custom subscription logic, handle multiple concurrent subscriptions efficiently, or integrate with existing Nostr libraries.

The trade-off: You'll need to understand the Nostr protocol, handle JSON message parsing, manage connection states, and implement your own error handling. It's more work but gives you complete flexibility.

WebSocket Implementation Example:

Here's how to establish a WebSocket connection and communicate using standard Nostr protocol messages:

✨ Use window.eve When:

Building your first Arxlet
You want simple, clean code
Standard CRUD operations are enough
You prefer promise-based APIs
Built-in RxJS observables work for you
You don't need custom protocol handling

⚡ Use WebSocket When:

You need maximum performance
Custom subscription management required
Integrating existing Nostr libraries
You understand the Nostr protocol
Need fine-grained connection control
Building high-frequency applications

🎯 Choosing the Right Approach

Start with window.eve: Even if you think you might need WebSocket later, begin with the high-level API. You can always refactor specific parts to use WebSocket once you understand your performance requirements.

Hybrid approach: Many successful Arxlets use window.eve for most operations and WebSocket only for specific high-performance features like real-time chat or live collaboration.

Migration path: The data structures are the same, so you can gradually migrate from{" "} window.eve to WebSocket for specific features without rewriting your entire application.

{/* Best Practices */}

💡 Best Practices for Robust Arxlets

🛡 Error Handling & Reliability

Always use try-catch blocks:

Network requests can fail, relays can be down, or data might be malformed. Wrap all API calls to prevent crashes.

Check for null/undefined returns:

Query methods return null when no data is found. Always check before using the result.

Provide meaningful user feedback:

Show loading states, error messages, and success confirmations. Users should know what's happening.

Implement retry logic for critical operations:

Publishing events or loading essential data should retry on failure with exponential backoff.

⚡ Performance & Efficiency

Use specific, narrow filters:

Instead of fetching all events and filtering in JavaScript, use precise Nostr filters to reduce data transfer.

Cache frequently accessed data:

Profile information, avatars, and static content should be cached to avoid repeated API calls.

Implement pagination for large datasets:

Don't load thousands of events at once. Use limit and until parameters for pagination.

Debounce rapid user actions:

If users can trigger API calls quickly (like typing in search), debounce to avoid overwhelming the relay.

Unsubscribe from observables:

Always clean up subscriptions to prevent memory leaks and unnecessary network traffic.

🎯 User Experience

Show loading states:

Use spinners, skeletons, or progress indicators while data loads. Empty screens feel broken.

Handle empty states gracefully:

When no data is found, show helpful messages or suggestions rather than blank areas.

Implement optimistic updates:

Update the UI immediately when users take actions, then sync with the server. Makes apps feel faster.

Provide offline indicators:

Let users know when they're disconnected or when operations might not work.

🔒 Security & Privacy

Validate all user inputs:

Never trust user input. Validate, sanitize, and escape data before using it in events or UI.

Be mindful of public data:

Remember that events are visible to everyone in your CCN by default. Don't accidentally expose private information.

Handle signing errors gracefully:

Users might reject signing requests. Always have fallbacks and clear error messages.

Respect user privacy preferences:

Some users prefer pseudonymous usage. Don't force real names or personal information.

🚀 Quick Checklist for Production Arxlets

Code Quality:
  • All API calls wrapped in try-catch
  • Null checks before using data
  • Subscriptions properly cleaned up
  • Input validation implemented
User Experience:
  • Loading states for all async operations
  • Error messages are user-friendly
  • Empty states handled gracefully
  • Performance tested with large datasets
); };