Sats as signal.
No KYC,
no custody.
Sign one Bitcoin message. Any app can verify you’ve kept N sats unspent for N days in one API call. No account. No permission. Honest users pay nothing — attackers pay real opportunity cost.
Pick the path that matches your problem.
Every row points at a real integration that exists today — guide, package, and working code. If none of them match, read how OrangeCheck compares to alternatives and decide from there.
- [01]Running a forum or comments section
Bot spam, drive-by throwaways, and Sybil accounts undermining every thread. Require a small OC attestation before a user can post.
// @orangecheck/gate · 10 lines→ Gate a route - [02]Running an airdrop or token distribution
Sybil farms that split one wallet into ten thousand claim addresses. Filter candidate addresses by min_sats × min_days before distribution.
// @orangecheck/airdrop-gate · bulk CLI→ Filter an airdrop - [03]Operating a Nostr relay
Unbounded spam from unproofed npubs — impossible to moderate at scale. Accept posts only from npubs with a verified OrangeCheck attestation.
// @orangecheck/relay-filter · Strfry plugin→ Filter a relay - [04]Building a web app that needs identity
Passwords, magic links, and email auth — all leak, all scale poorly. Sign in with a Bitcoin message. The address is the account.
// /api/auth/* · 30-day session→ Sign in with Bitcoin - [05]Running on-chain governance or DAO votes
Sybil governance attacks where one voter controls many "holders". Weight votes by OC score — log(sats) × days rewards long-term skin.
// score_v0 · offline-verifiable→ Weight by score - [06]None of the above — you want full control
No external dependency on ochk.io, your own relays, your own Postgres. Clone the stack, point the SDK at your instance. Same protocol, your infra.
// 3 env vars · any Postgres 14+→ Self-host the verifier
Three steps. One primitive. Fits on a napkin.
- [01]SIGN
One canonical message. BIP-322 signature from any Bitcoin wallet. No transaction, no spending — funds never leave your control.
// sha256(msg) → attestation_id - [02]PUBLISH
Drop the proof on Nostr, embed it on your site, share a short URL. Self-contained JSON that anyone can verify offline, forever.
// kind 30078 · parameterized replaceable - [03]VERIFY
One GET returns pass/fail plus raw metrics. No SDK. Or drop in @orangecheck/gate middleware for Express, Next, Fastify, Hono.
// GET /api/check → 200 · 60s cache
Same decision,
every stack.
Query the hosted API, drop in middleware, or import the SDK. Pick your poison.
curl "https://attest.ochk.io/api/check?addr=bc1q...&min_sats=100000&min_days=30"
{
"ok": true,
"sats": 125000,
"days": 47,
"score": 30.12,
"attestation_id": "a3f5b8c2…",
"identities": [
{ "protocol": "nostr", "identifier": "npub1alice…" },
{ "protocol": "github", "identifier": "alice" }
]
}Every piece open. Every piece optional.
Open-core. Pick the piece that fits your stack — or just curl the hosted API directly.
- node@orangecheck/sdkCore protocol. check(), verify(), createAttestation()
- node@orangecheck/gateHTTP middleware. Express, Next, Fastify, Hono, Workers
- node@orangecheck/react<OcBadge>, <OcGate>, <OcChallengeButton>
- node@orangecheck/wallet-adapterOne sign() API across UniSat, Xverse, Leather, Alby
- node@orangecheck/cli`oc` shell. check, verify, discover, challenge
- node@orangecheck/relay-filterSybil filter for Nostr relays. Strfry plugin included
- node@orangecheck/airdrop-gateFilter candidates into sybil-resistant allowlists
- pythonorangecheckPython SDK. Django, Flask, FastAPI
No email. No password. No KYC.
Every page except your dashboard works without signing in. Every public API endpoint is unauthenticated. Sign in — when you want to — with one Bitcoin signature; your wallet is your login.
- >>→create a proofEnter an address, sign a canonical message with your wallet, share the URL.
- >→sign in with bitcoinOne BIP-322 signature opens a session. No email, no password — your wallet is your login.
- >→try the api/api/check · /api/verify · /api/challenge · /api/discover · /api/stats.
- >→airdrop gatePaste candidate addresses, filter live, download the sybil-resistant allowlist.