Skip to content

Repository files navigation

🛡️ exSafe — NFT Community Safety Desk

Check it before you sign it. exSafe gives NFT communities one clear verdict — 🟢 SAFE / 🟡 CAUTION / 🔴 DANGER — on any link, contract address, transaction, signature request, or suspicious announcement, before a member connects a wallet or signs.

Wallet drainers steal hundreds of millions of dollars a year (see Scam Sniffer's annual reports for the latest figure). Most of it happens through one bad signature — a setApprovalForAll, a Permit, a fake mint link posted in a Discord that got hijacked. Wallets like MetaMask show you almost nothing useful at that moment. exSafe does.


What it does

One verdict engine ("the brain"), exposed through the places communities actually are:

Surface What it does
Web app Paste anything → clear verdict card with a plain-language explanation and a transparent signal checklist.
Discord bot Auto-scans every link/address posted in a channel and replies with a verdict. /check and /report slash commands.
/api/check The shared brain any surface (or your own tool) can call.

It understands four kinds of input, auto-detected:

  • Links — phishing blocklist (MetaMask's live eth-phishing-detect), typosquat / look-alike detection, domain age, community lists.
  • Contracts / addresses — GoPlus reputation (phishing, drainer, honeypot, hidden owner…), Etherscan verified-source + contract age.
  • Transactions & signatures (the flex) — decodes setApprovalForAll, approve, permit, Permit2 and Seaport signatures into plain English, and cross-checks the address receiving the permission against reputation feeds. "This gives 0x00…dbad permission to transfer EVERY NFT you own — and that address has been reported as a drainer."
  • Announcements — Claude flags social-engineering tactics (false urgency, "we got hacked, use this new link", claim/airdrop bait) and checks every link inside.

The community wedge

Other tools are individual browser extensions. exSafe is a community safety desk: mods verify official links (allowlist), members report scams (blocklist), and every verdict is scoped to your community (Discord guild). The bot lives where your members already are — no install required.


Architecture — one brain, many doors

                 detect → checkers → score → narrate (Claude)
                 ┌───────────────────────────────────────────┐
  web app  ─────▶│  lib/engine/runCheck()                     │
  discord  ─────▶│    ├─ checkers/url        (phishing, RDAP) │
  /api     ─────▶│    ├─ checkers/contract   (GoPlus, scan)   │
                 │    ├─ checkers/calldata   (viem decode)    │
                 │    ├─ checkers/announcement (Claude)       │
                 │    └─ community/store     (allow/blocklist)│
                 └───────────────────────────────────────────┘

Everything degrades gracefully: with zero API keys the app still runs (GoPlus, phishing list, RDAP and the community layer need no key; LLM narration falls back to deterministic text — set AI_API_KEY for Xiaomi MiMo / OpenAI-compatible, or ANTHROPIC_API_KEY for Claude; Etherscan signals are simply skipped and noted).

AI keys (narration)

# Xiaomi MiMo (recommended if you already farmed keys into 9Router)
AI_PROVIDER=openai
AI_API_KEY=sk-...
AI_BASE_URL=https://api.xiaomimimo.com/v1
AI_MODEL=mimo-v2.5-pro

Do not point Vercel at localhost:20128 (9Router). Use the public MiMo base URL above. Anthropic still works via ANTHROPIC_API_KEY if preferred.


Quickstart

npm install
cp .env.example .env.local   # optional — the app runs without any keys

# 1) Web app + API
npm run dev                  # http://localhost:3000

# 2) Discord bot (needs a bot token — see .env.example)
npm run bot

Try the buttons on the homepage, or:

curl -s localhost:3000/api/check -H 'content-type: application/json' \
  -d '{"input":"opensea-mint.net"}'

Discord setup {#discord-setup}

  1. Create an app at https://discord.com/developers/applications.
  2. Bot tab → enable Message Content Intent (required for auto-scan).
  3. Invite with scopes bot + applications.commands (perms: Send Messages, Embed Links, Read Message History).
  4. Put the token/client id (and optionally a guild id) in .env.local.
  5. Set NEXT_PUBLIC_DISCORD_INVITE to the bot invite URL so the landing page shows Add to Discord.
  6. Point EXSAFE_API_URL at the deployed web API, then npm run bot.

Shareable verdicts & judge demo

  • Any check updates the URL: ?q=<input>&chain=8453&lang=en
  • Use Copy share link on the verdict card
  • Judge path: open /?demo=judge or click Run demo (official → typosquat → drainer approval → hijacked announcement)

Default chain is Base (8453) for Vibestarter / Wave 1 alignment.


API

POST /api/check

// request
{ "input": "0x...", "chainId": "8453", "community": "guild-123", "lang": "en" }
// response
{ "verdict": "DANGER", "score": 100, "kind": "calldata",
  "summary": "...", "explanation": "...", "recommendation": "...",
  "signals": [{ "label": "...", "severity": "danger", "detail": "...", "source": "GoPlus" }],
  "meta": { "chainName": "Base", "checkedAt": "...", "degraded": [], "aiNarrated": true } }

POST /api/report{ "value": "scam.xyz", "type": "domain", "list": "block", "community": "guild-123" }


Data sources

MetaMask eth-phishing-detect · GoPlus Security · Etherscan · RDAP · on-chain calldata decoding via viem · your community's own reports.

Limitations

exSafe surfaces risk signals; it is not financial advice, and no automated check is a guarantee of safety. Absence of a signal is not proof something is safe. RDAP does not cover every TLD (e.g. .io). The community store is a file-backed MVP — swap it for a database for multi-instance persistence.

Roadmap

  • Full transaction simulation (Tenderly / Alchemy) showing exact asset outflow
  • MetaMask Snap for in-wallet insights at signing time
  • Persistent DB + mod dashboard for the community desk
  • Browser extension companion

About

exSafe — NFT Community Safety Desk: one clear verdict on links, contracts, transactions & announcements before you connect a wallet or sign.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages