Files
welshman/packages/util/src/Address.ts
T

68 lines
1.8 KiB
TypeScript

import {nip19} from 'nostr-tools'
import {GROUP, COMMUNITY} from './Kinds'
// Define this locally to avoid circular dependencies
type AddressableEvent = {
kind: number
pubkey: string
tags: string[][]
}
export class Address {
constructor(
readonly kind: number,
readonly pubkey: string,
readonly identifier: string,
readonly relays: string[] = []
) {}
static isAddress(address: string) {
return Boolean(address.match(/^\d+:\w+:.*$/))
}
static from(address: string, relays: string[] = []) {
const [kind, pubkey, identifier = ""] = address.match(/^(\d+):(\w+):(.*)$/)!.slice(1)
return new Address(parseInt(kind), pubkey, identifier, relays)
}
static fromNaddr(naddr: string) {
let type
let data = {} as any
try {
({type, data} = nip19.decode(naddr) as {
type: "naddr"
data: any
})
} catch (e) {
// pass
}
if (type !== "naddr") {
throw new Error(`Invalid naddr ${naddr}`)
}
return new Address(data.kind, data.pubkey, data.identifier, data.relays)
}
static fromEvent(event: AddressableEvent, relays: string[] = []) {
const identifier = event.tags.find(t => t[0] === "d")?.[1] || ""
return new Address(event.kind, event.pubkey, identifier, relays)
}
toString = () => [this.kind, this.pubkey, this.identifier].join(":")
toNaddr = () => nip19.naddrEncode(this)
}
// Utils
export const getAddress = (e: AddressableEvent) => Address.fromEvent(e).toString()
export const isGroupAddress = (a: string, ...args: unknown[]) => Address.isAddress(a) && Address.from(a).kind === GROUP
export const isCommunityAddress = (a: string, ...args: unknown[]) => Address.isAddress(a) && Address.from(a).kind === COMMUNITY
export const isContextAddress = (a: string, ...args: unknown[]) => Address.isAddress(a) && [GROUP, COMMUNITY].includes(Address.from(a).kind)