clone of repo on github
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.
 
 
 
 

113 lines
3.4 KiB

import { NDKEvent } from "@nostr-dev-kit/ndk";
/**
* Generate well-known NIP-05 URL
*/
export function wellKnownUrl(domain: string, name: string): string {
return `https://${domain}/.well-known/nostr.json?name=${name}`;
}
/**
* Generate well-known LNURLp URL for Lightning Network addresses
*/
export function lnurlpWellKnownUrl(domain: string, name: string): string {
return `https://${domain}/.well-known/lnurlp/${name}`;
}
/**
* Validate NIP-05 address format
*/
export function isValidNip05Address(address: string): boolean {
return /^[a-z0-9._-]+@[a-z0-9.-]+$/i.test(address);
}
/**
* Helper function to normalize search terms
*/
export function normalizeSearchTerm(term: string): string {
return term.toLowerCase().replace(/\s+/g, "");
}
/**
* Helper function to check if a profile field matches the search term
*/
export function fieldMatches(field: string, searchTerm: string): boolean {
if (!field) return false;
const fieldLower = field.toLowerCase();
const fieldNormalized = fieldLower.replace(/\s+/g, "");
const searchTermLower = searchTerm.toLowerCase();
const normalizedSearchTerm = normalizeSearchTerm(searchTerm);
// Check exact match
if (fieldLower === searchTermLower) return true;
if (fieldNormalized === normalizedSearchTerm) return true;
// Check if field contains the search term
if (fieldLower.includes(searchTermLower)) return true;
if (fieldNormalized.includes(normalizedSearchTerm)) return true;
// Check individual words (handle spaces in display names)
const words = fieldLower.split(/\s+/);
return words.some((word) => word.includes(searchTermLower));
}
/**
* Helper function to check if NIP-05 address matches the search term
*/
export function nip05Matches(nip05: string, searchTerm: string): boolean {
if (!nip05) return false;
const nip05Lower = nip05.toLowerCase();
const searchTermLower = searchTerm.toLowerCase();
const normalizedSearchTerm = normalizeSearchTerm(searchTerm);
// Check if the part before @ contains the search term
const atIndex = nip05Lower.indexOf("@");
if (atIndex !== -1) {
const localPart = nip05Lower.substring(0, atIndex);
const localPartNormalized = localPart.replace(/\s+/g, "");
return (
localPart.includes(searchTermLower) ||
localPartNormalized.includes(normalizedSearchTerm)
);
}
return false;
}
/**
* Common domains for NIP-05 lookups
*/
export const COMMON_DOMAINS = [
"gitcitadel.com",
"theforest.nostr1.com",
"nostr1.com",
"nostr.land",
"sovbit.host",
] as const;
/**
* Check if an event is an emoji reaction (kind 7)
*/
export function isEmojiReaction(event: NDKEvent): boolean {
return event.kind === 7;
}
/**
* Create a profile object from event data
*/
// deno-lint-ignore no-explicit-any
export function createProfileFromEvent(event: NDKEvent, profileData: any): any {
return {
name: profileData.name,
displayName: profileData.displayName || profileData.display_name,
nip05: profileData.nip05,
picture: profileData.picture,
about: profileData.about,
banner: profileData.banner,
website: profileData.website,
lud16: profileData.lud16,
pubkey: event.pubkey,
created_at: event.created_at, // AI-NOTE: Preserve timestamp for proper date display
isInUserLists: profileData.isInUserLists, // AI-NOTE: Preserve user list information
listKinds: profileData.listKinds, // AI-NOTE: Preserve list kinds information
};
}