-
Notifications
You must be signed in to change notification settings - Fork 16
ArcTrust Reputation via Social Graph and NIP 32
The NIP-32 label events on nostr can be noisy and spammy, but overlaying them onto your social graph can make sense of these ratings in the context of your personal web of trust.
ArcLib will implement features for indexing a user's own social graph in the ArcadeSocial class, querying it for distances between the user and a given pubkey, querying the relay pool for NIP-32 events labeling a given pubkey, and determining the overall reputation of the pubkey for any label (such as trade
for scores related to ArcTrade). Implementing this inside of Arcade as a client-side reputation feature will be our first proof of concept. Work on this can be followed here: https://github.com/ArcadeLabsInc/arclib/pull/22
ArcTrust is the next step: a remote API that crawls and indexes the nostr social graph and may be called to retrieve personalized social graph data to easily mark pubkeys in Arcade with reputation scores relative to the user.
If ArcTrust is developed in this way, it could be turned into a monetized API that other apps can pay for. This data enables other apps to provide easy, visual indicators for how trusted a given user is based on their users' personal social graph.
A rater may use a NIP-32 event to rate an evaluee (some pubkey).
{
id: "..."
pubkey: "..."
created_at: ...
kind: 1985
tags: [
["L","city.arcade"],
["l","trade","city.arcade","{\"quality\":0.75}"],
["p","<evaluee pubkey>"],
["e","<optional trade eventid>"]
]
content: "<optional review>"
}
ArcLib's Social module collects these 1985 events, filtered by nomenclature ["L","city.arcade"]
and optionally by label ["l","trade"]
to calculate a reputation score.
If the rater would like to change, add to, or remove their ratings for a given pubkey, they may simply publish a new kind 1985. The most recent kind 1985 for a given author should be considered the only valid rating. Instead of using parameterized replaceable events, regular events can be aggregated to visualize a user rating delta and history is not lost.
Ratings can be for anything, but MUST be either a verb (bare infinitive, no "-ing") or noun (singular).
Official nomenclature includes:
-
trade
: quality between 0 and 1 representing the evaluee's desirability as a counterparty.
The "L"
namespace tag must be city.arcade
to specify this nomenclature.
We want to find out the reputation of a given user, our evaluee, represented by a pubkey.
- Collect all 1985 rating events for the evaluee pubkey, optionally filtered by nomenclature
L
and/or labell
:
// in this example we are evaluating a user's `trade` rating.
filter: {
kinds: [1985],
"#p": ["<evaluee pubkey>"],
"#L": ["city.arcade"],
"#l": ["trade"]
}
- For each event author, filter only the most recent event by
created_at
. The following steps only operate on the remaining events. - For each event, parse the
quality
as a float asscore
. Discard events with unparseable values or values outside of 0-1 range. - For each event, get the social graph distance between yourself and the event author as
distance
. If thedistance
is not known or calculable, thedistance
is set to 3. - For each event, calculate
( 1 / distance ** 2 )
asweight
. Ifdistance
is 0 (you to yourself),weight
is set to 10_000. - For each event, calculate
weight * score
asscaledScore
. - Calculate the sum of all
weight
s asweightSum
- Calculate the sum of all
scaledScore
s asscaledScoreSum
- Calculate
scaledScoreSum / weightSum
asweightedAverageScore
. - The
weightedAverageScore
is the social graph reputation of the rating.
You have 0 distance to yourself.
You have 1 distance from any pubkey you follow ("friends").
You have 2 distance from any pubkey you don't follow but your friends do follow.
You have 3 distance if your friends do not follow. 3 is the maximum distance. If the pubkey is not in the graph, they get a distance of 3 automatically.
Building a social graph to accommodate this only requires a depth of 2 (level 1 is your friends, level 2 is who your friends follow). Building a social graph deeper than 2 levels is unnecessarily expensive for negligible gain.
- decide if we should use a
city.arcade
nomenclature to establish a standard or use something more generalized so that ratings from other apps come across. How likely is it that we all use the same label if we don't adopt a specific nomenclature? 🤔