Trusted Assertions (Sovereign Version)

Specifies: kind 30382 kind 10040

NIP-85

Trusted Assertions

draft optional

Certain Webs of Trust calculations require access to a large volume of events and/or computing power, making it virtually impossible to perform them directly on clients. This NIP allows users to offload such calculations to declared Trusted Assertion (TA) services, and for these providers to generate signed Trusted Assertion events for their clients’ to request and consume.

TA service providers MAY choose EITHER to publish TA events “ON_DEMAND” (where every event contains only the results requested in a client’s REQ filter) OR to publish “ALL_IN_ONE” TA events (where every event contains ALL of the results specified in a user’s published TA preferences). Either way, calculation results MAY be refined over time (represented as ‘newer’ events being delivered, with the same address). Requesting clients SHOULD keep REQ sessions OPEN to allow results to improve over time.

TA Event Kinds

Trusted Assertions are always addressable (replaceable) events with the d tag being the “subject of the assertion”. This NIP currently recognizes four kinds of subjects for which TA results can be generated: pubkeys, regular events, addressable events, and external references. Each subject kind is mapped to an event kind. When parsing these events for TA data, a subject path is used to match to a WoT verified user (eg: the author or mentioned user) in the event.

Subject Kind Event Kind Expected d tag format Default Subject Path*
User 30382 user : <pubkey> pubkey
Event 30383 event : <id> e:1
Addressable Event 30384 a tag : <kind>:<pubkey>:<d_tag> a:1
External Content 30385 nip-73 : <external_reference> i:1

TA Event Tags

Trusted Assertion events MAY contain any number of uppercase W tags. This allows REQ filtering on #W for query strings. Trusted Assertion events MAY ALSO contain any number of lowercase w tags. This allows REQ filtering on #w for context strings.

// OPTIONAL W/w filters in a REQ message sent for TA events
// If NEITHER `#W` nor `#w` are specified, then an "ALL_IN_ONE" event MAY be delivered, 
// where query strings are fetched from the user's published TA preferences.
{
  "#W" : ["<query>"],
  // If `#w` is omitted, then `context` is assumed to be "default".
  "#w" : ["<context>"],
  //...
}
// OPTIONAL W/w tags in a TA event
// Any number of TA results are permitted in an event.
[
  ["W", "<query>", "<context>", "<result>"],
  // The `w` tag MAY be omitted for results with "default" context.
  ["w", "<context>", "<query>", "<result>"]
  // Legacy TA tags MAY be present in older "ALL_IN_ONE" events.
  ["<legacy_tag_string>", "<result>"],
  //...
]

A Simple Example :

Users MAY have published TA preferences OR clients MAY use their own provider :

{
  "kind": 10040,
  "pubkey": "a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411e88",
  "tags" : [
    ["default", "25f60700378a4879180dcbbb4a5027850411e88a691e98d9987c964521dff600", "wss://ta.example.com"],
    //...
  ],
  //...
}

The client sends a REQ message for two trusted assertions using the TA service’s “default” context :

{
  "authors" : ["25f60700378a4879180dcbbb4a5027850411e88a691e98d9987c964521dff600"],
  "kinds" : ["30382"],
  "#d" : ["e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411"],
  // Inclusion of a #W filter supports both "ON_DEMAND" and "ALL_IN_ONE" services
  "#W" : ["rank", "2:latest/1:count:p"],
}

The TA service responds with a single TA event showing that (subject) user has a trust rank of 89 :

{
  "kind": 30382,
  "pubkey" : "25f60700378a4879180dcbbb4a5027850411e88a691e98d9987c964521dff600",
  "tags": [
    ["d", "e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411"], 
    // "ON_DEMAND" services will ONLY include the requested results in their generated events.
    ["W", "rank", "default", "89"], // user trust rank = 89
    ["W", "2:latest/1:count:p", "default", "1234"], // number of followers = 1234
    // "ALL_IN_ONE" services may include additional results in their published events.
    ["W", "1:earliest/1:time:created_at", "default", "2025-12-21T11:57:00Z"], // earliest post = Dec 21, 2025
    ["W", "1:all:count", "default", "4321"], // total number of posts = 4321
  ],
  "content": "",
  //...
}

TA Query and Context strings

Query and Context strings are how TA events are requested from (and published by) a TA service. The context string is used by a TA service to fetch (or generate) a list of “verified users”, for event processing. The query string is used to specify what event kinds to fetch and what data should be “harvested” from them. Together, these two strings allow a TA service to generate specific and targeted TA events for any use case.

Query strings

TA queries do the “harvesting” of event data, given a list of “verified users”.

If the TA query consists of ONLY "rank" as a string value :

The TA service MUST return the subjects’ rank directly from the WoT service (for the given “context”) as the result value (normalized to 0-100).

Otherwise, TA queries MUST have the following syntax :

<kinds>:<filterstring>:<opstring>:<datapath?>@<subjectpath?>
  1. <kinds> : kinds is a colon : separated list of kind numbers identifying what event kinds to query for data.

  2. :<filterstring> : filterstring is a known string (see Appendix 3) with optional parameters (all separated by backslashes /) used to limit the subset of qualifying query events.

  3. :<opstring> : opstring is a known string (see Appendix 4) specifying “what to do” with a qualifying query event, or the data harvested from it.

  4. :<datapath> : datapath is a colon : separated pathstring (see Appendix 5) specifying HOW to find the desired data within a qualifying query event. This component MAY be empty ":", and MAY be omitted entirely if @<subjectpath> component is also omitted.

  5. @<subjectpath> : subjectpath is a colon : separated pathstring (see Appendix 5) specifying WHERE the subject key (#d value) should be found on qualifying query events. The path MUST lead to EITHER a qualified subject identifier (eg: pubkey, e:1, a:1, i:1) OR a boolean value OR a number that can be coerced into a boolean value to determine whether the event qualifies to have its data harvested.

  • Output format for result is determined by the opstring OR the expected format found at datapath. (See Appendix 4 for more details.)

Context strings

A “context” string represents a “set of WoT filters used to compute a list of verified users”, and can have any arbitrary value. This string MAY come from a TA or WoT service’s list of default contexts, OR a user published list of contexts (spec TBD), OR it MAY be input directly by the user. If no context is provided, the value of “default” MUST be used. (See Appendix 1 about trust services.)

Declaring Trusted Service Providers

A kind 10040 (replaceable event with preference tags) is how users declare their preferred TA service providers. The expected structure for a preference tag is ["<query | prefstring>", "<pubkey>", "<relayurl>"].

  • The query (a query string as defined above) allows users to specify a provider preference for ONLY specific queries. This is useful for SOME services that don’t provide “arbitrary calculations” (as is the case with many “ALL_IN_ONE” providers). As such, individual preference tags SHOULD be added for EACH calculation desired from the service.
  • The prefstring (as defined in Appendix 6) allows users to specify (with varying granularity) individual providers for a variety of query kinds and operations. Even WoT providers may be specified in this manner.
  • The pubkey identifies the provider’s identity, and MAY be unique to each user publishing 10040 preferences (or even unique to an individual preference).
  • The relayurl is used to identify the preferred relay for fetching the provider’s TA events. This MAY be a service specific relay OR a user determined relay.
  • Users MAY specify preference tags privately by JSON-stringifying and encrypting a tag list in the .content using NIP-44.
  • Users MAY specify their preferences in legacy 10040 string format. These SHOULD be treated as query string preferences by TA receiving clients. See Appendix 6 for conversion details.
  • Users MAY specify SEPARATE preferences for WoT service providers. (See Appendix 1 about trust services.)
{
  "kind": 10040,
  "pubkey": "a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411e88",
  "tags": [
    // user might have a preference for default TA provider
    ["default", "4fd5e210530e4f6b2cb083795834bfe5108324f1ed9f00ab73b9e8fcfe5f12fe", "wss://nip85.nostr.band"],
    // user might have a special WoT provider for generating content ranks.
    ["30383:30384:30385:context", "3d842afecd5e293f28b6627933704a3fb8ce153aa91d790ab11f6a752d44a42d", "wss://nostr.wine"],
    // user might have a TA provider for processing zap events
    ["9735", "4fd5e210530e4f6b2cb083795834bfe5108324f1ed9f00ab73b9e8fcfe5f12fe", "wss://nip85.nostr.band"],
  ],
  "content": nip44Encrypt(JSON.stringify([
    // user might secretly specify an overriding preference (with `!` prefix) for ALL 30382 queries
    ["!30382", "4fd5e210530e4f6b2cb083795834bfe5108324f1ed9f00ab73b9e8fcfe5f12fe", "wss://nip85.nostr.band"],
  ]),
  //...
}

Final Considerations

TA services SHOULD render ONLY the requested assertions in each published TA event. TA services SHOULD update TA events as fast as new information arrives, but only if the results of each calculation actually changes, to avoid re-downloading the same information.

TA services MAY limit access to the results by requiring relay authentication.

In TAs, p, e, and a tags with the same value as the d tag MAY be used to add a relay hint to the home relay of that user or event.

WoT and TA services can offer their own ways to calculate results. For instance, the “default” context of one WoT provider might remove the user’s muted public keys while another provider keeps them. Users can then choose how they want to see this information by configuring their provider settings (on provider apps) OR picking a different provider in their preferred client.



Appendix 1 : Trust Service Architecture

This NIP allows for two distinct “trust services”, which MAY or MAY NOT be offered by the same provider:

  1. Web of Trust (WoT) Services SHOULD calculate “contextually aware” lists of verified users, which are indexed by a context string. A WoT service answers the question: “Who should be verified in a given context?”

  2. Trusted Assertion (TA) Services SHOULD generate “trustworthy” assertions about any subject (users, events, etc.) by extracting data (according to query parameters) from published events where verified users have interacted with that subject. A TA service answers the question: “What is the engagement on this content from that list of verified users?”

When a TA service provider receives a REQ request for a TA event (with query and context strings), it SHOULD EITHER :

A. resolve the specified context using its own (internal) WoT service, OR B. forward context resolution to the subscribed user’s preferred WoT provider

  • If the subscribed user has WoT provider preferences published (in a 10040 event), the TA service SHOULD forward context resolution to the preferred WoT provider AND retrieve a list of verified users in return.
  • If a client sends a user’s TA requests to THEIR OWN TA provider (eg: the user doesn’t have applicable TA prefs published), then the TA provider SHOULD STILL use the subscriber WoT preferences (despite the user having published WoT preferences or not).

The recommended TA data flow is:

  User TA Preferences
    ↓           ↓
Client → TA service ←→ WoT Provider
    ↑           ↓
  Published TA Event

This NIP specifies:

  • ✅ How users declare TA and WoT provider preferences
  • ✅ How TA events can be requested and consumed by clients
  • ✅ A standard TA “query” interface across providers.

This NIP DOES NOT specify:

  • ❌ How WoT services communicate with TA services
  • ❌ How WoT services communicate with clients
  • ❌ A standard WoT “context” interface across providers

Appendix 2 : Handling Legacy NIP-85 TA Events and Preferences

For backward compatibility, legacy (old NIP-85) ‘tag strings’ MAY be used in place of query strings. These MAY be included in the REQ filter (as non-standard filters) for requesting TA events OR they MAY be included in TA events and TA preference events.

  • Clients interfacing with legacy providers, SHOULD NOT include #W or #w filters in their REQ requests for TA events. (You know a legacy provider when #W/#w filter returns null). Legacy TA services will return a SINGLE TA event with ALL LEGACY TAGS supported by them included in the event (in the format of ["<tagstring>", "<result>"]).

  • TA services interfacing with legacy clients will receive REQ requests WITHOUT #W or #w filters, and possibly WITH non-standard filter keys corresponding to legacy tag strings. These providers SHOULD return a SINGLE TA event with ALL LEGACY TAGS ‘supported’ by them included in the event (in the format of ["<tagstring>", "<result>"]) using their OWN “default” WoT context.

  • Legacy TA preference events will have preference tags in the format of ["<kind>:<tagstring>", "<pubkey>", "<relayurl>"], where kind is a TA event kind (e.g. 30382, 30383, 30384, 30385) and tagstring is a legacy tag string (without kind numbers or colons :). Whenever a legacy tagstring is found, clients and services SHOULD use the tables in Appendix 7 to get the querystring conversion.

Please consult Appendix 7 for legacy tag string conversions.

Example Support for Legacy TA Services

User has legacy preferences published :

{
  "kind": 10040,
  "pubkey": "a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411e88",
  "tags" : [
    ["30382:rank", "e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411e88a691", "wss://ta.example.com"],
    ["30382:followers", "e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411e88a691", "wss://ta.example.com"],
    ["30382:first_created_at", "e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411e88a691", "wss://ta.example.com"],
    // user might have preference in the current format ... that DO NOT override (more specific) legacy preferences
    ["default", "4fd5e210530e4f6b2cb083795834bfe5108324f1ed9f00ab73b9e8fcfe5f12fe", "wss://nip85.nostr.band"],
    //...
  ],
  //...
}

The client discovers the user’s legacy preferences and requests an event from the preferred legacy service :

{
  "authors" : ["e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411e88a691"],
  "kinds" : ["30382"],
  "#d" : ["e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411"],
}

TA service delivers an “ALL_IN_ONE” event WITH legacy tags (see Appendix 7 for conversion details)

{
  "kind": 30382,
  "pubkey" : "e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411e88a691",
  "tags": [
    ["d", "e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411"], 
    ["rank", "89"], // user trust rank = 89
    ["followers", "1234"], // number of followers = 1234
    ["first_created_at", "2025-12-21T11:57:00Z"], // first post = Dec 21, 2025
    ["post_cnt", "4321"] // total number of posts = 4321
    // If the TA service NOW supports the current format, it MAY deliver `W` tags instead
    ["W", "rank", "default", "89"], // user trust rank = 89
    ["W", "followers", "default", "1234"], // number of followers = 1234
    ["W", "first_created_at", "default", "2025-12-21T11:57:00Z"], // first post = Dec 21, 2025
    ["W", "post_cnt", "default", "4321"] // total number of posts = 4321
  ],
  "content": "",
  //...
}

Appendix 3 : filterstring values

A filterstring can have any of the following backslash / separated values :

  • all : all events pass the filter
  • earliest : only the first count events (by created_at) pass the filter
  • /<count> = an integer
  • latest : only the latest count events (by created_at) pass the filter
  • /<count> = an integer
  • range : the events are grouped (by created_at) according to duration, with (optionally) one or more subset and a count of the final subset (from current time) passing the filter.
  • /<duration> = years | months | weeks | days | hours | minutes | seconds
  • /<subset> = start | end | middle | top | index
  • /<count> = an integer
  • top : the events are sorted according to the occurrence of values discovered by <datapath>, with only the top count passing the filter.
  • /<count> = an integer

Filterstring Examples

all - Include all events:

  • 9735:all:sum:description:amount - Sum all zap amounts

earliest/N - First N events (oldest):

  • 9735:earliest/5:value[]:description:amount - Get amounts from the first 5 zaps received

latest/N - Latest N events (most recent):

  • 1:latest/100:count - Count the latest 100 posts
  • 1:latest/50:value[]:content - Get content from the latest 50 posts

range/duration - Group by time period:

  • 1:range/days:count[] - Count posts per day (all days)
  • 9735:range/weeks:sum[]:description:amount - Sum zaps per week
  • 1:range/hours:avg[]:content - Average content length per hour

range/duration/subset - Select specific time buckets:

  • 1:range/days/end:count - Count posts in the most recent day
  • 9735:range/days/end/7:sum[]:description:amount - Sum zaps for the last 7 days
  • 1:range/hours/top/5:count[] - Count posts in the top 5 most active hours

top/N - Most frequent values:

  • 1:top/10:value[]:t - Get the top 10 most used hashtags
  • 1:top/5:count[]:p - Count mentions for the top 5 most mentioned users
  • 9735:top/20:sum[]:description:pubkey - Sum zaps grouped by top 20 senders

Appendix 4 : opstring values

An opstring MAY be any ONE of the following string values :

  • count | count[] : returns an integer count of events or values found in an array, or an array of [<value>, <count>] (<value> as found by <datapath> in Appendix 5) if [] is used
  • sum | sum[] : returns a number sum of all values found in an array, or an array of [<value>, <sum>] (<value> as found by <datapath> in Appendix 5) if [] is used .
  • avg | avg[] : returns a number average of all values found in an array, or an array of [<value>, <avg>] (<value> as found by <datapath> in Appendix 5) if [] is used.
  • median | median[] : returns the number median of all values found in an array, or an array of [<value>, <median>] (<value> as found by <datapath> in Appendix 5) if [] is used.
  • value | value[] : returns a string or number (as found by <datapath> in Appendix 5), or an array of string[] or number[] if [] is used.
  • time | time[] : returns an ISO 8601 formatted time string (as found by <datapath> in Appendix 5), or an array of time[] if [] is used.
  • any | any[] : returns a JSON stringified value (as found by <datapath> in Appendix 5), or an array of <JSON> if [] is used.

Opstring Examples

count - Count events or values:

  • 1:all:count - Count all kind 1 events from verified users → "342"
  • 9735:all:count:description:amount - Count how many zaps have an amount → "156"
  • 1:all:count[]:t - Count occurrences of each hashtag → [["nostr",89], ["bitcoin",67], ["freedom",45]]

sum - Sum numeric values:

  • 9735:all:sum:description:amount - Total sats received from zaps → "2100000"
  • 9735:range/days:sum[]:description:amount - Daily zap totals with timestamps → [["2024-12-16","50000"], ["2024-12-17","75000"], ["2024-12-18","120000"]]

avg - Average numeric values:

  • 9735:all:avg:description:amount - Average zap amount → "13461.54"
  • 1:range/weeks:avg[]:content - Average content length per week → [["2024-W50", 280], ["2024-W51", 315], ["2024-W52", 298]]

median - Median of numeric values:

  • 9735:all:median:description:amount - Median zap amount → "5000"
  • 1:range/months:median[]:content - Median content length per month → [["2024-10", 250], ["2024-11", 265], ["2024-12", 270]]

value - Extract single or multiple values:

  • 1:top/10:value[]:t - Top 10 hashtags by frequency → ["nostr","bitcoin","privacy","freedom","tech","art","music","photography","memes","news"]
  • 9735:latest/1:value:description:amount - Most recent zap amount → "21000"
  • 1:all:value[]:p - All mentioned pubkeys → ["pubkey1...","pubkey2...","pubkey3..."]

time - Extract timestamps:

  • 1:latest/1:time:created_at - Timestamp of most recent post → "2024-12-19T18:25:00Z"
  • 9735:all:time[]:created_at - All zap timestamps → ["2024-12-19T10:00:00Z","2024-12-19T11:30:00Z"]

any - Extract any JSON value:

  • 9735:latest/1:any:description - Full zap description object → {"amount":21000,"pubkey":"...","content":"Great post!"}
  • 1984:all:any[]:p:2 - All report reasons → ["spam","nudity","impersonation"]

Examples with range filter:

  • 1:range/days:count[] - Posts per day with dates → [["2024-12-16", 45], ["2024-12-17", 52], ["2024-12-18", 38], ["2024-12-19", 61]]
  • 9735:range/weeks:sum[]:description:amount - Weekly zap totals with week labels → [["2024-W50", 150000], ["2024-W51", 200000], ["2024-W52", 175000]]
  • 1:range/hours/top/3:count[] - Post count for top 3 hours with timestamps → [["2024-12-19T14:00:00Z", 12], ["2024-12-19T18:00:00Z", 10], ["2024-12-19T20:00:00Z", 9]]

Appendix 5 : pathstring values

A pathstring is a colon : separated list used to navigate into an event’s structure to find data. It can contain ANY of the following JSON safe (and colon escaped) strings, in this order:

  1. Event field name - e.g., pubkey, created_at, content, kind
  2. Event tag key - e.g., p, e, a, t, description
  3. Event tag index - e.g., 1, 2, 3 (which element of the tag array)
  4. JSON object key OR array index - for navigating nested JSON in content or tag values
  5. Conditional suffix - EITHER ="<value>" (match check) OR ? (existence check) to output booleans

Pathstring Examples

Example 1: Simple field access

  • pubkey → Returns the event’s pubkey field
  • created_at → Returns the event’s timestamp

Example 2: Tag navigation

  • p:1 → Returns the first value (index 1) of the first p tag found
  • e:2 → Returns the second value (index 2) of the first e tag (typically a relay hint)
  • t → Returns the first value of a t tag (hashtag)

Example 3: JSON content navigation

  • description:amount → In a zap event’s description tag, parse the JSON and get the amount field
  • description:pubkey → In a zap event’s description tag, get the pubkey of who sent the zap

Example 4: Conditional checks

  • p:2="nudity" → Returns true if the second value of a p tag equals “nudity”
  • i:3="fork" → Returns true if the third value of an i tag equals “fork”
  • content? → Returns true if the content field exists and is non-empty

Example 5: Complex paths

  • description:amount@description:pubkey → Used in queries where datapath is description:amount and subjectpath is description:pubkey
    • This finds zaps where the subject (user being queried) is the sender, not the receiver

Appendix 6 : prefstring values

A prefstring MUST be either “default” OR a colon : separated list of the following params :

  1. all OR <kindstring>:
    • EITHER a single string all to indicate less specificity,
    • OR any number of integer kind numbers to increase specificity
      • (TA kind numbers indicate a preferred provider for TA events of these kinds.)
      • (OTHER integer kind numbers indicate a preferred provider for calculating event data on these kinds.)
    • WITH ! prefix indicates a preference that should override ALL other less specific preferences. (useful for testing new algos)
  2. any OR <opstring>:
    • EITHER a SINGLE string any to indicate less specificity,
    • OR a SINGLE string matching any of <opstring> (without [] suffix) to limit the scope of the preference to a specific calculation operation. (see Appendix 4)
  3. OPTIONAL context OR <context> :
    • A SINGLE string as third parameter indicates a user’s preference to use a specific WoT provider for ALL queries matching the preference parameters AND the specified context. The string context is used to indicate a default WoT provider preference for all contexts.
  • The prefstring (list of preferences) SHOULD be ‘ANDed’ together by clients to determine a user’s preference and priority. More specific preferences SHOULD have priority, when requesting TA events by query string.
  • To prevent conflicts, the second param SHOULD always be considered more specific than the first (eg: all:value takes priority over 1:any when determining a preferred provider for 1:top/10:value[]:t, a query string for “Popular Hashtags”).
  • When a THIRD parameter is provided (anything after rank or <opstring>), then the provider details (pubkey and relayurl) MUST be used as the preferred WoT provider to which the TA service sends “context” and fetches a list of “verified users” BEFORE processing the query string.

Prefstring Examples

Least specific (catches everything):

  • default - Fallback provider for all queries

Low specificity (by operation):

  • all:value - Provider for all value extraction operations
  • all:rank - WoT provider for all rank calculations

Medium specificity (by kind):

  • !9735 - Provider for kind 9735 (zaps) calculations (with ! override)

High specificity (kind + operation):

  • 1:count - Provider for counting kind 1 events
  • 9735:sum - Provider for summing zap amounts (overridden by !9735)
  • 30382:rank - WoT provider for ranking users

Highest specificity (kind + operation + context):

  • 30382:rank:only_zombies - WoT provider for user ranking in “only_zombies” context

Appendix 7 : Legacy Tag String Conversions

Use these tables to convert legacy tag strings to TA query and pathstring formats.

  • Output format for all queries is determined by the opstring. (See Appendix 4)

For Kind 30382 (users as subject) :

Default subjectpath is @pubkey (subject is the value of the event pubkey field).

Assertion Legacy Tag String TA Query Conversion Pathstring Conversion
User Rank rank rank 30382:rank
Follower Count followers 2:latest/1:count:p 30382:2:count
Earliest Post Time first_created_at 1:earliest/1:time:created_at 30382:1:time
Post Count post_cnt 1:all:count 30382:1:count
Post Count This year n/a 1:range/years/end:count 30382:1:count
Posts Per Day n/a 1:range/days:avg 30382:1:avg
Comment Count reply_cnt 1111:all:count 30382:1111:count
Reactions Count reactions_cnt 17:all:count 30382:17:count
Zap Amount Received zap_amt_recd 9735:all:sum:description:amount 30382:9735:sum
Zap Amount Sent zap_amt_sent 9735:all:sum:description:amount@description:pubkey 30382:9735:sum
Zap Number Received zap_cnt_recd 9735:all:count 30382:9735:count
Zap Number Sent zap_cnt_sent 9735:all:count@description:pubkey 30382:9735:count
Avg Zap Amount/day recd zap_avg_amt_day_recd 9735:range/days:avg:description:amount 30382:9735:avg
Avg Zap Amount/day sent zap_avg_amt_day_sent 9735:range/days:avg:description:amount@description:pubkey 30382:9735:avg
Reported Count reports_cnt_recd 1984:all:count@p:1 30382:1984:count
Reported Count Nudity n/a 1984:all:count:p:2="nudity"@p:1 30382:1984:count
Reported Most Common n/a 1984:top/5:value[]:p:2@p:1 30382:1984:value
Reports Sent reports_cnt_sent 1984:all:count 30382:1984:count
Popular Hashtags n/a 1:top/10:value[]:t 30382:1:value
Generally active start active_hours_start 1:range/hours/start/top/1:time:created_at 30382:1:time
Generally active end active_hours_end 1:range/hours/end/top/1:time:created_at 30382:1:time
Generally active hours n/a 1:range/hours/top/3:time[]:created_at 30382:1:time

For Kind 30383 (events as subject) :

Default subjectpath is @e:1 (subject is the first index of an e tag event id).

Assertion Legacy Tag String TA Query Conversion Pathstring Conversion
Content Rank rank rank 30383:rank
Event Comment Count comment_cnt 1111:all:count 30383:1111:count
Event Quote Count quote_cnt 1:all:count@q:1 30383:1:count
Event Repost Count repost_cnt 6:all:count 30383:6:count
Event Reaction Count reaction_cnt 1:17:all:count 30383:17:count
Event Zap Count zap_cnt 9735:all:count@description:e:1 30383:9735:count
Event Zap Amount zap_amount 9735:all:sum:description:amount@description:e:1 30383:9735:sum

For Kind 30384 (addressable events as subject) :

Default subjectpath is @a:1 (subject is the first index of an a tag addressable event reference).

Assertion Legacy Tag String TA Query Conversion Pathstring Conversion
Content Rank rank rank 30384:rank
Event Comment Count comment_cnt 1111:all:count 30384:1111:count
Event Quote Count quote_cnt 1:all:count@q:1 30384:1:count
Event Repost Count repost_cnt 6:all:count 30384:6:count
Event Reaction Count reaction_cnt 1:17:all:count 30384:17:count
Event Zap Count zap_cnt 9735:all:count@description:a:1 30384:9735:count
Event Zap Amount zap_amount 9735:all:sum:description:amount@description:a:1 30384:9735:sum

For Kind 30385: External identifier as Subject

Default subjectpath is @i:1 (subject is the first index of an i tag external identifier).

Providers can rate books, locations, movies, websites, and hashtags using NIP-73 identifiers. NIP-73 i/k tags pairs should be added to the output TA event.

Assertion Legacy Tag String TA Query Conversion Pathstring Conversion
Content Rank rank rank 30385:rank
Comment Count comment_cnt 1111:all:count 30385:1111:count
Reaction Count reaction_cnt 17:all:count 30385:17:count
Count Rel ‘fork’ n/a 17:all:count:i:3="fork" 30385:17:count

Appendix 8 : More Examples

Here are a couple of more involved examples of typical TA transactions.

To retrieve the follower count for a subject user, using the context “only_zombies”:

The current user has subscribed to the “only_zombies” user list (WoT provider) for detecting zombie npubs.

{
  "kind" : "10040",
  "tags" : [
    ["all:any:only_zombies", "0b04ac14550f78ad19ae493aaab5e0bcf53c9c412b1d2e10ced28aeb48acbd3f", "wss://relay.plebsvszombies.cc"],
  ]
}

The client sends the following REQ filter to wss://relay.plebsvszombies.cc requesting all of the following WRT pubkeys that match the “only_zombies” context:

{
  "authors": ["0b04ac14550f78ad19ae493aaab5e0bcf53c9c412b1d2e10ced28aeb48acbd3f"],
  "kinds": ["30382"],
  "#d": ["e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411"],
  "#W": ["2:latest/1:count:p@pubkey", "2:all:value[]:pubkey@p:1"],
  "#w": ["only_zombies"]
}

The relay returns the following TA event :

{
  "author": "25f60700378a4879180dcbbb4a5027850411e88a691e98d9987c964521dff600",
  "kind": 30382,
  "tags": [
    ["d", "e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411"],
    ["W", "2:latest/1:count:p@pubkey", "only_zombies", "342"],
    ["w", "only_zombies", "2:latest/1:count:p@pubkey", "342"],
    ["W", "2:all:value[]:pubkey@p:1", "only_zombies", "21"],
    ["w", "only_zombies", "2:all:value[]:pubkey@p:1", "21"]
  ],
  "content": "",
  //...
}

First query returns a count of pubkeys that might be zombies in the subject’s follow list.

  • 2 = Query kind 2 events (follow lists per NIP-02)
  • latest/1 = Only fetch the most recent event
  • count = Count the number
  • p = Of p tags (pubkey references) in the event
  • @pubkey = Where the subject (user being queried) appears as the event author

Second query returns a list of subject followers that might also be zombies.

  • 2 = Query kind 2 events (follow lists per NIP-02)
  • all = Fetch all events
  • value[] = Get the values
  • pubkey = Of the author pubkey from the events
  • @p:1 = Where the subject (user being queried) appears as a p tag in the event

To retrieve the ten most common hashtags used by a user

{
  "kind": 10040,
  "tags": [
    // user might prefer an AI powered TA provider for processing string values.
    ["!all:value", "4fd5e210530e4f6b2cb083795834bfe5108324f1ed9f00ab73b9e8fcfe5f12fe", "wss://nip85.nostr.band"],
    // user might have their own zaps based web of trust algo
    ["all:any:web_of_zaps", "4fd5e210530e4f6b2cb083795834bfe5108324f1ed9f00ab73b9e8fcfe5f12fe", "wss://nip85.nostr.band"],
  ]
}

The client sends the following REQ filter:

{
  "authors": ["25f60700378a4879180dcbbb4a5027850411e88a691e98d9987c964521dff600"],
  "kinds": ["30382"],
  "#d": ["e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411"],
  "#W": ["1:top/10:value[]:t"],
  "#w": ["default"]
}

Relays return the following event published by the TA service:

{
  "author": "25f60700378a4879180dcbbb4a5027850411e88a691e98d9987c964521dff600",
  "kind": 30382,
  "tags": [
    ["d", "e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411"],
    ["W", "1:top/10:value[]:t", "default", '["nostr","bitcoin","privacy","freedom","tech","art","music","photography","memes","news"]'],
    ["w", "default", "1:top/10:value[]:t", '["nostr","bitcoin","privacy","freedom","tech","art","music","photography","memes","news"]']
  ],
  "content": "",
  //...
}

Query returns an array of the top 10 most frequent hashtags from the subject’s notes.

  • 1 = Query kind 1 events (text notes)
  • top/10 = Sort by frequency, return top 10
  • value[] = Return an array of values
  • t = Look at t tags (hashtags)
  • (no @subjectpath means use default: @pubkey)

Looking for comments…

Searching Nostr relays. This may take a moment the first time this article is opened.