sigit.io/src/utils/nostr.ts

127 lines
3.1 KiB
TypeScript
Raw Normal View History

import { nip05, nip19, verifyEvent } from 'nostr-tools'
import { SignedEvent } from '../types'
import axios from 'axios'
/**
* @param hexKey hex private or public key
* @returns whether or not is key valid
*/
const validateHex = (hexKey: string) => {
return hexKey.match(/^[a-f0-9]{64}$/)
}
/**
* NPUB provided - it will convert NPUB to HEX
* NIP-05 provided - it will query NIP-05 profile and return HEX key if found
* HEX provided - it will return HEX
*
* @param pubKey in NPUB, NIP-05 or HEX format
* @returns HEX format
*/
export const pubToHex = async (pubKey: string): Promise<string | null> => {
// If key is NIP-05
if (pubKey.indexOf('@') !== -1)
return Promise.resolve(
(await nip05.queryProfile(pubKey).then((res) => res?.pubkey)) || null
)
// If key is NPUB
if (pubKey.startsWith('npub')) {
try {
return nip19.decode(pubKey).data as string
} catch (error) {
return Promise.resolve(null)
}
}
// valid hex key
if (validateHex(pubKey)) return Promise.resolve(pubKey)
// Not a valid hex key
return Promise.resolve(null)
}
/**
* If NSEC key is provided function will convert it to HEX
* If HEX key Is provided function will validate the HEX format and return
*
* @param nsec or private key in HEX format
*/
export const nsecToHex = (nsec: string): string | null => {
// If key is NSEC
if (nsec.startsWith('nsec')) {
try {
return nip19.decode(nsec).data as string
} catch (error) {
return null
}
}
// since it's not NSEC key we check if it's a valid hex key
if (validateHex(nsec)) return nsec
return null
}
2024-03-01 10:16:35 +00:00
export const hexToNpub = (hexPubkey: string | undefined): string => {
if (!hexPubkey) return 'n/a'
return nip19.npubEncode(hexPubkey)
}
export const verifySignedEvent = (event: SignedEvent) => {
const isGood = verifyEvent(event)
if (!isGood) {
throw new Error(
'Signed event did not pass verification. Check sig, id and pubkey.'
)
}
}
export const queryNip05 = async (
nip05: string
): Promise<{
pubkey: string
relays: string[]
}> => {
const NIP05_REGEX = /^(?:([\w.+-]+)@)?([\w_-]+(\.[\w_-]+)+)$/
const match = nip05.match(NIP05_REGEX)
if (!match) throw new Error('Invalid nip05')
const [_, name = '_', domain] = match
const url = `https://${domain}/.well-known/nostr.json?name=${name}`
const res = await axios(url)
.then((res) => {
return res.data
})
.catch((err) => {
console.log('err :>> ', err)
throw err
})
const pubkey = res.names[name]
const relays: string[] = []
if (pubkey) {
// check nip46 for user pubkey, if relays found for user, return those
const userRelays = res.nip46?.[pubkey] as string[]
if (userRelays && userRelays.length > 0) {
relays.push(...userRelays)
} else {
// otherwise check nip46 for root user pubkey, if relays found, return those
const root = res.names['_']
if (root) {
const rootUserRelays = res.nip46?.[root] as string[]
if (rootUserRelays && rootUserRelays.length > 0)
relays.push(...rootUserRelays)
}
}
}
return {
pubkey,
relays
}
}