Plugins for TRUSTed Filters
Plugins for TRUSTed Filters
nip-trusted-filter-plugins
draft
extends nip-trusted-filters
This NIP defines a set of plugins that extend the functionality of TRUSTed Filters. Trust services MAY indicate support for any one or more of these plugins (by plugin_key) in their TRUST message ping response to connecting clients (as well as in their NIP-11 "Relay Information Document").
- Filtering plugins operate on candidate events
W: defines named keys for user input & optional filtering. (seenip-trusted-filters)sort_alpha: sorts candidate events alphabetically.sort_numeric: sorts candidate events numerically.sort_frequency: sorts candidate events by frequency of value appearance.
- Transformation plugins extract and process data from filtered events:
count: counts filtered events or values according to an EventPath.sum: sums numeric values across filtered events, according to an EventPath.avg: calculates average of numeric values across filtered events, according to an EventPath.min: finds minimum value across filtered events, according to an EventPath.max: finds maximum value across filtered events, according to an EventPath.
- Flow Control plugins modify filter execution behavior:
required: marks a filter as being required.schedule: schedules automatic execution of a filter.iterate: executes a filter multiple times with different values.
- Input & Output plugins manage the
IOnamespace: w: extracts data from filtered events toIO. (seenip-trusted-filters)#: stores pre-rendered tag arrays. (seenip-trusted-filters)
- Publishing plugins publishes events from extracted data:
publish: creates and publishes Nostr events fromIOdata. (seenip-trusted-filters)publish_every: publishes separate events for each value at anIOquery path.page: selects specific page of tags for pagination.
sort_alpha
sort_alpha is a Filtering & Sorting plugin. It sorts candidate events alphabetically by a value extracted from an EventPath.
Functions:
{
"plugins": [
["sort_alpha", ["<event_path>", "<order?>"]]
]
}Arguments:
<event_path>:EventPath: (required) : Path to extract sort value from each event<order>:string: (optional) : Sort order -"asc"or"desc"(default:"asc")
IO:
- Writes to: Does NOT write to
IO. - Reads from: Does NOT read from
IO.
Behavior:
- Evaluates
<event_path>on each candidate event. - Sorts events alphabetically by the extracted value.
- Applies
<order>to reverse if"desc".
sort_numeric
sort_numeric is a Filtering & Sorting plugin. It sorts candidate events numerically by a value extracted from an EventPath.
Functions:
{
"plugins": [
["sort_numeric", ["<event_path>", "<order?>"]]
]
}Arguments:
<event_path>:EventPath: (required) : Path to extract numeric sort value from each event<order>:string: (optional) : Sort order -"asc"or"desc"(default:"asc")
IO:
- Writes to: Does NOT write to
IO. - Reads from: Does NOT read from
IO.
Behavior:
- Evaluates
<event_path>on each candidate event. - Sorts events numerically by the extracted value.
- Applies
<order>to reverse if"desc".
sort_frequency
sort_frequency is a Filtering & Sorting plugin. It sorts candidate events by the frequency of value appearance at an EventPath.
Functions:
{
"plugins": [
["sort_frequency", ["<event_path>", "<order?>"]]
]
}Arguments:
<event_path>:EventPath: (required) : Path to extract value for frequency counting from each event<order>:string: (optional) : Sort order -"asc"or"desc"(default:"desc")
IO:
- Writes to: Does NOT write to
IO. - Reads from: Does NOT read from
IO.
Behavior:
- Evaluates
<event_path>on each candidate event. - Counts occurrences of each unique value.
- Sorts events by frequency count.
- Applies
<order>to reverse if"asc".
count
count is a Transformation plugin. It counts filtered events or values at an EventPath and writes the result to IO.w.
Functions:
{
"plugins": [
["count", ["<output_key>", "<event_path?>"]]
]
}Arguments:
<output_key>:string: (required) : Key for storing count inIO.w<event_path>:EventPath: (optional) : Path to count values from (if omitted, counts filtered events)
IO:
- Writes to:
IOnamespace atw:count.<output_key> - Reads from: Filtered events (via EventPath)
Behavior:
- If
<event_path>is omitted: counts total filtered events. - If
<event_path>is provided: counts unique values at that path across all filtered events. - Writes count value to
IO.w:count.<output_key>.
sum
sum is a Transformation plugin. It sums numeric values at an EventPath and writes the result to IO.w.
Functions:
{
"plugins": [
["sum", ["<output_key>", "<event_path>"]]
]
}Arguments:
<output_key>:string: (required) : Key for storing sum inIO.w<event_path>:EventPath: (required) : Path to extract numeric values from
IO:
- Writes to:
IOnamespace atw:sum.<output_key> - Reads from: Filtered events (via EventPath)
Behavior:
- Extracts all numeric values at
<event_path>from filtered events. - Sums the values.
- Writes sum value to
IO.w:sum.<output_key>.
avg
avg is a Transformation plugin. It calculates average of numeric values at an EventPath and writes the result to IO.w.
Functions:
{
"plugins": [
["avg", ["<output_key>", "<event_path>"]]
]
}Arguments:
<output_key>:string: (required) : Key for storing average inIO.w<event_path>:EventPath: (required) : Path to extract numeric values from
IO:
- Writes to:
IOnamespace atw:avg.<output_key> - Reads from: Filtered events (via EventPath)
Behavior:
- Extracts all numeric values at
<event_path>from filtered events. - Calculates average.
- Writes average value to
IO.w:avg.<output_key>.
min
min is a Transformation plugin. It finds minimum value at an EventPath and writes the result to IO.w.
Functions:
{
"plugins": [
["min", ["<output_key>", "<event_path>"]]
]
}Arguments:
<output_key>:string: (required) : Key for storing minimum inIO.w<event_path>:EventPath: (required) : Path to extract values from
IO:
- Writes to:
IOnamespace atw:min.<output_key> - Reads from: Filtered events (via EventPath)
Behavior:
- Extracts all values at
<event_path>from filtered events. - Finds minimum value (numeric or alphabetic).
- Writes minimum value to
IO.w:min.<output_key>.
max
max is a Transformation plugin. It finds maximum value at an EventPath and writes the result to IO.w.
Functions:
{
"plugins": [
["max", ["<output_key>", "<event_path>"]]
]
}Arguments:
<output_key>:string: (required) : Key for storing maximum inIO.w<event_path>:EventPath: (required) : Path to extract values from
IO:
- Writes to:
IOnamespace atw:max.<output_key> - Reads from: Filtered events (via EventPath)
Behavior:
- Extracts all values at
<event_path>from filtered events. - Finds maximum value (numeric or alphabetic).
- Writes maximum value to
IO.w:max.<output_key>.
required
required is a Flow Control plugin. It marks a filter as being required to return results. If a required filter returns no results, the entire request SHOULD return empty. This MAY be useful for producing AND logic in an array of OR'd filters.
Functions:
{
"plugins": [
// required plugin has no functions or arguments
["required"]
]
}Arguments:
None.
IO:
- Writes to: Does NOT write to
IO. - Reads from: Does NOT read from
IO.
Behavior:
- Marks the filter as being required to return results.
- If this filter returns empty, the entire TRUST request SHOULD return empty.
schedule
schedule is a Flow Control plugin. It schedules automatic re-execution of the filter at specified intervals. Service providers MAY limit filter scheduling on a per subscription basis.
Functions:
{
"plugins": [
["schedule", ["<interval>", "<start?>", "<end?>"]]
]
}Arguments:
<interval>:TimeUnit: (required) : Interval for automatic updates (e.g.,"1h","30m","1d")<start>:timestamp|RelativeTime: (optional) : Start time for the schedule<end>:timestamp|RelativeTime: (optional) : End time for the schedule
IO:
- Writes to: Does NOT write to
IO. - Reads from: Does NOT read from
IO.
Behavior:
- Schedules the filter to re-execute at
<interval>frequency. - If
<start>is specified, scheduling begins at that time. - If
<end>is specified, scheduling stops at that time. - Service providers MAY enforce minimum/maximum intervals.
- Scheduled execution updates any published events with new data.
iterate
iterate is a Filtering & Sorting plugin. It executes the filter multiple times with different values for a specified field.
Functions:
{
"plugins": [
["iterate", ["<field>", "<event_path>", "<max?>"]]
]
}Arguments:
<field>:string: (required) : Filter field to iterate over (e.g.,"authors","#p")<event_path>:EventPath: (required) : Path to extract iteration values from previous filter results<max>:number: (optional) : Maximum number of iterations
IO:
- Writes to: Does NOT write to
IO. - Reads from: Does NOT read from
IO.
Behavior:
- Extracts unique values from
<event_path>in previous filter results. - Executes this filter once for each unique value.
- Sets
<field>to that value for each iteration. - Combines results from all iterations.
- If
<max>is specified, limits to first N values.
publish_every
publish_every is a Publishing plugin. It publishes separate events for each value found at an IO query path.
Functions:
{
"plugins": [
["publish_every",
// IO query to iterate over (required)
["<io_query>", "<max?>"],
// Event Publisher function (required)
["<kind>", "<relay?>", ...],
// Event Composer functions (optional)
["<fieldname>", "<io_query>"],
// Tag Composer functions (optional)
["#<tagname>", "<io_query>", ...]
]
]
}Arguments:
<io_query>:IO: (required) : points to an array of values inIOto iterate over<max>:number: (optional) : Maximum number of events to publish
Additional arguments follow the same pattern as the publish plugin for Event Publisher, Event Composer, and Tag Composer functions.
IO:
- Writes to: Does NOT write to
IO. - Reads from:
IOnamespace at specified query path
Behavior:
- Extract array of values from
<io_query>. - Creates and publishes one separate event for each value.
- Each event is composed using the same Event Publisher, Event Composer, and Tag Composer functions as the
publishplugin. - If
<max>is specified, limits to first N events. - Event
pubkeyandcreated_atfields (anddtag) SHOULD be set by the publisher, if not otherwise specified.
page
page is a Transformation plugin. It selects a specific page of tags from IO.# for pagination support.
Functions:
{
"plugins": [
["page", ["<page_number>", "<page_size?>"]]
]
}Arguments:
<page_number>:number: (required) : Page number (0-indexed)<page_size>:number: (optional) : Tags per page (defaults to service limit, e.g., 1000)
IO:
- Writes to:
IOnamespace atw.pagefor tracking page number - Reads from:
IO.#namespaces
Behavior:
- Reads all tag arrays from
IO.#namespaces. - Paginates tags based on
<page_size>. - Keeps only tags for the specified
<page_number>. - Writes page number to
IO.w.pagefor tracking.
Examples
Example 1: Required Filter
["TRUST", "<subscription_pubkey>", "<session_id>",
// Must have a kind 3 event
{
"kinds": [3],
"authors": ["${pov}"],
"plugins": [
["required"]
]
},
// Optional mute list
{
"kinds": [10000],
"authors": ["${pov}"]
}
]Example 2: Scheduled Updates
{
"kinds": [1],
"since": "now-24h",
"plugins": [
["schedule", ["1h", "now", "+7d"]],
["count", ["hourly_notes"]],
["publish", ["30078"]]
]
}Example 3: Iterate Over Network
["TRUST", "<subscription_pubkey>", "<session_id>",
// Get follows
{
"kinds": [3],
"authors": ["${pov}"]
},
// Get notes from each follow
{
"kinds": [1],
"since": "now-24h",
"plugins": [
["iterate", ["authors", "#p[][1]", "50"]]
]
}
]