From 3bdb68020d309dbd6dbb13c64d61f3ad9416788f Mon Sep 17 00:00:00 2001 From: OFF0 Date: Sun, 12 Mar 2023 16:31:08 +0100 Subject: [PATCH] nip01: add support for filter prefix in authors and ids so clients can filter events by prefix in authors and ids as described in nip-01, i.e. to subscribe to mined events starting with zeroes or to add some privacy for clients that may not want to disclose the exact filter. see also https://github.com/scsibug/nostr-rs-relay/issues/104 --- filter.test.js | 24 ++++++++++++++++++++++++ filter.ts | 13 ++++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/filter.test.js b/filter.test.js index 6552e6a..27abdb8 100644 --- a/filter.test.js +++ b/filter.test.js @@ -37,6 +37,16 @@ describe('Filter', () => { expect(result).toEqual(false) }) + it('should return true when the event id starts with a prefix', () => { + const filter = {ids: ['22', '00']} + + const event = {id: '001'} + + const result = matchFilter(filter, event) + + expect(result).toEqual(true) + }) + it('should return false when the event kind is not in the filter', () => { const filter = {kinds: [1, 2, 3]} @@ -132,6 +142,20 @@ describe('Filter', () => { expect(result).toEqual(true) }) + it('should return true when at least one prefix matches the event', () => { + const filters = [ + {ids: ['1'], kinds: [1], authors: ['a']}, + {ids: ['4'], kinds: [2], authors: ['d']}, + {ids: ['9'], kinds: [3], authors: ['g']} + ] + + const event = {id: '987', kind: 3, pubkey: 'ghi'} + + const result = matchFilters(filters, event) + + expect(result).toEqual(true) + }) + it('should return true when event matches one or more filters and some have limit set', () => { const filters = [ {ids: ['123'], limit: 1}, diff --git a/filter.ts b/filter.ts index d9ed8f2..263b853 100644 --- a/filter.ts +++ b/filter.ts @@ -15,10 +15,17 @@ export function matchFilter( filter: Filter, event: Event ): boolean { - if (filter.ids && filter.ids.indexOf(event.id) === -1) return false + if (filter.ids && filter.ids.indexOf(event.id) === -1) { + if (!filter.ids.some(prefix => event.id.startsWith(prefix))) { + return false + } + } if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) return false - if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) - return false + if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) { + if (!filter.authors.some(prefix => event.pubkey.startsWith(prefix))) { + return false + } + } for (let f in filter) { if (f[0] === '#') {