Warning
This project is currently under active development.
Fayan (法眼), meaning "Dharma Eye" in Chinese, represents the ability to perceive truth and distinguish authenticity from deception. This project uses TrustRank and PageRank algorithms to identify spam accounts in the Nostr network.
A TrustRank & PageRank based reputation system for Nostr.
- Outbox Model Support - Accurately retrieves users' latest follow lists by querying their preferred relays
- Low Memory Footprint - Optimized for minimal resource consumption
- SQLite Storage - Lightweight and portable database backend
| Method | Path | Description |
|---|---|---|
| GET | /users/{pubkeyOrNpub} |
Query single user |
| POST | /users |
Batch query users |
| GET | /search?q=... |
Search users by name |
Official server:
https://fayan.jumble.social/
GET /users/{pubkeyOrNpub}
Supports both hex pubkey and npub format.
Response Fields:
| Field | Type | Description |
|---|---|---|
| pubkey | string | User public key (hex) |
| rank | int | Rank (lower is better) |
| percentile | int | Percentile (0-100) |
| followers | int | Number of followers |
| following | int | Number of following |
Response Example:
{
"pubkey": "hex_pubkey",
"rank": 123,
"percentile": 95,
"followers": 1000,
"following": 50
}POST /users
Request body:
{
"pubkeys": ["pubkey1", "npub1...", ...]
}Up to 100 pubkeys per request.
Response Structure:
| Key | Value Type | Description |
|---|---|---|
| pubkey/npub | UserResponse | User info object |
Response Example:
{
"pubkey1": {
"pubkey": "hex_pubkey1",
"rank": 1,
"percentile": 100,
"followers": 5000,
"following": 10
},
"npub1...": {
"pubkey": "hex_pubkey2",
"rank": 123,
"percentile": 95,
"followers": 1000,
"following": 50
}
}All endpoints return the following format on error:
{
"error": "Bad Request",
"message": "Detailed error message"
}GET /search?q={query}&limit={limit}
Search for users by name, display name, or NIP-05 identifier. Results are sorted by reputation rank.
Note: This feature is disabled by default. Enable it in
config.yamlby settingsearch.enabled: true.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| q | string | Yes | - | Search query |
| limit | int | No | 20 | Max results to return (max 100) |
| offset | int | No | 0 | Results to skip (max 1000) |
Response Fields:
| Field | Type | Description |
|---|---|---|
| event | object | Raw Nostr kind 0 event |
| pubkey | string | User public key (hex) |
| rank | int | Rank (lower is better) |
| percentile | int | Percentile (0-100) |
| followers | int | Number of followers |
| following | int | Number of following |
Response Example:
[
{
"event": {
"id": "...",
"pubkey": "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681",
"created_at": 1704067200,
"kind": 0,
"tags": [],
"content": "{\"name\":\"xxx\",\"about\":\"...\",\"picture\":\"...\"}",
"sig": "..."
},
"pubkey": "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681",
"rank": 1,
"percentile": 100,
"followers": 1000,
"following": 10
}
]# Copy example config files
cp config.example.yaml config.yaml
cp docker-compose.example.yml docker-compose.yml
# Start services
docker compose up --buildThis will build the frontend, embed it into the API binary, and start both crawler and API services. The web UI and API are available at http://localhost:9090.
Prerequisites:
- Go 1.24+
- Node.js 20+ (for frontend)
Option 1: Using build script
# Copy example config file
cp config.example.yaml config.yaml
# Build everything (frontend + Go binaries)
./build.sh
# Run crawler
./fayan-crawler
# Run API server in another terminal
./fayan-apiOption 2: Manual build
# Copy example config file
cp config.example.yaml config.yaml
# Build frontend
cd web
npm install
npm run build
cd ..
# Copy frontend assets to embed directory
cp -r web/dist/* cmd/api/static/
# Build Go binaries
go build -o fayan-crawler ./cmd/crawler/main.go
go build -o fayan-api ./cmd/api/main.go
# Run crawler
./fayan-crawler
# Run API server in another terminal
./fayan-apiCopy config.example.yaml to config.yaml and modify as needed. The example files are tracked by git while your local config files are ignored, making it easier to pull updates.
The user search feature is disabled by default. To enable it, add the following to your config.yaml:
search:
enabled: true # Enable user search feature
top_percentile: 50 # Only index users in top X% reputation (default: 50)The top_percentile setting controls which users' profiles are stored in the search index. Lower values mean stricter filtering, which reduces database size but may exclude more users from search results.
fayan/
├── cmd/
│ ├── api/ # API server with embedded frontend
│ │ ├── main.go
│ │ └── static/ # Embedded frontend files (built from web/)
│ └── crawler/ # Network crawler
├── internal/
│ ├── api/ # API handlers and middleware
│ ├── cache/ # In-memory caching
│ ├── crawler/ # Crawler logic
│ ├── ranking/ # PageRank/TrustRank algorithms
│ └── repository/ # SQLite storage layer
├── web/ # React frontend source
├── build.sh # Build script for frontend + Go binaries
├── Dockerfile # Multi-stage Docker build
└── docker-compose.example.yml
MIT License