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
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 |
|
}; |
|
}
|
|
|