You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.5 KiB
88 lines
2.5 KiB
import { VALIDATION } from './search_constants'; |
|
import type { NostrEventId } from './nostr_identifiers'; |
|
|
|
/** |
|
* Nostr identifier types |
|
*/ |
|
export type NostrCoordinate = string; // kind:pubkey:d-tag format |
|
export type NostrIdentifier = NostrEventId | NostrCoordinate; |
|
|
|
/** |
|
* Interface for parsed Nostr coordinate |
|
*/ |
|
export interface ParsedCoordinate { |
|
kind: number; |
|
pubkey: string; |
|
dTag: string; |
|
} |
|
|
|
/** |
|
* Check if a string is a valid hex event ID |
|
* @param id The string to check |
|
* @returns True if it's a valid hex event ID |
|
*/ |
|
export function isEventId(id: string): id is NostrEventId { |
|
return new RegExp(`^[a-f0-9]{${VALIDATION.HEX_LENGTH}}$`, 'i').test(id); |
|
} |
|
|
|
/** |
|
* Check if a string is a valid Nostr coordinate (kind:pubkey:d-tag) |
|
* @param coordinate The string to check |
|
* @returns True if it's a valid coordinate |
|
*/ |
|
export function isCoordinate(coordinate: string): coordinate is NostrCoordinate { |
|
const parts = coordinate.split(':'); |
|
if (parts.length < 3) return false; |
|
|
|
const [kindStr, pubkey, ...dTagParts] = parts; |
|
|
|
// Check if kind is a valid number |
|
const kind = parseInt(kindStr, 10); |
|
if (isNaN(kind) || kind < 0) return false; |
|
|
|
// Check if pubkey is a valid hex string |
|
if (!isEventId(pubkey)) return false; |
|
|
|
// Check if d-tag exists (can contain colons) |
|
if (dTagParts.length === 0) return false; |
|
|
|
return true; |
|
} |
|
|
|
/** |
|
* Parse a Nostr coordinate into its components |
|
* @param coordinate The coordinate string to parse |
|
* @returns Parsed coordinate or null if invalid |
|
*/ |
|
export function parseCoordinate(coordinate: string): ParsedCoordinate | null { |
|
if (!isCoordinate(coordinate)) return null; |
|
|
|
const parts = coordinate.split(':'); |
|
const [kindStr, pubkey, ...dTagParts] = parts; |
|
|
|
return { |
|
kind: parseInt(kindStr, 10), |
|
pubkey, |
|
dTag: dTagParts.join(':') // Rejoin in case d-tag contains colons |
|
}; |
|
} |
|
|
|
/** |
|
* Create a coordinate string from components |
|
* @param kind The event kind |
|
* @param pubkey The author's public key |
|
* @param dTag The d-tag value |
|
* @returns The coordinate string |
|
*/ |
|
export function createCoordinate(kind: number, pubkey: string, dTag: string): NostrCoordinate { |
|
return `${kind}:${pubkey}:${dTag}`; |
|
} |
|
|
|
/** |
|
* Check if a string is any valid Nostr identifier |
|
* @param identifier The string to check |
|
* @returns True if it's a valid Nostr identifier |
|
*/ |
|
export function isNostrIdentifier(identifier: string): identifier is NostrIdentifier { |
|
return isEventId(identifier) || isCoordinate(identifier); |
|
}
|