This document maps NIP-85 Trusted Assertion tags to PrimalServer methods and response fields.
PrimalServer provides limited support for NIP-85 statistics:
- ✅ Supported: User follower counts, user scores/ranks, and comprehensive event-level statistics (likes, replies, reposts, zaps)
- ❌ Not Supported: User post counts, reply counts, zap totals, reports, topics, active hours, addressable event stats, and NIP-73 identifier stats
The supported fields are accessed through methods like getUserInfos(), getUserProfile(), getFeed(), getEvents(), and getThreadView().
| NIP-85 Tag | NIP-85 Description | PrimalServer Method | Response Field |
|------------|-------------------|---------------------|----------------|
| followers | Follower Count | getUserInfos(), getUserProfile() | UserInfo.followerCount, UserProfileResponse.profile.followers_count (kind 10000133) |
| rank | User Rank (0-100) | getUserInfos() | UserInfo.score (kind 10000108) |
| NIP-85 Tag | NIP-85 Description | PrimalServer Method | Response Field |
|------------|-------------------|---------------------|----------------|
| rank | Event Rank (0-100) | getFeed(), getEvents(), getThreadView() | FeedPost.stats.score, EventsResponse.eventStats[id].score (kind 10000100) |
| comment_cnt | Event Comment Count | getFeed(), getEvents(), getThreadView() | FeedPost.stats.replies, EventsResponse.eventStats[id].replies |
| repost_cnt | Event Repost Count | getFeed(), getEvents(), getThreadView() | FeedPost.stats.reposts, EventsResponse.eventStats[id].reposts |
| reaction_cnt | Event Reaction Count | getFeed(), getEvents(), getThreadView() | FeedPost.stats.likes, EventsResponse.eventStats[id].likes |
| zap_cnt | Event Zap Count | getFeed(), getEvents(), getThreadView() | FeedPost.stats.zaps, EventsResponse.eventStats[id].zaps |
| zap_amount | Event Zap Amount (sats) | getFeed(), getEvents(), getThreadView() | FeedPost.stats.satszapped, EventsResponse.eventStats[id].satszapped |
Not supported by PrimalServer - no methods available for addressable event statistics.
Not supported by PrimalServer - no methods available for NIP-73 identifier statistics.
Primal includes some fields not in NIP-85:
| Field | Description | PrimalServer Method | Response Field |
|-------|-------------|---------------------|----------------|
| mentions | Number of times event is mentioned | getFeed(), getEvents(), getThreadView() | FeedPost.stats.mentions, EventsResponse.eventStats[id].mentions |
| score24h | 24-hour engagement score | getFeed(), getEvents(), getThreadView() | FeedPost.stats.score24h, EventsResponse.eventStats[id].score24h |
| bookmarks | Number of bookmarks | getFeed(), getEvents(), getThreadView() | FeedPost.stats.bookmarks, EventsResponse.eventStats[id].bookmarks |
| membership | Premium membership information (kind 10000169) | getUserProfile(), getUserInfos() | UserProfileResponse.membership, UserInfo.membership |
The Primal API uses custom event kinds (10000000+) for enriched responses:
- 10000100 - EVENT_STATS: Event statistics (likes, replies, zaps, etc.)
- 10000105 - USER_PROFILE: User profile information
- 10000107 - REFERENCED_EVENT: Referenced events in threads
- 10000108 - USER_SCORES: User scores/rankings
- 10000113 - RANGE: Response range metadata
- 10000115 - EVENT_ACTIONS_COUNT: User's actions on events
- 10000117 - DIRECTMSG_COUNT: Direct message counts
- 10000119 - MEDIA_METADATA: Media metadata
- 10000128 - LINK_METADATA: Link preview metadata
- 10000129 - ZAP_EVENT: Zap event details
- 10000133 - USER_FOLLOWER_COUNTS: Follower counts
- 10000134 - DIRECTMSG_COUNT_2: DM counts v2
- 10000136 - NOSTR_STATS: Network statistics
- 10000138 - USER_PUBKEY: User public key info
- 10000141 - EVENT_RELAYS: Event relay information
- 10000158 - USER_PRIMAL_NAMES: Primal verified names
- 10000168 - MEMBERSHIP_LEGEND_CUSTOMIZATION: Premium member customization
- 10000169 - MEMBERSHIP_COHORTS: Membership tier info
1. No direct NIP-85 implementation: Primal uses custom event kinds (10000100+) instead of NIP-85's 30382-30385 range
2. Limited user-level statistics: Most NIP-85 user statistics (post counts, reply counts, zap totals, etc.) are not exposed through PrimalServer methods
3. Event-level statistics well-supported: Event stats (likes, replies, reposts, zaps) are available through multiple methods
4. Additional granularity: Primal has score24h, bookmarks, and mentions not in NIP-85
5. No addressable/NIP-73 stats: These would need to be implemented
CREATE TABLE event_stats (
event_id bytea PRIMARY KEY,
author_pubkey bytea NOT NULL,
created_at bigint NOT NULL,
likes bigint NOT NULL,
replies bigint NOT NULL,
mentions bigint NOT NULL,
reposts bigint NOT NULL,
zaps bigint NOT NULL,
satszapped bigint NOT NULL,
score bigint NOT NULL,
score24h bigint NOT NULL
)
CREATE TABLE pubkey_followers_cnt (
key bytea PRIMARY KEY, -- pubkey
value bigint NOT NULL -- follower count
)
CREATE TABLE pubkey_zapped (
pubkey bytea PRIMARY KEY,
zaps bigint NOT NULL,
satszapped bigint NOT NULL
)
CREATE TABLE pubkey_events (
pubkey bytea NOT NULL,
event_id bytea NOT NULL,
created_at bigint NOT NULL,
is_reply bigint NOT NULL
)
{
"kind": 30382,
"tags": [
["d", "e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411"],
["rank", "89"],
["followers", "1234"]
],
"content": ""
}
import { PrimalServer } from './PrimalServer.ts';
const server = new PrimalServer('wss://cache.primal.net/v1');
// Get user statistics (followers, rank/score)
const userInfo = await server.getUserInfos([
'e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411'
]);
const user = userInfo.users.get('e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411');
console.log('Rank/Score:', user?.score); // 89
console.log('Followers:', user?.followerCount); // 1234
{
"kind": 30383,
"tags": [
["d", "event_id_here"],
["rank", "95"],
["comment_cnt", "42"],
["reaction_cnt", "156"],
["zap_cnt", "12"],
["zap_amount", "5000"]
],
"content": ""
}
// Get event statistics
const events = await server.getEvents(['event_id_here'], true);
const stats = events.eventStats.get('event_id_here');
console.log('Rank/Score:', stats?.score); // 95
console.log('Comments:', stats?.replies); // 42
console.log('Reactions:', stats?.likes); // 156
console.log('Zaps:', stats?.zaps); // 12
console.log('Sats Zapped:', stats?.satszapped); // 5000