oninvalidevent

This commit is contained in:
arthurfranca
2026-02-26 18:08:17 -03:00
committed by GitHub
parent e45a9987e2
commit 54199504a7
4 changed files with 85 additions and 2 deletions
+2 -2
View File
@@ -266,7 +266,7 @@ export class AbstractSimplePool {
subscribeEose(
relays: string[],
filter: Filter,
params: Pick<SubscribeManyParams, 'label' | 'id' | 'onevent' | 'onclose' | 'maxWait' | 'onauth'>,
params: Pick<SubscribeManyParams, 'label' | 'id' | 'onevent' | 'oninvalidevent' | 'onclose' | 'maxWait' | 'onauth'>,
): SubCloser {
let subcloser: SubCloser
subcloser = this.subscribe(relays, filter, {
@@ -283,7 +283,7 @@ export class AbstractSimplePool {
subscribeManyEose(
relays: string[],
filter: Filter,
params: Pick<SubscribeManyParams, 'label' | 'id' | 'onevent' | 'onclose' | 'maxWait' | 'onauth'>,
params: Pick<SubscribeManyParams, 'label' | 'id' | 'onevent' | 'oninvalidevent' | 'onclose' | 'maxWait' | 'onauth'>,
): SubCloser {
return this.subscribeEose(relays, filter, params)
}
+5
View File
@@ -426,6 +426,8 @@ export class AbstractRelay {
const event = data[2] as NostrEvent
if (this.verifyEvent(event) && matchFilters(so.filters, event)) {
so.onevent(event)
} else {
so.oninvalidevent?.(event)
}
if (!so.lastEmitted || so.lastEmitted < event.created_at) so.lastEmitted = event.created_at
return
@@ -504,6 +506,7 @@ export class Subscription {
public receivedEvent: ((relay: AbstractRelay, id: string) => void) | undefined
public onevent: (evt: Event) => void
public oninvalidevent: ((evt: unknown) => void) | undefined
public oneose: (() => void) | undefined
public onclose: ((reason: string) => void) | undefined
@@ -525,6 +528,7 @@ export class Subscription {
this.oneose = params.oneose
this.onclose = params.onclose
this.oninvalidevent = params.oninvalidevent
this.onevent =
params.onevent ||
(event => {
@@ -576,6 +580,7 @@ export class Subscription {
export type SubscriptionParams = {
onevent?: (evt: Event) => void
oninvalidevent?: (evt: unknown) => void
oneose?: () => void
onclose?: (reason: string) => void
alreadyHaveEvent?: (id: string) => boolean
+21
View File
@@ -393,3 +393,24 @@ test('track relays when publishing', async () => {
await Promise.all(pool.publish(relayURLs, event2))
expect(pool.seenOn.get(event2.id)).toBeUndefined()
})
test('oninvalidevent is called through the pool for invalid events', async done => {
const mockRelay = mockRelays[0]
const relay = await pool.ensureRelay(mockRelay.url)
const sub = relay.prepareSubscription([{ kinds: [1] }], {
oninvalidevent(event) {
expect((event as any).kind).toBe('1')
sub.close()
done()
},
})
const sk = generateSecretKey()
const wrongFieldTypeEvent = [finalizeEvent(
{ kind: 1, content: 'hello', created_at: Math.floor(Date.now() / 1000), tags: [] },
sk,
)].map(v => { (v as any).kind = '1'; return v })[0]
relay._onmessage({ data: JSON.stringify(['EVENT', sub.id, wrongFieldTypeEvent]) } as MessageEvent)
})
+57
View File
@@ -1,6 +1,7 @@
import { expect, test } from 'bun:test'
import { Server } from 'mock-socket'
import { finalizeEvent, generateSecretKey, getPublicKey } from './pure.ts'
import { NostrEvent } from './pure.ts'
import { Relay, useWebSocketImplementation } from './relay.ts'
import { MockRelay, MockWebSocketClient } from './test-helpers.ts'
@@ -336,3 +337,59 @@ test('reconnect on disconnect', async () => {
expect(relay.connected).toBeTrue()
expect(closes).toBe(1) // should not have closed again
})
test('oninvalidevent is called for malformed events', async done => {
const mockRelay = new MockRelay()
const relay = new Relay(mockRelay.url)
await relay.connect()
const sub = relay.prepareSubscription([{ kinds: [1] }], {
oninvalidevent(event) {
expect((event as any).kind).toBe('1')
sub.close()
relay.close()
done()
},
})
const sk = generateSecretKey()
const wrongFieldTypeEvent = [finalizeEvent(
{
kind: 1,
content: 'content',
created_at: 0,
tags: [],
},
sk
)].map(v => { (v as any).kind = '1'; return v })[0]
relay._onmessage({ data: JSON.stringify(['EVENT', sub.id, wrongFieldTypeEvent]) } as MessageEvent)
})
test('oninvalidevent is called for events that do not match subscription filters', async done => {
const mockRelay = new MockRelay()
const sk = generateSecretKey()
const relay = new Relay(mockRelay.url)
await relay.connect()
const sub = relay.prepareSubscription([{ kinds: [999] }], {
oninvalidevent(event) {
expect((event as NostrEvent).kind).toBe(1)
sub.close()
relay.close()
done()
},
})
const event = finalizeEvent(
{
kind: 1,
content: 'does not match filter',
created_at: Math.floor(Date.now() / 1000),
tags: [],
},
sk,
)
relay._onmessage({ data: JSON.stringify(['EVENT', sub.id, event]) } as MessageEvent)
})