diff --git a/src/controllers/api/instance.ts b/src/controllers/api/instance.ts index 70f38e1..cc71b1f 100644 --- a/src/controllers/api/instance.ts +++ b/src/controllers/api/instance.ts @@ -1,25 +1,19 @@ -import { NSchema as n } from '@nostrify/nostrify'; - -import { type AppController } from '@/app.ts'; +import { AppController } from '@/app.ts'; import { Conf } from '@/config.ts'; -import { serverMetaSchema } from '@/schemas/nostr.ts'; -import { Storages } from '@/storages.ts'; +import { getInstanceMetadata } from '@/utils/instance.ts'; const instanceController: AppController = async (c) => { const { host, protocol } = Conf.url; - const { signal } = c.req.raw; - - const [event] = await Storages.db.query([{ kinds: [0], authors: [Conf.pubkey], limit: 1 }], { signal }); - const meta = n.json().pipe(serverMetaSchema).catch({}).parse(event?.content); + const meta = await getInstanceMetadata(c.req.raw.signal); /** Protocol to use for WebSocket URLs, depending on the protocol of the `LOCAL_DOMAIN`. */ const wsProtocol = protocol === 'http:' ? 'ws:' : 'wss:'; return c.json({ uri: host, - title: meta.name ?? 'Ditto', - description: meta.about ?? 'Nostr and the Fediverse', - short_description: meta.tagline ?? meta.about ?? 'Nostr and the Fediverse', + title: meta.name, + description: meta.about, + short_description: meta.tagline, registrations: true, max_toot_chars: Conf.postCharLimit, configuration: { @@ -59,7 +53,7 @@ const instanceController: AppController = async (c) => { streaming_api: `${wsProtocol}//${host}`, }, version: '0.0.0 (compatible; Ditto 0.0.1)', - email: meta.email ?? `postmaster@${host}`, + email: meta.email, nostr: { pubkey: Conf.pubkey, relay: `${wsProtocol}//${host}/relay`, diff --git a/src/controllers/nostr/relay-info.ts b/src/controllers/nostr/relay-info.ts index a56df51..192cab2 100644 --- a/src/controllers/nostr/relay-info.ts +++ b/src/controllers/nostr/relay-info.ts @@ -1,20 +1,15 @@ -import { NSchema as n } from '@nostrify/nostrify'; - import { AppController } from '@/app.ts'; import { Conf } from '@/config.ts'; -import { serverMetaSchema } from '@/schemas/nostr.ts'; -import { Storages } from '@/storages.ts'; +import { getInstanceMetadata } from '@/utils/instance.ts'; const relayInfoController: AppController = async (c) => { - const { signal } = c.req.raw; - const [event] = await Storages.db.query([{ kinds: [0], authors: [Conf.pubkey], limit: 1 }], { signal }); - const meta = n.json().pipe(serverMetaSchema).catch({}).parse(event?.content); + const meta = await getInstanceMetadata(c.req.raw.signal); return c.json({ - name: meta.name ?? 'Ditto', - description: meta.about ?? 'Nostr and the Fediverse.', + name: meta.name, + description: meta.about, pubkey: Conf.pubkey, - contact: `mailto:${meta.email ?? `postmaster@${Conf.url.host}`}`, + contact: meta.email, supported_nips: [1, 5, 9, 11, 16, 45, 50, 46, 98], software: 'Ditto', version: '0.0.0', diff --git a/src/utils/instance.ts b/src/utils/instance.ts new file mode 100644 index 0000000..004e4cf --- /dev/null +++ b/src/utils/instance.ts @@ -0,0 +1,37 @@ +import { NostrEvent, NostrMetadata, NSchema as n } from '@nostrify/nostrify'; + +import { Conf } from '@/config.ts'; +import { serverMetaSchema } from '@/schemas/nostr.ts'; +import { Storages } from '@/storages.ts'; + +/** Like NostrMetadata, but some fields are required and also contains some extra fields. */ +export interface InstanceMetadata extends NostrMetadata { + name: string; + about: string; + tagline: string; + email: string; + event?: NostrEvent; +} + +/** Get and parse instance metadata from the kind 0 of the admin user. */ +export async function getInstanceMetadata(signal?: AbortSignal): Promise { + const [event] = await Storages.db.query( + [{ kinds: [0], authors: [Conf.pubkey], limit: 1 }], + { signal }, + ); + + const meta = n + .json() + .pipe(serverMetaSchema) + .catch({}) + .parse(event?.content); + + return { + ...meta, + name: meta.name ?? 'Ditto', + about: meta.about ?? 'Nostr community server', + tagline: meta.tagline ?? meta.about ?? 'Nostr community server', + email: meta.email ?? `postmaster@${Conf.url.host}`, + event, + }; +}