{"id":"a2bf015016a0d835eed3410597efed001dc8365801c19dbf944c1593da392929","pubkey":"266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5","created_at":1782768998,"kind":30817,"tags":[["d","nip-db"],["title","NIP-DB: Browser Nostr Event Database Interface"],["alt","Nostr Implementation Possibility: NIP-DB: Browser Nostr Event Database Interface"],["client","NostrHub"]],"content":"# NIP-DB: Browser Nostr Event Database Interface\n\n## Abstract\n\nThis NIP defines a standard interface for browser extensions that provide local Nostr event storage capabilities to web applications. The interface allows web applications to interact with Nostr events stored locally in the browser through a standardized `window.nostrdb` API.\n\n## Motivation\n\nBrowser extensions can provide valuable local storage and caching capabilities for Nostr events, improving performance and enabling offline functionality.\n\nThis NIP establishes a common interface that browser extensions can implement to provide Nostr event storage services to web applications.\n\n## Specification\n\n### Interface Definition\n\nBrowser extensions implementing this NIP MUST inject a `window.nostrdb` object that implements the following interface:\n\n```typescript\ninterface IWindowNostrDB {\n  /** Add an event to the database */\n  add(event: NostrEvent): Promise<boolean>;\n\n  /** Get a single event by ID */\n  event(id: string): Promise<NostrEvent | undefined>;\n\n  /** Get the latest version of a replaceable event */\n  replaceable(\n    kind: number,\n    author: string,\n    identifier?: string,\n  ): Promise<NostrEvent | undefined>;\n\n  /** Count the number of events matching filters */\n  count(filters: Filter | Filter[]): Promise<number>;\n\n  /** Check if the database backend supports features */\n  supports(): Promise<string[]>;\n\n  /** Get events by filters */\n  query(filters: Filter | Filter[]): Promise<NostrEvent[]>;\n\n  /** Subscribe to events in the database based on filters */\n  subscribe(filters: Filter | Filter[]): AsyncGenerator<NostrEvent>;\n}\n```\n\n### Feature Detection\n\nThe `supports()` method allows web applications to check for optional features:\n\n- `\"search\"` - NIP-50 full-text search capabilities\n\n### Implementation Requirements\n\n1. **Injection**: The interface MUST be injected into every web page via content scripts\n2. **Availability**: The interface MUST be available as `window.nostrdb` after DOM content is loaded\n3. **Error Handling**: All methods MUST handle errors gracefully and return appropriate error states\n4. **Thread Safety**: The interface MUST be safe to use from multiple contexts\n\n### Usage Examples\n\n#### Basic Event Operations\n\n```javascript\n// Add an event\nconst success = await window.nostrdb.add(nostrEvent);\n\n// Get a specific event\nconst event = await window.nostrdb.event(eventId);\n\n// Get latest replaceable event\nconst profile = await window.nostrdb.replaceable(0, pubkey);\n\n// Count events\nconst count = await window.nostrdb.count({ kinds: [1] });\n```\n\n#### Getting Events\n\n```javascript\n// Get events matching filters\nconst events = await window.nostrdb.query([{ kinds: [1] }]);\nconsole.log(\"Found events:\", events);\n```\n\n#### Subscribing to Events\n\n```javascript\n// Subscribe to events using an async iterator\nfor await (const event of window.nostrdb.subscribe([{ kinds: [1] }])) {\n  console.log(\"New event:\", event);\n}\n```\n\n#### Feature Detection\n\n```javascript\n// Get all supported features\nconst supportedFeatures = await window.nostrdb.supports();\n\n// Check for search support\nif (supportedFeatures.includes(\"search\")) {\n  // Use search functionality\n  const notes = await window.nostrdb.query({ kinds: [1], search: \"nostr\" });\n}\n```\n\n## Reference Implementation\n\nA reference implementation is available at: [nostr-bucket](https://github.com/hzrd149/nostr-bucket)","sig":"e6d232252583f637c0ef6a1ca6fab52d020d0052a4193caf14a93fc64a92de2ff5d1208c22d301dd09d58979b88ba4f2d65e630a170da6387289d328fd01401f"}