### Install @nostr/tools Source: https://github.com/nbd-wtf/nostr-tools/blob/master/README.md Install the package using npm or npx. ```bash npx jsr add @nostr/tools ``` -------------------------------- ### Publish Event using Signer Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/signer-and-bunker.md Example of how to use a Signer implementation to get a public key and sign an event before publishing. ```typescript import type { Signer } from '@nostr/tools/signer' async function publishEvent(signer: Signer, event: EventTemplate) { const pubkey = await signer.getPublicKey() const signed = await signer.signEvent(event) console.log(`Published by ${pubkey}`) } ``` -------------------------------- ### Example Filter Usage Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/filters.md Demonstrates how to construct a Filter object to query events. This example specifies event kinds, authors, a time range, tag filters, and a limit. ```typescript import type { Filter } from '@nostr/tools/filter' const filter: Filter = { kinds: [1, 7], authors: ['author1', 'author2'], since: 1609459200, until: 1609545600, '#t': ['bitcoin', 'nostr'], limit: 100 } ``` -------------------------------- ### Filter Usage Example Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/filters.md An example demonstrating how to construct a Filter object with various criteria. ```APIDOC ## Example Filter ```typescript import type { Filter } from '@nostr/tools/filter' const filter: Filter = { kinds: [1, 7], authors: ['author1', 'author2'], since: 1609459200, until: 1609545600, '#t': ['bitcoin', 'nostr'], limit: 100 } ``` ``` -------------------------------- ### Import Core Nostr Tools for Client Building Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/00-START-HERE.md Import necessary functions for generating keys, getting public keys, finalizing events, and utilizing the SimplePool for relay management. Refer to API documentation for 'core-and-pure.md' and 'relay-and-pool.md'. ```typescript import { generateSecretKey, getPublicKey, finalizeEvent } from '@nostr/tools/pure' import { SimplePool } from '@nostr/tools/pool' // See: api-reference/core-and-pure.md // See: api-reference/relay-and-pool.md ``` -------------------------------- ### Create Public Chat Channel and Message (NIP-28) Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/additional-nips.md This example demonstrates creating a public chat channel (kind 40) and then sending a message within that channel (kind 42). Channel messages are tagged with the channel's ID. Requires the 'finalizeEvent' function. ```typescript const channelCreation = finalizeEvent({ kind: 40, created_at: Math.floor(Date.now() / 1000), tags: [], content: 'My Chat Channel' }, secretKey) const channelId = channelCreation.id const channelMessage = finalizeEvent({ kind: 42, created_at: Math.floor(Date.now() / 1000), tags: [['e', channelId]], content: 'Hello channel!' }, secretKey) ``` -------------------------------- ### Set Fetch Implementation for Node.js < v18 Source: https://github.com/nbd-wtf/nostr-tools/blob/master/README.md Provides a way to set a custom fetch implementation for older Node.js versions when using NIP-05 profile querying. Requires installing 'node-fetch@2'. ```javascript import { useFetchImplementation } from '@nostr/tools/nip05' useFetchImplementation(require('node-fetch')) ``` -------------------------------- ### get Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/relay-and-pool.md Queries a single event from one or more relays. ```APIDOC ## get ### Description Queries a single event from one or more relays (convenience method). ### Method `get` ### Parameters - **relays** (string[]) - Required - Array of relay URLs to query - **filter** (Filter) - Required - Filter to match against (typically should include `limit: 1`) ### Return type `Promise` — First matching event found, or null if none found. ### Timeout Uses the pool's `maxWaitForConnection` setting. ### Request Example ```typescript const pool = new SimplePool() const event = await pool.get( ['wss://relay.damus.io', 'wss://relay.primal.net'], { ids: ['d7dd5eb3ab747e16f8d0212d53032ea2a7cadef53837e5a6c66d42849fcb9027'] } ) if (event) { console.log('Found event:', event) } ``` ### Response None ### Response Example None ``` -------------------------------- ### Connecting to a Bunker (NIP-46) - Method 2: Client Initiated Source: https://github.com/nbd-wtf/nostr-tools/blob/master/README.md Initiates a connection to a remote NIP-46 signer (bunker) from the client side, typically for first-time connections via QR code. This method uses a `nostrconnect://` URI and the `BunkerSigner.fromURI()` which is asynchronous and resolves only after the bunker connects. ```APIDOC ## Connecting to a Bunker (NIP-46) - Method 2: Client Initiated ### Description Initiates a connection to a bunker from the client using a `nostrconnect://` URI. The `BunkerSigner.fromURI()` method is asynchronous and waits for the bunker to connect, returning an already connected signer. ### Method Signature `createNostrConnectURI(options: NostrConnectURIOptions): string` `BunkerSigner.fromURI(localSecretKey: string, uri: string, options: { pool: SimplePool }): Promise` ### Parameters #### `createNostrConnectURI` Parameters - **options** (object) - Required - Options for creating the URI. - **clientPubkey** (string) - Required - The public key of the client. - **relays** (string[]) - Required - List of relays the client can use. - **secret** (string) - Optional - A secret string to verify the bunker's response. - **name** (string) - Optional - The name of the client application. #### `BunkerSigner.fromURI` Parameters - **localSecretKey** (string) - Required - The client's local secret key for secure communication. - **uri** (string) - Required - The `nostrconnect://` URI generated by the client. - **options** (object) - Required - Configuration options. - **pool** (SimplePool) - Required - An instance of SimplePool for relay communication. ### Request Example ```js import { getPublicKey } from '@nostr/tools/pure' import { BunkerSigner, createNostrConnectURI } from '@nostr/tools/nip46' import { SimplePool } from '@nostr/tools/pool' const localSecretKey = generateSecretKey() const pool = new SimplePool() const clientPubkey = getPublicKey(localSecretKey) // generate a connection URI for the bunker to scan const connectionUri = createNostrConnectURI({ clientPubkey, relays: ['wss://relay.damus.io', 'wss://relay.primal.net'], secret: 'a-random-secret-string', name: 'My Awesome App' }) // wait for the bunker to connect const signer = await BunkerSigner.fromURI(localSecretKey, connectionUri, { pool }) // Use the connected bunker const pubkey = await signer.getPublicKey() const event = await signer.signEvent({ kind: 1, created_at: Math.floor(Date.now() / 1000), tags: [], content: 'Hello from a client-initiated connection!' }) // cleanup await signer.close() pool.close([]) ``` ### Response `BunkerSigner.fromURI` returns a `Promise` that resolves to a fully connected `BunkerSigner` instance. ``` -------------------------------- ### Connecting to a Bunker (NIP-46) - Method 1: Bunker Initiated Source: https://github.com/nbd-wtf/nostr-tools/blob/master/README.md Establishes a connection to a remote NIP-46 signer (bunker) when the bunker initiates the connection, typically using a `bunker://` URI. This method requires an explicit `connect()` call for the initial handshake. ```APIDOC ## Connecting to a Bunker (NIP-46) - Method 1: Bunker Initiated ### Description Connects to a bunker when the bunker initiates the connection using a `bunker://` URI. Requires an explicit `connect()` call for the initial authorization. ### Method Signature `BunkerSigner.fromBunker(localSecretKey: string, bunkerPointer: BunkerPointer, options: { pool: SimplePool }): BunkerSigner `await bunker.connect(): void` ### Parameters #### `BunkerSigner.fromBunker` Parameters - **localSecretKey** (string) - Required - The client's local secret key for secure communication. - **bunkerPointer** (BunkerPointer) - Required - Parsed input from a bunker URI or NIP-05 identifier. - **options** (object) - Required - Configuration options. - **pool** (SimplePool) - Required - An instance of SimplePool for relay communication. #### `bunker.connect()` Parameters None. ### Request Example ```js import { BunkerSigner, parseBunkerInput } from '@nostr/tools/nip46' import { SimplePool } from '@nostr/tools/pool' import { generateSecretKey } from '@nostr/tools/pure' const localSecretKey = generateSecretKey() const pool = new SimplePool() // parse a bunker URI const bunkerPointer = await parseBunkerInput('bunker://abcd...?relay=wss://relay.example.com') if (!bunkerPointer) { throw new Error('Invalid bunker input') } // create the bunker instance const bunker = BunkerSigner.fromBunker(localSecretKey, bunkerPointer, { pool }) await bunker.connect() // Establish connection for the first time // Use the connected bunker const pubkey = await bunker.getPublicKey() const event = await bunker.signEvent({ kind: 1, created_at: Math.floor(Date.now() / 1000), tags: [], content: 'Hello from bunker!' }) // cleanup await bunker.close() pool.close([]) ``` ### Response `BunkerSigner.fromBunker` returns a `BunkerSigner` instance. `bunker.connect()` returns void upon successful connection. ``` -------------------------------- ### BunkerSigner.fromBunker Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/signer-and-bunker.md Creates a BunkerSigner instance using an existing bunker configuration. This method does not establish a connection immediately; `await connect()` must be called on the returned instance. ```APIDOC ## BunkerSigner.fromBunker ### Description Create a BunkerSigner using an existing bunker configuration. ### Method Signature ```typescript static fromBunker( clientSecretKey: Uint8Array, bp: BunkerPointer, params?: BunkerSignerParams ): BunkerSigner ``` ### Parameters #### Path Parameters - **clientSecretKey** (Uint8Array) - Required - Your 32-byte secret key (for secure communication with bunker) - **bp** (BunkerPointer) - Required - Bunker pointer with pubkey and relays #### Query Parameters - **params.pool** (AbstractSimplePool) - Optional - Relay pool for communication. Defaults to `new SimplePool()`. - **params.onauth** (function) - Optional - Callback if bunker needs re-authentication. - **params.skipSwitchRelays** (boolean) - Optional - Skip switchRelays() call (for manual control). Defaults to `false`. ### Return type `BunkerSigner` - Instance ready to use after calling `await connect()`. ### Behavior - Creates a signer with the bunker's pubkey and secret - Does **not** establish connection immediately - Call `await bunker.connect()` on first use to authorize ### Example ```typescript import { BunkerSigner, parseBunkerInput } from '@nostr/tools/nip46' import { generateSecretKey } from '@nostr/tools/pure' import { SimplePool } from '@nostr/tools/pool' const clientSk = generateSecretKey() const bunkerPointer = await parseBunkerInput('bunker://pubkey...?relay=wss://...') const pool = new SimplePool() const signer = BunkerSigner.fromBunker(clientSk, bunkerPointer, { pool }) await signer.connect() // First time: requests authorization const pubkey = await signer.getPublicKey() ``` ``` -------------------------------- ### Get Public Key Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/signer-and-bunker.md Retrieves the public key that the bunker signer is authorized to sign as. The result is cached after the first call. ```typescript const pk = await signer.getPublicKey() console.log(`Signing as ${pk}`) ``` -------------------------------- ### Signer Interface Definition Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/signer-and-bunker.md Defines the abstract interface for event signing operations, including getting a public key and signing an event. ```typescript interface Signer { getPublicKey(): Promise signEvent(event: EventTemplate): Promise } ``` -------------------------------- ### Initialize SimplePool with Options Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/relay-and-pool.md Instantiate SimplePool with options to enable ping keep-alive or automatic reconnection. ```typescript import { SimplePool } from '@nostr/tools/pool' const pool = new SimplePool({ enablePing: true }) ``` -------------------------------- ### Check if a string is an NPub using NostrTypeGuard Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/nip19-bech32.md Example of using the `isNPub` type guard to validate a public key string. Ensure you have imported `NostrTypeGuard`. ```typescript import { NostrTypeGuard } from '@nostr/tools/nip19' const input = 'npub1...' if (NostrTypeGuard.isNPub(input)) { console.log('It\'s a public key') } ``` -------------------------------- ### Create and Connect to a Relay Simultaneously Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/relay-and-pool.md Use the static `connect` method to create a Relay instance and connect it in a single step. This is a convenient shortcut for instantiation and connection. ```typescript import { Relay } from '@nostr/tools/relay' const relay = await Relay.connect('wss://relay.damus.io') // relay is now connected ``` -------------------------------- ### Signer Interface Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/signer-and-bunker.md The Signer interface provides an abstract way to sign Nostr events. It defines methods for getting a public key and signing an event template. ```APIDOC ## Signer Interface ### Description Abstract interface for event signing. ### Methods - `getPublicKey()`: Async; returns the 64-char hex public key this signer controls. - `signEvent(event)`: Async; takes an EventTemplate, returns a fully signed VerifiedEvent. ### Usage Example ```typescript import type { Signer } from '@nostr/tools/signer' async function publishEvent(signer: Signer, event: EventTemplate) { const pubkey = await signer.getPublicKey() const signed = await signer.signEvent(event) console.log(`Published by ${pubkey}`) } ``` ``` -------------------------------- ### Get Event Hash Difficulty (TypeScript) Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/additional-nips.md Computes the difficulty of an event hash, represented by the number of leading zero bits. Use this to check the proof-of-work level of an existing event. ```typescript import { getEventHash } from '@nostr/tools/nip13' const event = { /* ... signed event ... */ } const difficulty = getEventHash(event) console.log(`Difficulty: ${difficulty} leading zeros`) ``` -------------------------------- ### Create Client-Initiated Connection URI (NIP-46) Source: https://github.com/nbd-wtf/nostr-tools/blob/master/README.md Generates a `nostrconnect://` URI for a client-initiated NIP-46 connection. This URI can be scanned by a bunker to establish a connection. The `BunkerSigner.fromURI` method is asynchronous and returns a connected signer. ```javascript import { getPublicKey } from '@nostr/tools/pure' import { BunkerSigner, createNostrConnectURI } from '@nostr/tools/nip46' import { SimplePool } from '@nostr/tools/pool' const clientPubkey = getPublicKey(localSecretKey) // generate a connection URI for the bunker to scan const connectionUri = createNostrConnectURI({ clientPubkey, relays: ['wss://relay.damus.io', 'wss://relay.primal.net'], secret: 'a-random-secret-string', // A secret to verify the bunker's response name: 'My Awesome App' }) // wait for the bunker to connect const pool = new SimplePool() const signer = await BunkerSigner.fromURI(localSecretKey, connectionUri, { pool }) // and use it const pubkey = await signer.getPublicKey() const event = await signer.signEvent({ kind: 1, created_at: Math.floor(Date.now() / 1000), tags: [], content: 'Hello from a client-initiated connection!' }) // cleanup await signer.close() pool.close([]) ``` -------------------------------- ### connect Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/signer-and-bunker.md Establishes a connection to the bunker and requests authorization. This method is primarily used for the `fromBunker()` flow. ```APIDOC ## connect ### Description Establishes connection and requests authorization from the bunker. ### Method `async connect(maxWaitOrAbort?: number | AbortSignal): Promise` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **maxWaitOrAbort** (number | AbortSignal) - Optional - Milliseconds to wait or AbortSignal. Defaults to 300000. ### Throws - Error: If connection fails or times out ### Behavior - Sends initial request to bunker - Waits for bunker approval - Sets up subscription to bunker relay - Only needed for `fromBunker()` flow; `fromURI()` already connected ### Request Example ```typescript const signer = BunkerSigner.fromBunker(clientSk, bunkerPointer) await signer.connect({ timeout: 10000 }) ``` ### Response #### Success Response (200) - None (Promise) #### Response Example None ``` -------------------------------- ### Get a Single Event with SimplePool Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/relay-and-pool.md Query for a single event matching the filter from the specified relays. Returns the first event found or null. Uses the pool's `maxWaitForConnection` for timeouts. ```typescript const pool = new SimplePool() const event = await pool.get( ['wss://relay.damus.io', 'wss://relay.primal.net'], { ids: ['d7dd5eb3ab747e16f8d0212d53032ea2a7cadef53837e5a6c66d42849fcb9027'] } ) if (event) { console.log('Found event:', event) } ``` -------------------------------- ### Interact with Relays using SimplePool Source: https://github.com/nbd-wtf/nostr-tools/blob/master/README.md Demonstrates querying for single and multiple events, publishing new events, and subscribing to events from one or more relays using the SimplePool utility. Ensure you have imported the necessary functions. ```javascript import { finalizeEvent, generateSecretKey, getPublicKey } from '@nostr/tools/pure' import { SimplePool } from '@nostr/tools/pool' const pool = new SimplePool() const relays = ['wss://relay.example.com', 'wss://relay.example2.com'] // let's query for one event that exists const event = pool.get( relays, { ids: ['d7dd5eb3ab747e16f8d0212d53032ea2a7cadef53837e5a6c66d42849fcb9027'], }, ) if (event) { console.log('it exists indeed on this relay:', event) } // let's query for more than one event that exists const events = pool.querySync( relays, { kinds: [1], limit: 10 }, ) if (events) { console.log('it exists indeed on this relay:', events) } // let's publish a new event while simultaneously monitoring the relay for it let sk = generateSecretKey() let pk = getPublicKey(sk) pool.subscribe( ['wss://a.com', 'wss://b.com', 'wss://c.com'], { kinds: [1], authors: [pk], }, { onevent(event) { console.log('got event:', event) } } ) let eventTemplate = { kind: 1, created_at: Math.floor(Date.now() / 1000), tags: [], content: 'hello world', } // this assigns the pubkey, calculates the event id and signs the event in a single step const signedEvent = finalizeEvent(eventTemplate, sk) await Promise.any(pool.publish(['wss://a.com', 'wss://b.com'], signedEvent)) relay.close() ``` -------------------------------- ### Encode and Decode NIP-19 Codes Source: https://github.com/nbd-wtf/nostr-tools/blob/master/README.md Encodes and decodes Nostr entities (secret keys, public keys, profiles) using NIP-19 standards. Includes examples for 'nsec', 'npub', and 'nprofile' formats. ```javascript import { generateSecretKey, getPublicKey } from '@nostr/tools/pure' import * as nip19 from '@nostr/tools/nip19' let sk = generateSecretKey() let nsec = nip19.nsecEncode(sk) let { type, data } = nip19.decode(nsec) assert(type === 'nsec') assert(data === sk) let pk = getPublicKey(generateSecretKey()) let npub = nip19.npubEncode(pk) let { type, data } = nip19.decode(npub) assert(type === 'npub') assert(data === pk) let pk = getPublicKey(generateSecretKey()) let relays = ['wss://relay.nostr.example.mydomain.example.com', 'wss://nostr.banana.com'] let nprofile = nip19.nprofileEncode({ pubkey: pk, relays }) let { type, data } = nip19.decode(nprofile) assert(type === 'nprofile') assert(data.pubkey === pk) assert(data.relays.length === 2) ``` -------------------------------- ### Create BunkerSigner from Bunker Configuration Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/signer-and-bunker.md Use this method to create a BunkerSigner instance from an existing bunker configuration. The connection is not established immediately; you must call `await signer.connect()` to authorize the connection. ```typescript static fromBunker( clientSecretKey: Uint8Array, bp: BunkerPointer, params?: BunkerSignerParams ): BunkerSigner ``` ```typescript import { BunkerSigner, parseBunkerInput } from '@nostr/tools/nip46' import { generateSecretKey } from '@nostr/tools/pure' import { SimplePool } from '@nostr/tools/pool' const clientSk = generateSecretKey() const bunkerPointer = await parseBunkerInput('bunker://pubkey...?relay=wss://...') const pool = new SimplePool() const signer = BunkerSigner.fromBunker(clientSk, bunkerPointer, { pool }) await signer.connect() // First time: requests authorization const pubkey = await signer.getPublicKey() ``` -------------------------------- ### Nostr Cryptographic Backend Interface Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/core-and-pure.md Defines the contract for the cryptographic backend used by Nostr. It includes methods for generating secret keys, getting public keys, finalizing events, and verifying events. ```typescript interface Nostr { generateSecretKey(): Uint8Array getPublicKey(secretKey: Uint8Array): string finalizeEvent(event: EventTemplate, secretKey: Uint8Array): VerifiedEvent verifyEvent(event: Event): event is VerifiedEvent } ``` -------------------------------- ### Relay.connect (instance method) Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/relay-and-pool.md Establishes a WebSocket connection to the relay. This method handles connection timeouts, abort signals, and reconnection logic. ```APIDOC ## Relay.connect (instance method) ### Description Establishes a WebSocket connection to the relay. This method handles connection timeouts, abort signals, and reconnection logic. ### Method `async connect(opts?: { timeout?: number; abort?: AbortSignal }): Promise` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **opts.timeout** (number) - Optional - Milliseconds to wait before timing out (0 to infinity by default) - **opts.abort** (AbortSignal) - Optional - An AbortSignal to abort the connection attempt ### Throws - Error: If connection fails, times out, or is aborted ### Behavior - Resubscribes to all open subscriptions on reconnection - Emits 'onopen' callback when connection is established - Handles ping/pong if enabled - Attempts automatic reconnection with exponential backoff if enableReconnect is true ### Example ```typescript const relay = new Relay('wss://relay.example.com') const controller = new AbortController() setTimeout(() => controller.abort(), 5000) try { await relay.connect({ timeout: 10000, abort: controller.signal }) } catch (err) { console.error('Failed to connect:', err) } ``` ``` -------------------------------- ### Resolving Mentions to Names using NIP-05 Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/nip05-nip27-parsing.md Parses event references and includes logic for attempting to fetch profile metadata from known relays. This snippet demonstrates the initial setup for resolving mentions. ```typescript import { parseReferences } from '@nostr/tools/references' import { queryProfile } from '@nostr/tools/nip05' const event = { /* ... */ } const refs = parseReferences(event) for (const ref of refs) { if (ref.profile?.relays?.[0]) { // Try to fetch metadata from known relay } } ``` -------------------------------- ### Instantiate and Connect to a Relay Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/relay-and-pool.md Create a new Relay instance and establish a WebSocket connection. This is useful for direct interaction with a single relay. ```typescript import { Relay } from '@nostr/tools/relay' const relay = new Relay('wss://relay.damus.io') await relay.connect() ``` -------------------------------- ### AbstractRelayConstructorOptions Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/types.md Options for AbstractRelay and Relay constructors. These options configure the behavior of individual relay connections. ```APIDOC ## AbstractRelayConstructorOptions ### Description Options for AbstractRelay and Relay constructors. ### Type Definition ```typescript type AbstractRelayConstructorOptions = { verifyEvent: Nostr['verifyEvent'] websocketImplementation?: typeof WebSocket enablePing?: boolean enableReconnect?: boolean } ``` ``` -------------------------------- ### Implement WebSocket for Node.js Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/relay-and-pool.md For Node.js environments, you must provide a WebSocket implementation. Import `useWebSocketImplementation` and pass your WebSocket constructor. ```typescript import { useWebSocketImplementation } from '@nostr/tools/relay' // or import { useWebSocketImplementation } from '@nostr/tools/pool' import WebSocket from 'ws' useWebSocketImplementation(WebSocket) ``` -------------------------------- ### Handle queryProfile() and searchDomain() Failures Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/errors.md queryProfile and searchDomain never throw errors; they return null or an empty object instead. Check the return value to handle cases where the NIP-05 profile could not be resolved due to domain issues, format errors, missing files, or user not found. ```typescript import { queryProfile, searchDomain } from '@nostr/tools/nip05' const profile = await queryProfile('user@domain.com') if (!profile) { // Could not resolve NIP-05: // - Domain unreachable // - Invalid format // - .well-known/nostr.json not found or malformed // - User not found in names } const names = await searchDomain('domain.com') if (Object.keys(names).length === 0) { // No names found or domain unreachable } ``` -------------------------------- ### Instantiate AbstractRelay and AbstractSimplePool with WASM Verification Source: https://github.com/nbd-wtf/nostr-tools/blob/master/README.md Connects to a Nostr relay or creates a connection pool using WASM-compiled event verification for potentially faster performance. Requires importing abstract classes and passing the `verifyEvent` function. ```javascript import { setNostrWasm, verifyEvent } from '@nostr/tools/wasm' import { AbstractRelay } from '@nostr/tools/abstract-relay' import { AbstractSimplePool } from '@nostr/tools/abstract-pool' import { initNostrWasm } from 'nostr-wasm' initNostrWasm().then(setNostrWasm) const relay = AbstractRelay.connect('wss://relayable.org', { verifyEvent }) const pool = new AbstractSimplePool({ verifyEvent }) ``` -------------------------------- ### Custom Fetch Implementation (Node.js) Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/ARCHITECTURE.md Customize the fetch implementation for NIP-05 and NIP-46. Import the respective `useFetchImplementation` functions and pass your custom fetch module, like `nodeFetch`. ```typescript import { useFetchImplementation } from '@nostr/tools/nip05' import { useFetchImplementation as useNip46Fetch } from '@nostr/tools/nip46' useFetchImplementation(nodeFetch) useNip46Fetch(nodeFetch) ``` -------------------------------- ### useFetchImplementation Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/nip05-nip27-parsing.md Allows overriding the default fetch implementation, which is particularly useful in Node.js environments where a global `fetch` might not be available or a specific implementation like `node-fetch` is preferred. ```APIDOC ## useFetchImplementation ### Description Override the fetch implementation (for Node.js). ### Method `function useFetchImplementation(fetchImplementation: unknown): void` ### Parameters #### Path Parameters - **fetchImplementation** (unknown) - Required - Fetch-compatible function (for Node.js, pass `node-fetch`) ### Example ```typescript import { useFetchImplementation } from '@nostr/tools/nip05' import fetch from 'node-fetch' useFetchImplementation(fetch) ``` ``` -------------------------------- ### AbstractPoolConstructorOptions Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/types.md Options for AbstractSimplePool and SimplePool constructors. Extends relay options with pool-specific callbacks and configurations. ```APIDOC ## AbstractPoolConstructorOptions ### Description Options for AbstractSimplePool and SimplePool constructors, extending relay options with pool-specific callbacks. ### Type Definition ```typescript type AbstractPoolConstructorOptions = AbstractRelayConstructorOptions & { automaticallyAuth?: (relayURL: string) => null | ((event: EventTemplate) => Promise) onRelayConnectionFailure?: (url: string) => void onRelayConnectionSuccess?: (url: string) => void allowConnectingToRelay?: (url: string, operation: ['read', Filter[]] | ['write', Event]) => boolean maxWaitForConnection: number } ``` ``` -------------------------------- ### Create BunkerSigner from Connection URI Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/signer-and-bunker.md This asynchronous method creates a BunkerSigner from a client-generated connection URI. It waits for the bunker to scan and connect, returning a connected signer instance. Connection is automatically established, and `switchRelays()` is called unless `skipSwitchRelays` is set to true. ```typescript static async fromURI( clientSecretKey: Uint8Array, connectionURI: string, bunkerParams?: BunkerSignerParams, maxWaitOrAbort?: number | AbortSignal ): Promise ``` ```typescript import { BunkerSigner, createNostrConnectURI } from '@nostr/tools/nip46' import { getPublicKey } from '@nostr/tools/pure' import { SimplePool } from '@nostr/tools/pool' const clientSk = generateSecretKey() const clientPk = getPublicKey(clientSk) // Generate a URI for the bunker to scan const uri = createNostrConnectURI({ clientPubkey: clientPk, relays: ['wss://relay.damus.io'], secret: 'my-secret-123', name: 'My App' }) // Show URI as QR code; wait for bunker to scan and connect const pool = new SimplePool() const signer = await BunkerSigner.fromURI(clientSk, uri, { pool }, 60000) // Already connected and ready to use const pubkey = await signer.getPublicKey() ``` -------------------------------- ### Handle Relay Authentication with SimplePool (NIP-42) Source: https://github.com/nbd-wtf/nostr-tools/blob/master/README.md Implement automatic authentication handling for relays that require it. The `onauth` option in `subscribeMany`, `subscribeManyEose`, and `subscribeEose` will sign the challenge and automatically resubscribe. ```javascript import { SimplePool } from '@nostr/tools/pool' const pool = new SimplePool() pool.subscribeMany( ['wss://myrelay.com'], [{ '#t': ['restricted'] }], { onevent(event) { console.log('got event:', event) }, onauth: (eventTemplate) => window.nostr.signEvent(eventTemplate), } ) ``` -------------------------------- ### Custom Signer Implementation Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/ARCHITECTURE.md Implement the Signer interface to create a custom signer, such as for hardware wallets. Ensure `getPublicKey` and `signEvent` methods are implemented. ```typescript class HardwareWalletSigner implements Signer { async getPublicKey() { /* ... */ } async signEvent(event) { /* ... */ } } ``` -------------------------------- ### Custom WebSocket Implementation Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/ARCHITECTURE.md Replace the default WebSocket implementation with a custom one. Import `useWebSocketImplementation` and pass your custom WebSocket class. ```typescript import { useWebSocketImplementation } from '@nostr/tools/relay' import CustomWebSocket from 'my-websocket-lib' useWebSocketImplementation(CustomWebSocket) ``` -------------------------------- ### Connect to Bunker Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/signer-and-bunker.md Establishes a connection to the bunker and requests authorization. This is only needed for the `fromBunker()` flow. The connection will time out if authorization is not received within the specified duration. ```typescript const signer = BunkerSigner.fromBunker(clientSk, bunkerPointer) await signer.connect({ timeout: 10000 }) ``` -------------------------------- ### Parsing References with NIP-27 Source: https://github.com/nbd-wtf/nostr-tools/blob/master/README.md Demonstrates how to parse content for references (mentions) according to NIP-27. It iterates through blocks of parsed content, identifying and processing different types like text, references (nevent, naddr, npub, nprofile URIs), URLs, media, and relays. ```APIDOC ## Parsing References (NIP-27) ### Description Parses content based on NIP-27 to extract references, URLs, and other block types. ### Method Signature `nip27.parse(content: string): IterableIterator ### Parameters #### Path Parameters - **content** (string) - Required - The content string to parse. ### Response An iterable iterator yielding block objects, each with a `type` property and associated data (e.g., `text`, `pointer`, `url`). ### Example ```js import * as nip27 from '@nostr/tools/nip27' for (let block of nip27.parse(evt.content)) { switch (block.type) { case 'text': console.log(block.text) break case 'reference': { if ('id' in block.pointer) { console.log("it's a nevent1 uri", block.pointer) } else if ('identifier' in block.pointer) { console.log("it's a naddr1 uri", block.pointer) } else { console.log("it's an npub1 or nprofile1 uri", block.pointer) } break } case 'url': { console.log("it's a normal url:", block.url) break } case 'image', case 'video', case 'audio': console.log("it's a media url:", block.url) break case 'relay': console.log("it's a websocket url, probably a relay address:", block.url) break default: break } } ``` ``` -------------------------------- ### v2 Namespace Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/encryption-nip04-nip44.md Provides direct access to NIP-44 v2 utilities, including key derivation, padding, and encryption/decryption functions. ```APIDOC ## v2 Namespace ### Description Direct access to NIP-44 v2 utilities: ### Usage ```typescript import { v2 } from '@nostr/tools/nip44' const convKey = v2.utils.getConversationKey(privkey, pubkey) const encrypted = v2.encrypt(plaintext, convKey) const decrypted = v2.decrypt(encrypted, convKey) ``` ### Available Utilities - **getConversationKey**: Derives the conversation key. - **encrypt**: Encrypts a message. - **decrypt**: Decrypts a message. - **calcPaddedLen**: Calculates padded length for encryption. - **pad**: Pads plaintext for encryption. - **unpad**: Unpads decrypted plaintext. ``` -------------------------------- ### buildAuthorizationHeader (NIP-98) Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/additional-nips.md Creates an `Authorization: Nostr` header for HTTP requests, allowing authentication using Nostr events. ```APIDOC ## buildAuthorizationHeader (NIP-98) ### Description Create an `Authorization: Nostr` header for HTTP requests. ### Function Signature ```typescript function buildAuthorizationHeader(event: VerifiedEvent): string ``` ### Parameters - **event** (VerifiedEvent) - Required - A signed Nostr event used for authentication (kind 27235). ### Return Type string - Header value suitable for HTTP Authorization header. ### Example ```typescript import { buildAuthorizationHeader } from '@nostr/tools/nip98' const authEvent = finalizeEvent({ kind: 27235, created_at: Math.floor(Date.now() / 1000), tags: [ ['u', 'https://api.example.com/upload'], ['method', 'POST'] ], content: '' }, secretKey) const header = buildAuthorizationHeader(authEvent) const response = await fetch('https://api.example.com/upload', { method: 'POST', headers: { 'Authorization': header, 'Content-Type': 'application/octet-stream' }, body: fileData }) ``` ``` -------------------------------- ### Relay.connect (static method) Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/relay-and-pool.md A static method to create and establish a connection to a Nostr relay in a single step. It returns a connected Relay instance. ```APIDOC ## Relay.connect (static method) ### Description A static method to create and establish a connection to a Nostr relay in a single step. It returns a connected Relay instance. ### Method `static async connect(url: string, options?: Pick): Promise` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **url** (string) - Required - Relay WebSocket URL - **options** (object) - Optional - Connection options (enablePing, enableReconnect) ### Return Type `Promise` - A Relay instance that is already connected. ### Example ```typescript import { Relay } from '@nostr/tools/relay' const relay = await Relay.connect('wss://relay.damus.io') // relay is now connected ``` ``` -------------------------------- ### Configure WebSocket for Node.js Source: https://github.com/nbd-wtf/nostr-tools/blob/master/README.md If using Node.js, you must explicitly set the WebSocket implementation for the pool to use. This involves importing the 'ws' package and passing it to the `useWebSocketImplementation` function. ```javascript import { useWebSocketImplementation } from '@nostr/tools/pool' // or import { useWebSocketImplementation } from '@nostr/tools/relay' if you're using the Relay directly import WebSocket from 'ws' useWebSocketImplementation(WebSocket) ``` -------------------------------- ### Connect to Bunker via URI (NIP-46) Source: https://github.com/nbd-wtf/nostr-tools/blob/master/README.md Establishes a connection to a remote NIP-46 signer initiated by the bunker. Requires parsing a bunker URI and explicitly calling connect. A SimplePool is used for relay communication. ```javascript import { BunkerSigner, parseBunkerInput } from '@nostr/tools/nip46' import { SimplePool } from '@nostr/tools/pool' // parse a bunker URI const bunkerPointer = await parseBunkerInput('bunker://abcd...?relay=wss://relay.example.com') if (!bunkerPointer) { throw new Error('Invalid bunker input') } // create the bunker instance const pool = new SimplePool() const bunker = BunkerSigner.fromBunker(localSecretKey, bunkerPointer, { pool }) await bunker.connect() // and use it const pubkey = await bunker.getPublicKey() const event = await bunker.signEvent({ kind: 1, created_at: Math.floor(Date.now() / 1000), tags: [], content: 'Hello from bunker!' }) // cleanup await signer.close() pool.close([]) ``` -------------------------------- ### SimplePool Constructor Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/relay-and-pool.md Initializes a new SimplePool instance. Options can be provided to control ping keep-alive and automatic reconnection. ```APIDOC ## SimplePool Constructor ### Description Initializes a new SimplePool instance. Options can be provided to control ping keep-alive and automatic reconnection. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **options.enablePing** (boolean) - Optional - Enable ping keep-alive on relays - **options.enableReconnect** (boolean) - Optional - Automatically reconnect relays on disconnection ### Request Example ```typescript import { SimplePool } from '@nostr/tools/pool' const pool = new SimplePool({ enablePing: true }) ``` ### Response None ### Response Example None ``` -------------------------------- ### Import Common Nostr Tools Functions Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/README.md Import the most commonly used functions from the main entry point of the nostr-tools package. This includes functions for key generation, event finalization, and event verification. ```typescript import { generateSecretKey, finalizeEvent, verifyEvent } from '@nostr/tools' ``` -------------------------------- ### BunkerSigner.fromURI Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/signer-and-bunker.md Creates a BunkerSigner instance from a client-generated connection URI. This method automatically waits for and establishes a connection. ```APIDOC ## BunkerSigner.fromURI ### Description Create a BunkerSigner from a client-generated connection URI. ### Method Signature ```typescript static async fromURI( clientSecretKey: Uint8Array, connectionURI: string, bunkerParams?: BunkerSignerParams, maxWaitOrAbort?: number | AbortSignal ): Promise ``` ### Parameters #### Path Parameters - **clientSecretKey** (Uint8Array) - Required - Your 32-byte secret key - **connectionURI** (string) - Required - `nostrconnect://` URI from createNostrConnectURI #### Query Parameters - **bunkerParams** (BunkerSignerParams) - Optional - Pool and callback options. - **maxWaitOrAbort** (number | AbortSignal) - Optional - Milliseconds to wait (or AbortSignal). Defaults to `300000`. ### Return type `Promise` - A connected signer instance (no need to call connect()). ### Behavior - Waits for bunker to scan and connect to the URI - Returns immediately when connection succeeds - Throws if connection fails or times out - If `skipSwitchRelays` is false, calls switchRelays() automatically ### Example ```typescript import { BunkerSigner, createNostrConnectURI } from '@nostr/tools/nip46' import { getPublicKey } from '@nostr/tools/pure' import { SimplePool } from '@nostr/tools/pool' const clientSk = generateSecretKey() const clientPk = getPublicKey(clientSk) // Generate a URI for the bunker to scan const uri = createNostrConnectURI({ clientPubkey: clientPk, relays: ['wss://relay.damus.io'], secret: 'my-secret-123', name: 'My App' }) // Show URI as QR code; wait for bunker to scan and connect const pool = new SimplePool() const signer = await BunkerSigner.fromURI(clientSk, uri, { pool }, 60000) // Already connected and ready to use const pubkey = await signer.getPublicKey() ``` ``` -------------------------------- ### Import Nostr Tools for Profile Lookups Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/00-START-HERE.md Import functions for querying user profiles and parsing Nostr references, essential for user identity and reference resolution. Refer to API documentation for 'nip05-nip27-parsing.md'. ```typescript import { queryProfile, parseReferences } from '@nostr/tools' // See: api-reference/nip05-nip27-parsing.md ``` -------------------------------- ### Use nostr-tools from Browser without Bundler Source: https://github.com/nbd-wtf/nostr-tools/blob/master/README.md Includes the nostr-tools library directly in an HTML file using a CDN link, allowing usage in the browser without a build process. ```html ``` -------------------------------- ### BunkerSignerParams Type Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/signer-and-bunker.md Configuration options for initializing a BunkerSigner. ```APIDOC ## BunkerSignerParams Options for BunkerSigner configuration. ### Type Definition ```typescript type BunkerSignerParams = { pool?: AbstractSimplePool onauth?: (url: string) => void skipSwitchRelays?: boolean } ``` ### Fields - `pool` (AbstractSimplePool) - Custom relay pool; uses SimplePool if omitted. - `onauth` ((url: string) => void) - Callback if bunker requires re-authentication. - `skipSwitchRelays` (boolean) - If true, don't call switchRelays() automatically in fromURI. ``` -------------------------------- ### Finding URLs and Media in Posts with NIP-27 Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/nip05-nip27-parsing.md Parses event content using NIP-27 to identify and log URLs, images, and videos. Assumes the event object has a 'content' property. ```typescript import { parse } from '@nostr/tools/nip27' const event = { content: 'Check this out: https://example.com/video.mp4' } for (const block of parse(event.content)) { if (block.type === 'image' || block.type === 'video') { console.log('Media:', block.url) } else if (block.type === 'url') { console.log('Link:', block.url) } } ``` -------------------------------- ### AbstractRelayConstructorOptions Type Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/types.md Options for AbstractRelay and Relay constructors. It includes event verification, optional WebSocket implementation, and settings for ping and reconnection. ```typescript type AbstractRelayConstructorOptions = { verifyEvent: Nostr['verifyEvent'] websocketImplementation?: typeof WebSocket enablePing?: boolean enableReconnect?: boolean } ``` -------------------------------- ### querySync Source: https://github.com/nbd-wtf/nostr-tools/blob/master/_autodocs/api-reference/relay-and-pool.md Queries multiple events from relays synchronously. ```APIDOC ## querySync ### Description Queries multiple events from relays synchronously. ### Method `querySync` ### Parameters - **relays** (string[]) - Required - Relay URLs to query - **filter** (Filter) - Required - Event filter ### Return type `Promise` — Array of all matching events found. ### Request Example ```typescript const events = await pool.querySync( ['wss://relay.example.com'], { kinds: [1], authors: ['pk1'], limit: 100 } ) console.log(`Found ${events.length} events`) ``` ### Response None ### Response Example None ```