UNPKG

@nostr-dev-kit/ndk

Version:

NDK - Nostr Development Kit. Includes AI Guardrails to catch common mistakes during development.

94 lines (80 loc) 2.87 kB
import createDebug from "debug"; import { NDKEvent } from "../events/index.js"; import { NDKKind } from "../events/kinds/index.js"; import type { NDK } from "../ndk/index.js"; import type { NDKSigner } from "../signers/index.js"; import type { NDKRelay } from "."; import type { NDKPool } from "./pool/index.js"; /** * NDKAuthPolicies are functions that are called when a relay requests authentication * so that you can define a behavior for your application. * * @param relay The relay that requested authentication. * @param challenge The challenge that the relay sent. */ type NDKAuthPolicy = (relay: NDKRelay, challenge: string) => Promise<boolean | undefined | NDKEvent>; /** * This policy will disconnect from relays that request authentication. */ function disconnect(pool: NDKPool, debug?: debug.Debugger) { debug ??= createDebug("ndk:relay:auth-policies:disconnect"); return async (relay: NDKRelay) => { debug?.(`Relay ${relay.url} requested authentication, disconnecting`); pool.removeRelay(relay.url); }; } type ISignIn = { ndk?: NDK; signer?: NDKSigner; debug?: debug.Debugger; }; async function signAndAuth( event: NDKEvent, relay: NDKRelay, signer: NDKSigner, debug: debug.Debugger, resolve: (event: NDKEvent) => void, reject: (event: NDKEvent) => void, ) { try { await event.sign(signer); resolve(event); } catch (e) { debug?.(`Failed to publish auth event to relay ${relay.url}`, e); reject(event); } } /** * Uses the signer to sign an event and then authenticate with the relay. * If no signer is provided the NDK signer will be used. * If none is not available it will wait for one to be ready. */ function signIn({ ndk, signer, debug }: ISignIn = {}) { debug ??= createDebug("ndk:auth-policies:signIn"); return async (relay: NDKRelay, challenge: string): Promise<NDKEvent> => { debug?.(`Relay ${relay.url} requested authentication, signing in`); const event = new NDKEvent(ndk); event.kind = NDKKind.ClientAuth; event.tags = [ ["relay", relay.url], ["challenge", challenge], ]; signer ??= ndk?.signer; // If we dont have a signer, we need to wait for one to be ready // eslint-disable-next-line no-async-promise-executor return new Promise(async (resolve, reject) => { if (signer) { await signAndAuth(event, relay, signer, debug!, resolve, reject); } else { ndk?.once("signer:ready", async (signer) => { await signAndAuth(event, relay, signer, debug!, resolve, reject); }); } }); }; } const NDKRelayAuthPolicies = { disconnect, signIn, }; export { NDKRelayAuthPolicies, type NDKAuthPolicy };