Skip to content

Travh98/player-graph

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Player Graph Icon PlayerGraph — Decentralized Trust & Match History for Competitive Games

"Players own their identity across games the same way Bitcoin users own their money — your match history, reputation, and trust network live on a blockchain you control, not inside Steam or Riot's database."

Prototype built for MIT Bitcoin Hackathon 2026. I'd love to see a system like this integrated with game providers.

How to Run

Prerequisites: Node.js 18+

# Install dependencies
cd server && npm install
cd ../client && npm install
# Terminal 1 — API (http://localhost:3001)
cd server && npm start

# Terminal 2 — Frontend (http://localhost:5173)
cd client && npm run dev

Open http://localhost:5173. The demo loads with ShadowFox pre-logged in and a seeded match history.

Optional — Lightning Network tips: Copy server/.env.example to server/.env and fill in your LND node credentials. If left unconfigured, the tip UI runs in demo mode with a simulated payment button.

The Problem

In competitive video games, you get matched with strangers. These people will likely never see you again, so there is no social consequence for toxic behavior — harassment, hate speech, and cyberbullying happens all the time.

Game providers like Steam, Riot Games, Epic Games, etc know who you encounter online. None of them talk to each other, and none of that history belongs to you.

The Solution

PlayerGraph is a decentralized network that tracks every player you encounter, the games you played together, and the reputation they've earned through peer ratings. It works across Steam, Riot Games, and Epic Games simultaneously.

When you enter a lobby, you see:

  • Every game you've played with each player, across all platforms
  • Games your friends have played with them — even if you weren't there
  • Trust badges based on ratings your friends have given them
  • Warnings if trusted people in your network have flagged a player as unfriendly

Because the history lives on a blockchain rather than inside a company's database, it can be used across all game providers. Your history is yours.

See warnings for players in your lobby.


The Technology

Blockchain — The PlayerGraph Chain

Every match and every rating is written as a block on the PlayerGraph Chain — a SHA-256 hash chain where each block cryptographically references the one before it.

[Genesis: 0000…0000]
        ↓ prev_hash
[Block 1]  type=match    game=CS2       hash=00a3f9…
        ↓ prev_hash
[Block 2]  type=rating   👍 Nova→Blaze  hash=00c821…
        ↓ prev_hash
[Block 3]  type=match    game=Valorant  hash=007d44…

Two block types are anchored to the chain:

  • Match blocks — record which players played together, in which game, on which teams, with the final score
  • Rating blocks — record a signed thumbs-up or thumbs-down from one player to another, tied to a specific match

Each block contains the data payload plus prev_hash — the hash of the block before it. To alter any historical record, an attacker must recompute that block and every block that follows, faster than the live network adds new blocks. This makes the history tamper-evident without requiring a trusted central authority.

Rate your teammates based on their friendliness.

Proof of Work

Simply hashing a payload is cheap — an attacker could rewrite history instantly. PlayerGraph requires proof of work before any block is accepted onto the chain.

When a match ends or a rating is submitted, the server searches for a nonce — an integer that, when included in the block payload, produces a hash beginning with a required number of leading zeros:

let nonce = 0;
do {
  blockHash = SHA - 256({ ...payload, prev_hash, nonce });
  nonce++;
} while (!blockHash.startsWith("00"));

This means producing a valid block requires hundreds of hash computations on average. Rewriting a block buried deep in the chain means re-mining it and every block above it — a cost that grows exponentially with chain depth.

The nonce and resulting hash are stored on every block and are visible in the Block Explorer.

Cryptographic Player Identity

Every player on PlayerGraph has a unique ECDSA P-256 keypair generated when they join:

pg_1001 (ShadowFox)
  ├── pg_id:      pg_1001              (universal identifier)
  ├── public_key: (stored on-chain, visible to everyone)
  └── private_key: (held only by the player)

The pg_id maps to usernames across all providers:

pg_1001 (ShadowFox)
  ├── steam_username:  shadowfox_steam   (linked via Steam OAuth)
  ├── riot_username:   shadowfox_val     (linked via Riot OAuth)
  └── epic_username:   shadowfox_epic    (linked via Epic OAuth)

When a match record arrives from any provider, PlayerGraph resolves the provider username to a pg_id. The chain stores pg_id values — not platform usernames — so your history is portable even if you rename yourself on any platform.

Signed Ratings

When a player submits a rating, the rating payload is cryptographically signed with their private key before being anchored to the chain:

{
  "rater_pg_id": "pg_1001",
  "ratee_pg_id": "pg_1002",
  "match_id": 7,
  "rating": 1,
  "created_at": "2026-04-11T15:00:00Z",
  "signature": "3045022100a9f2..."
}

The signature is embedded in the block payload and covered by the proof-of-work hash. This means:

  • No impersonation — the server cannot fabricate a rating on a player's behalf
  • No repudiation — a player cannot deny a rating they signed
  • Trustless verification — any node can verify the signature using only the public key, without trusting PlayerGraph's servers

Lightning Network Tips

Send tips to players.

Players can tip each other sats directly in the lobby using the Lightning Network — Bitcoin's Layer 2 payment protocol for instant, near-zero-fee transactions.

When a player clicks ⚡ Tip on a card:

  1. The server calls POST /v1/invoices on a connected LND testnet node, generating a BOLT11 payment request
  2. The UI renders the invoice as a QR code — scan it with any Lightning wallet (Phoenix, Muun, Zeus) to send the sats
  3. The server polls GET /v1/invoice/{hash} every 2 seconds until LND reports the invoice settled
  4. The tip is recorded in the PlayerGraph database with the payment hash
Tipper                     LND Node (testnet)          Tippee
  │                              │                        │
  │── POST /api/tips/invoice ───►│                        │
  │◄── BOLT11 + QR code ─────────│                        │
  │                              │                        │
  │  [scan QR in Lightning wallet]                        │
  │─────── Lightning payment ────────────────────────────►│
  │                              │                        │
  │── GET /api/tips/check ──────►│                        │
  │◄── { status: "paid" } ───────│                        │

All payments run on testnet — no real money is involved. The server connects to LND via its REST API using a macaroon for authentication and a TLS certificate for transport security.

If no LND node is configured, the UI runs in demo mode: a realistic lntb… invoice string is generated and displayed, and a "Simulate Payment" button stands in for an actual wallet.

LND is configured via environment variables in server/.env:

LND_REST_HOST=localhost:8080
LND_MACAROON_HEX=<hex-encoded invoice macaroon>
LND_TLS_CERT_BASE64=<base64-encoded tls.cert>   # optional

See server/.env.example for setup instructions.

Decentralized Network

The current demo runs on a single local node. In production, the PlayerGraph Chain would be replicated across a peer-to-peer network:

[Node A]  [Node B]  [Node C]  [Node D]
    \         |         |        /
         PlayerGraph Chain

Each node independently validates proof-of-work and signature integrity before accepting any block. No single node — including PlayerGraph's own infrastructure — can rewrite history without the rest of the network rejecting the fork.

Players can run their own node and hold a personal copy of their complete match history.

Who runs the nodes? Game providers are the natural operators:

Node operator Incentive
Valve / Steam Their match data becomes portable and trusted across platforms — increasing Steam's relevance as an identity layer
Riot Games Cross-game reputation makes Valorant players more invested in their account; reduces smurf accounts
Epic Games Fortnite players carry verified history into new titles without starting from zero
Independent platforms Tournament organizers, esports leagues, and community servers can anchor results without relying on a single publisher
Players Anyone can run a node and hold a personal, uncensorable copy of their own history

No provider controls the network alone. A publisher who tries to alter a player's history would be rejected by every other node — the same way no single bank can rewrite the Bitcoin ledger.

Game API Oracles

In the demo, matches are simulated locally. In production, match records would be sourced from official game APIs via trusted oracles — services that fetch, sign, and submit match proofs without any player being able to fabricate a result:

Riot API ──► Oracle Node (fetches + signs) ──► PlayerGraph Chain

Multiple independent oracles attest to each match. A threshold of 3-of-5 oracles agreeing is required before a match block is accepted — so no single oracle can forge a result.


Bitcoin Anchoring

The PlayerGraph Chain is anchored to the Bitcoin Testnet blockchain in real-time from the Block Explorer.

When you click Anchor to Bitcoin, the server:

  1. Takes the current chain tip hash (the latest block's SHA-256 hash)
  2. Constructs a Bitcoin transaction with an OP_RETURN output embedding that 32-byte hash
  3. Broadcasts it to the Bitcoin Testnet network via the Blockstream API
  4. Records the transaction ID so it can never be re-anchored for the same chain state
PlayerGraph Chain tip hash
         ↓
  Bitcoin OP_RETURN tx
  (0 satoshis output, 1000 sat fee)
         ↓
  Testnet blockchain
  (immutable, public, permanent)

This means the entire PlayerGraph history — every match, every rating, every signature — is timestamped on the most battle-tested public ledger in existence. Anyone can look up the transaction on any Bitcoin block explorer and verify that this exact chain state existed at that moment in time.

No match data is stored on Bitcoin. Only the 32-byte hash is anchored — making it extremely cheap (a fraction of a cent on mainnet) while providing cryptographic proof of the full history.

On mainnet this would cost ~$0.01–0.05 per anchor. For production, anchoring could run automatically every hour or after every N blocks.

Anchor to Bitcoin.


How the Demo Works

  1. Lobby view — ShadowFox enters a lobby of 9 other players. Familiarity badges and trust warnings appear immediately based on cross-game history and friend ratings.
  2. Player cards — Click any player to open their full timeline: every match you've shared, the score, which team you were on, which friends also played with them, and all ratings given and received.
  3. Simulate Match — Generates a real match block, mines it with proof-of-work, and anchors it to the chain.
  4. Rate teammates — Ratings are signed with the player's keypair and anchored as a separate block.
  5. Block Explorer — Live view of the PlayerGraph Chain showing block IDs, types, hashes, and nonces.
  6. Anchor to Bitcoin — Click "Anchor to Bitcoin" in the Block Explorer to publish the current chain tip hash to the Bitcoin Testnet blockchain via OP_RETURN. The transaction ID links directly to Blockstream's explorer.

Future Plans

Medium-term (production path)

  • Game API oracle implementation — Integrate with Steam Web API, Riot Games API, and Epic Games API to pull real match data.
  • P2P node network — Build a gossip protocol so multiple nodes can replicate the chain. Players who run a node hold their own history independent of PlayerGraph's servers.
  • Threshold oracle signing — Require 3-of-5 independent oracles to sign a match proof before it's accepted, eliminating any single point of trust.

Long-term (ecosystem)

  • Matchmaking integration — Work with game providers to use PlayerGraph trust scores during matchmaking. Players who've rated each other positively get paired together more often, building persistent respectful communities.
  • Cross-game friend discovery — Surface "you've played 12 games with this person across CS2 and Valorant but haven't added them as a friend" recommendations.
  • DAO governance — Let long-standing players vote on oracle operators, mining difficulty adjustments, and protocol changes, so no company controls the rules of the network.

About

Decentralized Trust & Match History for Competitive Games

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors