Deliver API events to outbox relays

This commit is contained in:
Alex Gleason 2024-04-02 18:29:26 -05:00
parent b2f2240d93
commit 4e54589c09
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
3 changed files with 36 additions and 5 deletions

View File

@ -11,6 +11,7 @@ import {
import { normalizeFilters } from '@/filter.ts'; import { normalizeFilters } from '@/filter.ts';
import { purifyEvent } from '@/storages/hydrate.ts'; import { purifyEvent } from '@/storages/hydrate.ts';
import { abortError } from '@/utils/abort.ts'; import { abortError } from '@/utils/abort.ts';
import { getRelays } from '@/utils/outbox.ts';
interface PoolStoreOpts { interface PoolStoreOpts {
pool: InstanceType<typeof RelayPoolWorker>; pool: InstanceType<typeof RelayPoolWorker>;
@ -34,12 +35,12 @@ class PoolStore implements NStore {
this.#publisher = opts.publisher; this.#publisher = opts.publisher;
} }
event(event: NostrEvent, opts: NStoreOpts = {}): Promise<void> { async event(event: NostrEvent, opts: NStoreOpts = {}): Promise<void> {
if (opts.signal?.aborted) return Promise.reject(abortError()); if (opts.signal?.aborted) return Promise.reject(abortError());
const { relays = this.#relays } = opts; const relays = [...await getRelays(event.pubkey)].slice(0, 4);
event = purifyEvent(event); event = purifyEvent(event);
this.#debug('EVENT', event); this.#debug('EVENT', event, relays);
this.#pool.publish(event, relays); this.#pool.publish(event, relays);
return Promise.resolve(); return Promise.resolve();

View File

@ -14,7 +14,7 @@ import {
import * as pipeline from '@/pipeline.ts'; import * as pipeline from '@/pipeline.ts';
import { AdminSigner } from '@/signers/AdminSigner.ts'; import { AdminSigner } from '@/signers/AdminSigner.ts';
import { APISigner } from '@/signers/APISigner.ts'; import { APISigner } from '@/signers/APISigner.ts';
import { eventsDB } from '@/storages.ts'; import { client, eventsDB } from '@/storages.ts';
import { nostrNow } from '@/utils.ts'; import { nostrNow } from '@/utils.ts';
const debug = Debug('ditto:api'); const debug = Debug('ditto:api');
@ -89,7 +89,10 @@ async function createAdminEvent(t: EventStub, c: AppContext): Promise<NostrEvent
async function publishEvent(event: NostrEvent, c: AppContext): Promise<NostrEvent> { async function publishEvent(event: NostrEvent, c: AppContext): Promise<NostrEvent> {
debug('EVENT', event); debug('EVENT', event);
try { try {
await pipeline.handleEvent(event, c.req.raw.signal); await Promise.all([
pipeline.handleEvent(event, c.req.raw.signal),
client.event(event),
]);
} catch (e) { } catch (e) {
if (e instanceof pipeline.RelayError) { if (e instanceof pipeline.RelayError) {
throw new HTTPException(422, { throw new HTTPException(422, {

27
src/utils/outbox.ts Normal file
View File

@ -0,0 +1,27 @@
import { Conf } from '@/config.ts';
import { eventsDB } from '@/storages.ts';
export async function getRelays(pubkey: string): Promise<Set<string>> {
const relays = new Set<`wss://${string}`>();
const events = await eventsDB.query([
{ kinds: [10002], authors: [pubkey, Conf.pubkey], limit: 2 },
]);
for (const event of events) {
for (const [name, relay, marker] of event.tags) {
if (name === 'r' && (marker === 'write' || !marker)) {
try {
const url = new URL(relay);
if (url.protocol === 'wss:') {
relays.add(url.toString() as `wss://${string}`);
}
} catch (_e) {
// do nothing
}
}
}
}
return relays;
}