diff --git a/event.ts b/event.ts index ca2039c..e0440fb 100644 --- a/event.ts +++ b/event.ts @@ -5,6 +5,9 @@ import { bytesToHex } from '@noble/hashes/utils' import { getPublicKey } from './keys.ts' import { utf8Encoder } from './utils.ts' +/** Designates a verified event signature. */ +export const verifiedSymbol = Symbol('verified') + /** @deprecated Use numbers instead. */ /* eslint-disable no-unused-vars */ export enum Kind { @@ -35,20 +38,26 @@ export enum Kind { FileMetadata = 1063, } -export type EventTemplate = { +export interface Event { kind: K tags: string[][] content: string created_at: number -} - -export type UnsignedEvent = EventTemplate & { pubkey: string -} - -export type Event = UnsignedEvent & { id: string sig: string + [verifiedSymbol]?: boolean +} + +export type EventTemplate = Pick, 'kind' | 'tags' | 'content' | 'created_at'> +export type UnsignedEvent = Pick< + Event, + 'kind' | 'tags' | 'content' | 'created_at' | 'pubkey' +> + +/** An event whose signature has been verified. */ +export interface VerifiedEvent extends Event { + [verifiedSymbol]: true } export function getBlankEvent(): EventTemplate @@ -103,9 +112,12 @@ export function validateEvent(event: T): event is T & UnsignedEvent { return true } -export function verifySignature(event: Event): boolean { +/** Verify the event's signature. This function mutates the event with a `verified` symbol, making it idempotent. */ +export function verifySignature(event: Event): event is VerifiedEvent { + if (typeof event[verifiedSymbol] === 'boolean') return event[verifiedSymbol] try { - return schnorr.verify(event.sig, getEventHash(event), event.pubkey) + event[verifiedSymbol] = schnorr.verify(event.sig, getEventHash(event), event.pubkey) + return event[verifiedSymbol] } catch (err) { return false }