🚀 Socket Launch Week Day 4:Socket MCP Adds Org Alerts, Threat Feed Review, and Package Inspection.Learn more
Sign In

@powforge/identity

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@powforge/identity

Depth-of-Identity SDK for Nostr. Measures accumulated irreversible work across five dimensions. Try it live at powforge.dev/explorer.

beta
Source
npmnpm
Version
0.7.0-beta.2
Version published
Weekly downloads
40
-16.67%
Maintainers
1
Weekly downloads
 
Created
Source

@powforge/identity

npm version license tests

Try it live: powforge.dev/explorer — connect your Nostr profile with NIP-07, see your depth score, rank your peers, and look up any npub. Self-lookup is free and runs client-side.

Agent-payable signed scores: POST https://identity.powforge.dev/l402/identity-score returns a schnorr-signed score JSON for 2 sats via Lightning HTTP 402.

Depth-of-Identity SDK for Nostr. Measures accumulated irreversible work across five dimensions to produce a single identity weight score.

Not human vs bot. Invested vs uninvested. It is about measuring intentions.

Install

npm install @powforge/identity

Quick Start

const { getIdentityDepth } = require('@powforge/identity');

const report = await getIdentityDepth(pubkey, {
  relays: ['wss://relay.powforge.dev'],
});

console.log(report.weight);      // total identity depth score
console.log(report.dimensions);  // breakdown by dimension

What It Measures

Five dimensions of identity depth:

DimensionWhat It ScoresEvent Kinds
SpatialCyberspace movement proofs, unique regions exploredkind:3333
SocialNotes published, reactions given, unique peers interacted withkind:1, kind:7
AccessNIP-13 proof-of-work accumulated across all eventsnonce tags
VouchInbound vouches from other identities, weighted by voucher depth with sqrt dilutionkind:33335

API

getIdentityDepth(pubkey, options?)

Returns a full identity report for a hex pubkey.

Options:

OptionDefaultDescription
relays['ws://localhost:3088']Array of relay WebSocket URLs to query
timeout5000Query timeout per relay in ms
dimensions['spatial', 'social', 'access', 'vouch']Which dimensions to score

Returns:

{
  "pubkey": "93da4435...",
  "totalEvents": 3,
  "weight": 24,
  "activeDimensions": 2,
  "dimensionMultiplier": 1.2,
  "dimensions": {
    "spatial": { "events": 3, "uniqueRegions": 3, "proofsVerified": 3, "score": 21 },
    "social": { "notes": 0, "reactions": 0, "uniquePeers": 0, "score": 0 },
    "access": { "totalEvents": 3, "totalPowBits": 0, "maxDifficulty": 0, "score": 3 },
    "vouch": { "inboundVouches": 0, "uniqueVouchers": 0, "totalWeight": 0, "score": 0 }
  },
  "firstActivity": "2026-04-12T17:25:47.000Z",
  "lastActivity": "2026-04-13T21:01:16.000Z",
  "relaysQueried": 1
}

queryRelay(relayUrl, filters, timeout?)

Low-level function to query a single relay for events matching NIP-01 filters.

How Scoring Works

Each dimension uses log2 scaling to prevent grinding attacks. You can't just spam events to inflate your score -- each additional unit of work yields diminishing returns, just like real proof-of-work.

  • Spatial: log2(events+1) * 2 + log2(uniqueRegions+1) * 5
  • Social: log2(notes+1) * 3 + log2(reactions+1) + log2(bidirectionalPeers+1) * 15 + log2(unidirectionalPeers+1) * 5
  • Access: totalPowBits * 2 + log2(powEvents+1) (PoW bits are already exponential, so they stay linear)
  • Vouch: log2(totalWeight+1) * 3 + log2(uniqueVouchers+1) * 20 (sqrt dilution prevents vouch farming)

A dimension multiplier rewards spreading across dimensions: having depth in 2 dimensions gives 1.2x, 3 gives 1.4x, all 4 gives 1.6x. One-trick ponies get no bonus.

The total weight is the sum of all dimension scores times the multiplier. Higher weight means more accumulated, irreversible work.

Why Not Just Check Follower Count?

Follower counts are trivially faked. This SDK measures things that cost real resources to produce: computation (PoW), time (event history), movement (spatial proofs), and social commitment (vouches backed by depth). Every dimension requires irreversible expenditure to increase.

Chaintip Freshness (beta)

Starting in 0.7.0-beta.1, the SDK ships an optional Bitcoin chain-tip anchor you can attach to a signed DoI score. The field is experimental, opt-in, and backwards-compatible. Scores without it still verify exactly as before.

What it adds: { height, hash, observed_at } under the signer's payload, where height and hash come from the current Bitcoin tip and observed_at is the ISO-8601 time of the fetch. Honest claim: block height plus hash as a freshness anchor, verifiable against any public Bitcoin node. This is not SPV, not a Merkle proof, and not a timestamp service. It tells a consumer "this score was measured after block N" — nothing more.

How to opt in

const { getChaintip, signWithChaintip } = require('@powforge/identity');

// Fetch the current tip directly.
const tip = await getChaintip();
// => { height: 946252, hash: '00000000...', observed_at: '2026-04-23T...' }

// Or wrap any signer to fold the tip into the signed payload.
const { payload, signature } = await signWithChaintip(
  scorePayload,
  (p) => mySigner(p),
  { includeChaintip: true },
);

On the hosted oracle, pass ?chaintip=1 on any score endpoint:

curl -s -X POST 'https://identity.powforge.dev/l402/identity-score?chaintip=1' \
  -H 'Content-Type: application/json' \
  -d '{"pubkey":"<64-hex>"}'

Limitations

  • Data source: mempool.space public API. Subject to their rate limits and uptime. If mempool.space is down, the score still ships, and the envelope carries bitcoin_tip_error instead of bitcoin_tip so callers can retry.
  • Cache window: 60 seconds in-process. Two calls within a minute get the same tip, which is fine because Bitcoin blocks land every 10 minutes on average.
  • No chain verification: we forward what mempool.space reports. A consumer who wants higher assurance should cross-check the returned hash against any Bitcoin node they already trust.

Upgrade path

When self-hosted Bitcoin RPC credentials are wired up, the mempool.space fetch swaps for a direct bitcoind JSON-RPC getblockchaininfo call. The public SDK surface does not change. See the TODO(bitcoind-rpc) marker in src/chaintip.js for the exact hook point.

License

MIT

Keywords

identity

FAQs

Package last updated on 23 Apr 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts