UNPKG

nostr-dm-magiclink-utils

Version:

A comprehensive Nostr utility library for magic link authentication via direct messages, supporting both ESM and CommonJS. Features NIP-01/04 compliant message encryption, multi-relay support, internationalization (i18n) with RTL support, and TypeScript-f

232 lines 9.14 kB
/** * Core Nostr types for magic link functionality */ /** * Type guard to check if an object is a valid SignedNostrEvent * @param obj The object to check * @returns True if the object is a valid SignedNostrEvent */ export function isSignedNostrEvent(obj) { if (!isNostrEvent(obj)) { return false; } const signedEvent = obj; return typeof signedEvent.id === 'string' && typeof signedEvent.sig === 'string'; } /** * Type guard to check if an object is a valid SignEventParams * @param obj The object to check * @returns True if the object is a valid SignEventParams */ export function isSignEventParams(obj) { if (!isEventParams(obj)) { return false; } const signParams = obj; return typeof signParams.privateKey === 'string'; } /** * Type guard to check if an object is a valid EventParams * @param obj The object to check * @returns True if the object is a valid EventParams */ export function isEventParams(obj) { if (!obj || typeof obj !== 'object') { return false; } const eventParams = obj; return (typeof eventParams.kind === 'number' && typeof eventParams.content === 'string' && (eventParams.tags === undefined || (Array.isArray(eventParams.tags) && eventParams.tags.every(tag => Array.isArray(tag) && tag.every(item => typeof item === 'string')))) && (eventParams.created_at === undefined || typeof eventParams.created_at === 'number') && (eventParams.pubkey === undefined || typeof eventParams.pubkey === 'string')); } /** * Type guard to check if an object is a valid NostrFilter * @param obj The object to check * @returns True if the object is a valid NostrFilter */ export function isNostrFilter(obj) { if (!obj || typeof obj !== 'object') { return false; } const filter = obj; return ((filter.ids === undefined || Array.isArray(filter.ids) && filter.ids.every(id => typeof id === 'string')) && (filter.authors === undefined || Array.isArray(filter.authors) && filter.authors.every(author => typeof author === 'string')) && (filter.kinds === undefined || Array.isArray(filter.kinds) && filter.kinds.every(kind => typeof kind === 'number')) && (filter.since === undefined || typeof filter.since === 'number') && (filter.until === undefined || typeof filter.until === 'number') && (filter.limit === undefined || typeof filter.limit === 'number')); } /** * Type guard to check if an object is a valid NostrRelay * @param obj The object to check * @returns True if the object is a valid NostrRelay */ export function isNostrRelay(obj) { if (!obj || typeof obj !== 'object') { return false; } const relay = obj; return (typeof relay.url === 'string' && (relay.status === 'connected' || relay.status === 'disconnected' || relay.status === 'connecting' || relay.status === 'error') && (relay.error === undefined || typeof relay.error === 'string')); } /** * Type guard to check if an object is a valid NostrKeyPair * @param obj The object to check * @returns True if the object is a valid NostrKeyPair */ export function isNostrKeyPair(obj) { if (!obj || typeof obj !== 'object') { return false; } const keyPair = obj; return (typeof keyPair.publicKey === 'string' && typeof keyPair.privateKey === 'string' && (keyPair.seedPhrase === undefined || typeof keyPair.seedPhrase === 'string')); } /** * Type guard to check if an object is a valid EncryptedMessage * @param obj The object to check * @returns True if the object is a valid EncryptedMessage */ export function isEncryptedMessage(obj) { if (!obj || typeof obj !== 'object') { return false; } const message = obj; return (typeof message.content === 'string' && typeof message.iv === 'string' && typeof message.sender === 'string' && typeof message.recipient === 'string' && typeof message.timestamp === 'number'); } /** * Type guard to check if an object is a valid NostrMessage * @param obj The object to check * @returns True if the object is a valid NostrMessage */ export function isNostrMessage(obj) { if (!obj || typeof obj !== 'object') { return false; } const message = obj; return (typeof message.type === 'string' && (isNostrEvent(message.payload) || isSignedNostrEvent(message.payload) || isNostrFilter(message.payload) || isNostrRelay(message.payload) || isNostrKeyPair(message.payload) || isEncryptedMessage(message.payload))); } /** * Type guard to check if an object is a valid NostrSubscription * @param obj The object to check * @returns True if the object is a valid NostrSubscription */ export function isNostrSubscription(obj) { if (!obj || typeof obj !== 'object') { return false; } const subscription = obj; return (typeof subscription.id === 'string' && Array.isArray(subscription.filters) && subscription.filters.every(filter => isNostrFilter(filter))); } /** * Type guard to check if an object is a valid ErrorDetails * @param obj The object to check * @returns True if the object is a valid ErrorDetails */ export function isErrorDetails(obj) { if (!obj || typeof obj !== 'object') { return false; } const details = obj; return ((details.relayUrl === undefined || typeof details.relayUrl === 'string') && (details.pubkey === undefined || typeof details.pubkey === 'string') && (details.event === undefined || isPartialNostrEvent(details.event)) && (details.cause === undefined || details.cause instanceof Error || details.cause === undefined)); } /** * Type guard to check if an object is a valid Partial<NostrEvent> * @param obj The object to check * @returns True if the object is a valid Partial<NostrEvent> */ export function isPartialNostrEvent(obj) { if (!obj || typeof obj !== 'object') { return false; } const event = obj; return ((event.pubkey === undefined || typeof event.pubkey === 'string') && (event.created_at === undefined || typeof event.created_at === 'number') && (event.kind === undefined || typeof event.kind === 'number') && (event.tags === undefined || (Array.isArray(event.tags) && event.tags.every(tag => Array.isArray(tag) && tag.every(item => typeof item === 'string')))) && (event.content === undefined || typeof event.content === 'string')); } /** * Custom error class for Nostr-related errors */ export class NostrError extends Error { code; details; /** * Creates a new NostrError * @param message - Error message * @param code - Error code from NostrErrorCode * @param details - Additional error details */ constructor(message, code, details) { super(message); this.code = code; this.details = details; this.name = 'NostrError'; } } export var NostrErrorCode; (function (NostrErrorCode) { NostrErrorCode["INVALID_KEY"] = "INVALID_KEY"; NostrErrorCode["ENCRYPTION_FAILED"] = "ENCRYPTION_FAILED"; NostrErrorCode["DECRYPTION_FAILED"] = "DECRYPTION_FAILED"; NostrErrorCode["RELAY_CONNECTION_FAILED"] = "RELAY_CONNECTION_FAILED"; NostrErrorCode["INVALID_EVENT"] = "INVALID_EVENT"; NostrErrorCode["MESSAGE_SEND_FAILED"] = "MESSAGE_SEND_FAILED"; NostrErrorCode["EVENT_CREATION_ERROR"] = "EVENT_CREATION_ERROR"; NostrErrorCode["PARSING_ERROR"] = "PARSING_ERROR"; NostrErrorCode["FORMATTING_ERROR"] = "FORMATTING_ERROR"; NostrErrorCode["VALIDATION_ERROR"] = "VALIDATION_ERROR"; NostrErrorCode["CONNECTION_ERROR"] = "CONNECTION_ERROR"; NostrErrorCode["RELAY_ERROR"] = "RELAY_ERROR"; NostrErrorCode["VERIFICATION_FAILED"] = "VERIFICATION_FAILED"; NostrErrorCode["TOKEN_GENERATION_ERROR"] = "TOKEN_GENERATION_ERROR"; NostrErrorCode["CONFIGURATION_ERROR"] = "CONFIGURATION_ERROR"; NostrErrorCode["GENERAL_ERROR"] = "GENERAL_ERROR"; })(NostrErrorCode || (NostrErrorCode = {})); /** * Type guard to check if an object is a valid NostrWSClient * @param obj The object to check * @returns True if the object is a valid NostrWSClient */ export function isNostrWSClient(obj) { if (!obj || typeof obj !== 'object') { return false; } const client = obj; return (typeof client.connect === 'function' && typeof client.close === 'function' && typeof client.sendMessage === 'function'); } /** * Type guard to check if an object is a valid NostrEvent * @param obj The object to check * @returns True if the object is a valid NostrEvent */ export function isNostrEvent(obj) { if (!obj || typeof obj !== 'object') { return false; } const event = obj; return (typeof event.pubkey === 'string' && typeof event.created_at === 'number' && typeof event.kind === 'number' && Array.isArray(event.tags) && event.tags.every(tag => Array.isArray(tag) && tag.every(item => typeof item === 'string')) && typeof event.content === 'string'); } //# sourceMappingURL=nostr.js.map