nip05 refactoring
This commit is contained in:
parent
5d92be05bb
commit
d2a9af2586
86
nip05.ts
86
nip05.ts
|
@ -1,5 +1,14 @@
|
||||||
import {ProfilePointer} from './nip19'
|
import {ProfilePointer} from './nip19'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NIP-05 regex. The localpart is optional, and should be assumed to be `_` otherwise.
|
||||||
|
*
|
||||||
|
* - 0: full match
|
||||||
|
* - 1: name (optional)
|
||||||
|
* - 2: domain
|
||||||
|
*/
|
||||||
|
export const NIP05_REGEX = /^(?:([\w.+-]+)@)?([\w.-]+)$/
|
||||||
|
|
||||||
var _fetch: any
|
var _fetch: any
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -25,36 +34,53 @@ export async function searchDomain(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function queryProfile(
|
/** nostr.json result. */
|
||||||
fullname: string
|
export interface NIP05Result {
|
||||||
): Promise<ProfilePointer | null> {
|
names: {
|
||||||
let [name, domain] = fullname.split('@')
|
[name: string]: string
|
||||||
|
|
||||||
if (!domain) {
|
|
||||||
// if there is no @, it is because it is just a domain, so assume the name is "_"
|
|
||||||
domain = name
|
|
||||||
name = '_'
|
|
||||||
}
|
}
|
||||||
|
relays?: {
|
||||||
if (!name.match(/^[A-Za-z0-9-_.]+$/)) return null
|
[pubkey: string]: string[]
|
||||||
if (!domain.includes('.')) return null
|
|
||||||
|
|
||||||
let res
|
|
||||||
try {
|
|
||||||
res = await (
|
|
||||||
await _fetch(`https://${domain}/.well-known/nostr.json?name=${name}`)
|
|
||||||
).json()
|
|
||||||
} catch (err) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!res?.names?.[name]) return null
|
|
||||||
|
|
||||||
let pubkey = res.names[name] as string
|
|
||||||
let relays = (res.relays?.[pubkey] || []) as string[] // nip35
|
|
||||||
|
|
||||||
return {
|
|
||||||
pubkey,
|
|
||||||
relays
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function queryProfile(fullname: string): Promise<ProfilePointer | null> {
|
||||||
|
const match = fullname.match(NIP05_REGEX)
|
||||||
|
if (!match) return null
|
||||||
|
|
||||||
|
const [_, name = '_', domain] = match
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch(`https://${domain}/.well-known/nostr.json?name=${name}`)
|
||||||
|
const { names, relays } = parseNIP05Result(await res.json())
|
||||||
|
|
||||||
|
const pubkey = names[name]
|
||||||
|
return pubkey ? { pubkey, relays: relays?.[pubkey] } : null
|
||||||
|
} catch (_e) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Parse the nostr.json and throw if it's not valid. */
|
||||||
|
function parseNIP05Result(json: any): NIP05Result {
|
||||||
|
const result: NIP05Result = {
|
||||||
|
names: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [name, pubkey] of Object.entries(json.names)) {
|
||||||
|
if (typeof name === 'string' && typeof pubkey === 'string') {
|
||||||
|
result.names[name] = pubkey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json.relays) {
|
||||||
|
result.relays = {}
|
||||||
|
for (const [pubkey, relays] of Object.entries(json.relays)) {
|
||||||
|
if (typeof pubkey === 'string' && Array.isArray(relays)) {
|
||||||
|
result.relays[pubkey] = relays.filter((relay: unknown) => typeof relay === 'string')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue